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 "LightSensor.h" 33 #include "ProximitySensor.h" 34 #include "AkmSensor.h" 35 36 /*****************************************************************************/ 37 38 struct sensors_poll_context_t { 39 struct sensors_poll_device_t device; // must be first 40 41 sensors_poll_context_t(); 42 ~sensors_poll_context_t(); 43 int activate(int handle, int enabled); 44 int setDelay(int handle, int64_t ns); 45 int pollEvents(sensors_event_t* data, int count); 46 47 private: 48 enum { 49 light = 0, 50 proximity = 1, 51 akm = 2, 52 numSensorDrivers, 53 numFds, 54 }; 55 56 static const size_t wake = numFds - 1; 57 static const char WAKE_MESSAGE = 'W'; 58 struct pollfd mPollFds[numFds]; 59 int mWritePipeFd; 60 SensorBase* mSensors[numSensorDrivers]; 61 62 int handleToDriver(int handle) const { 63 switch (handle) { 64 case ID_A: 65 case ID_M: 66 case ID_O: 67 return akm; 68 case ID_P: 69 return proximity; 70 case ID_L: 71 return light; 72 } 73 return -EINVAL; 74 } 75 }; 76 77 /*****************************************************************************/ 78 79 sensors_poll_context_t::sensors_poll_context_t() 80 { 81 mSensors[light] = new LightSensor(); 82 mPollFds[light].fd = mSensors[light]->getFd(); 83 mPollFds[light].events = POLLIN; 84 mPollFds[light].revents = 0; 85 86 mSensors[proximity] = new ProximitySensor(); 87 mPollFds[proximity].fd = mSensors[proximity]->getFd(); 88 mPollFds[proximity].events = POLLIN; 89 mPollFds[proximity].revents = 0; 90 91 mSensors[akm] = new AkmSensor(); 92 mPollFds[akm].fd = mSensors[akm]->getFd(); 93 mPollFds[akm].events = POLLIN; 94 mPollFds[akm].revents = 0; 95 96 int wakeFds[2]; 97 int result = pipe(wakeFds); 98 LOGE_IF(result<0, "error creating wake pipe (%s)", strerror(errno)); 99 fcntl(wakeFds[0], F_SETFL, O_NONBLOCK); 100 fcntl(wakeFds[1], F_SETFL, O_NONBLOCK); 101 mWritePipeFd = wakeFds[1]; 102 103 mPollFds[wake].fd = wakeFds[0]; 104 mPollFds[wake].events = POLLIN; 105 mPollFds[wake].revents = 0; 106 } 107 108 sensors_poll_context_t::~sensors_poll_context_t() { 109 for (int i=0 ; i<numSensorDrivers ; i++) { 110 delete mSensors[i]; 111 } 112 close(mPollFds[wake].fd); 113 close(mWritePipeFd); 114 } 115 116 int sensors_poll_context_t::activate(int handle, int enabled) { 117 int index = handleToDriver(handle); 118 if (index < 0) return index; 119 int err = mSensors[index]->enable(handle, enabled); 120 if (enabled && !err) { 121 const char wakeMessage(WAKE_MESSAGE); 122 int result = write(mWritePipeFd, &wakeMessage, 1); 123 LOGE_IF(result<0, "error sending wake message (%s)", strerror(errno)); 124 } 125 return err; 126 } 127 128 int sensors_poll_context_t::setDelay(int handle, int64_t ns) { 129 130 int index = handleToDriver(handle); 131 if (index < 0) return index; 132 return mSensors[index]->setDelay(handle, ns); 133 } 134 135 int sensors_poll_context_t::pollEvents(sensors_event_t* data, int count) 136 { 137 int nbEvents = 0; 138 int n = 0; 139 140 do { 141 // see if we have some leftover from the last poll() 142 for (int i=0 ; count && i<numSensorDrivers ; i++) { 143 SensorBase* const sensor(mSensors[i]); 144 if ((mPollFds[i].revents & POLLIN) || (sensor->hasPendingEvents())) { 145 int nb = sensor->readEvents(data, count); 146 if (nb < count) { 147 // no more data for this sensor 148 mPollFds[i].revents = 0; 149 } 150 count -= nb; 151 nbEvents += nb; 152 data += nb; 153 } 154 } 155 156 if (count) { 157 // we still have some room, so try to see if we can get 158 // some events immediately or just wait if we don't have 159 // anything to return 160 n = poll(mPollFds, numFds, nbEvents ? 0 : -1); 161 if (n<0) { 162 LOGE("poll() failed (%s)", strerror(errno)); 163 return -errno; 164 } 165 if (mPollFds[wake].revents & POLLIN) { 166 char msg; 167 int result = read(mPollFds[wake].fd, &msg, 1); 168 LOGE_IF(result<0, "error reading from wake pipe (%s)", strerror(errno)); 169 LOGE_IF(msg != WAKE_MESSAGE, "unknown message on wake queue (0x%02x)", int(msg)); 170 mPollFds[wake].revents = 0; 171 } 172 } 173 // if we have events and space, go read them 174 } while (n && count); 175 176 return nbEvents; 177 } 178 179 /*****************************************************************************/ 180 181 static int poll__close(struct hw_device_t *dev) 182 { 183 sensors_poll_context_t *ctx = (sensors_poll_context_t *)dev; 184 if (ctx) { 185 delete ctx; 186 } 187 return 0; 188 } 189 190 static int poll__activate(struct sensors_poll_device_t *dev, 191 int handle, int enabled) { 192 sensors_poll_context_t *ctx = (sensors_poll_context_t *)dev; 193 return ctx->activate(handle, enabled); 194 } 195 196 static int poll__setDelay(struct sensors_poll_device_t *dev, 197 int handle, int64_t ns) { 198 sensors_poll_context_t *ctx = (sensors_poll_context_t *)dev; 199 return ctx->setDelay(handle, ns); 200 } 201 202 static int poll__poll(struct sensors_poll_device_t *dev, 203 sensors_event_t* data, int count) { 204 sensors_poll_context_t *ctx = (sensors_poll_context_t *)dev; 205 return ctx->pollEvents(data, count); 206 } 207 208 /*****************************************************************************/ 209 210 int init_nusensors(hw_module_t const* module, hw_device_t** device) 211 { 212 int status = -EINVAL; 213 214 sensors_poll_context_t *dev = new sensors_poll_context_t(); 215 memset(&dev->device, 0, sizeof(sensors_poll_device_t)); 216 217 dev->device.common.tag = HARDWARE_DEVICE_TAG; 218 dev->device.common.version = 0; 219 dev->device.common.module = const_cast<hw_module_t*>(module); 220 dev->device.common.close = poll__close; 221 dev->device.activate = poll__activate; 222 dev->device.setDelay = poll__setDelay; 223 dev->device.poll = poll__poll; 224 225 *device = &dev->device.common; 226 status = 0; 227 return status; 228 } 229