JP Abgrall | 5dcc6c9 | 2012-05-31 20:39:43 -0700 | [diff] [blame] | 1 | /* |
| 2 | * Copyright (C) 2012 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 | #define LOG_TAG "Sensors" |
| 18 | //#define FUNC_LOG ALOGV("%s", __PRETTY_FUNCTION__) |
| 19 | #define FUNC_LOG |
| 20 | |
| 21 | #include <hardware/sensors.h> |
| 22 | #include <fcntl.h> |
| 23 | #include <errno.h> |
| 24 | #include <dirent.h> |
| 25 | #include <math.h> |
| 26 | #include <poll.h> |
| 27 | #include <pthread.h> |
| 28 | #include <stdlib.h> |
| 29 | |
| 30 | #include <utils/Atomic.h> |
| 31 | #include <utils/Log.h> |
| 32 | |
| 33 | #include "sensors.h" |
| 34 | |
JP Abgrall | 49d4995 | 2012-06-16 00:44:51 -0700 | [diff] [blame] | 35 | #include "MPLSensor.h" |
JP Abgrall | 5dcc6c9 | 2012-05-31 20:39:43 -0700 | [diff] [blame] | 36 | #include "LightSensor.h" |
| 37 | #include "PressureSensor.h" |
| 38 | |
| 39 | |
| 40 | /*****************************************************************************/ |
| 41 | |
| 42 | #define DELAY_OUT_TIME 0x7FFFFFFF |
| 43 | |
JP Abgrall | 5dcc6c9 | 2012-05-31 20:39:43 -0700 | [diff] [blame] | 44 | #define SENSORS_ROTATION_VECTOR_HANDLE (ID_RV) |
| 45 | #define SENSORS_LINEAR_ACCEL_HANDLE (ID_LA) |
| 46 | #define SENSORS_GRAVITY_HANDLE (ID_GR) |
| 47 | #define SENSORS_GYROSCOPE_HANDLE (ID_GY) |
JP Abgrall | 87e826c | 2012-10-03 20:50:01 -0700 | [diff] [blame] | 48 | #define SENSORS_RAW_GYROSCOPE_HANDLE (ID_RG) |
JP Abgrall | 5dcc6c9 | 2012-05-31 20:39:43 -0700 | [diff] [blame] | 49 | #define SENSORS_ACCELERATION_HANDLE (ID_A) |
| 50 | #define SENSORS_MAGNETIC_FIELD_HANDLE (ID_M) |
| 51 | #define SENSORS_ORIENTATION_HANDLE (ID_O) |
| 52 | #define SENSORS_LIGHT_HANDLE (ID_L) |
| 53 | #define SENSORS_PROXIMITY_HANDLE (ID_P) |
| 54 | #define SENSORS_PRESSURE_HANDLE (ID_PR) |
| 55 | #define AKM_FTRACE 0 |
| 56 | #define AKM_DEBUG 0 |
| 57 | #define AKM_DATA 0 |
| 58 | |
| 59 | /*****************************************************************************/ |
| 60 | |
| 61 | /* The SENSORS Module */ |
JP Abgrall | 3d96702 | 2012-10-22 12:42:18 -0700 | [diff] [blame] | 62 | #define LOCAL_SENSORS 2 |
JP Abgrall | 49d4995 | 2012-06-16 00:44:51 -0700 | [diff] [blame] | 63 | static struct sensor_t sSensorList[LOCAL_SENSORS + MPLSensor::numSensors] = { |
JP Abgrall | 5dcc6c9 | 2012-05-31 20:39:43 -0700 | [diff] [blame] | 64 | { "BH1721fvc Light sensor", |
| 65 | "Rohm", |
| 66 | 1, SENSORS_LIGHT_HANDLE, |
| 67 | SENSOR_TYPE_LIGHT, 65528.0f, 1.0f, 0.20f, 16000, { } }, |
| 68 | { "BMP182 Pressure sensor", |
| 69 | "Bosch", |
| 70 | 1, SENSORS_PRESSURE_HANDLE, |
| 71 | SENSOR_TYPE_PRESSURE, 1100.0f, 0.01f, 0.06f, 50000, { } }, |
| 72 | }; |
| 73 | static int numSensors = LOCAL_SENSORS; |
| 74 | |
| 75 | static int open_sensors(const struct hw_module_t* module, const char* id, |
| 76 | struct hw_device_t** device); |
| 77 | |
| 78 | |
| 79 | static int sensors__get_sensors_list(struct sensors_module_t* module, |
| 80 | struct sensor_t const** list) |
| 81 | { |
| 82 | *list = sSensorList; |
| 83 | return numSensors; |
| 84 | } |
| 85 | |
| 86 | static struct hw_module_methods_t sensors_module_methods = { |
| 87 | open: open_sensors |
| 88 | }; |
| 89 | |
| 90 | struct sensors_module_t HAL_MODULE_INFO_SYM = { |
| 91 | common: { |
| 92 | tag: HARDWARE_MODULE_TAG, |
| 93 | version_major: 1, |
| 94 | version_minor: 0, |
| 95 | id: SENSORS_HARDWARE_MODULE_ID, |
| 96 | name: "Samsung Sensor module", |
| 97 | author: "Samsung Electronic Company", |
| 98 | methods: &sensors_module_methods, |
| 99 | dso: 0, |
| 100 | reserved: {}, |
| 101 | }, |
| 102 | get_sensors_list: sensors__get_sensors_list, |
| 103 | }; |
| 104 | |
| 105 | struct sensors_poll_context_t { |
| 106 | struct sensors_poll_device_t device; // must be first |
| 107 | |
| 108 | sensors_poll_context_t(); |
| 109 | ~sensors_poll_context_t(); |
| 110 | int activate(int handle, int enabled); |
| 111 | int setDelay(int handle, int64_t ns); |
| 112 | int pollEvents(sensors_event_t* data, int count); |
| 113 | |
JP Abgrall | acd411c | 2012-06-21 20:01:28 -0700 | [diff] [blame] | 114 | // Will return true if the constructor completed |
| 115 | bool isValid() { return mInitialized; }; |
| 116 | |
JP Abgrall | 5dcc6c9 | 2012-05-31 20:39:43 -0700 | [diff] [blame] | 117 | private: |
JP Abgrall | acd411c | 2012-06-21 20:01:28 -0700 | [diff] [blame] | 118 | // Will be true if the constructor completed |
| 119 | bool mInitialized; |
| 120 | |
JP Abgrall | 5dcc6c9 | 2012-05-31 20:39:43 -0700 | [diff] [blame] | 121 | enum { |
JP Abgrall | 49d4995 | 2012-06-16 00:44:51 -0700 | [diff] [blame] | 122 | mpl = 0, |
| 123 | compass, |
JP Abgrall | 3d96702 | 2012-10-22 12:42:18 -0700 | [diff] [blame] | 124 | #ifdef ENABLE_DMP_DISPL_ORIENT_FEAT |
| 125 | dmpOrient, |
| 126 | #endif |
JP Abgrall | 49d4995 | 2012-06-16 00:44:51 -0700 | [diff] [blame] | 127 | light, |
JP Abgrall | 5dcc6c9 | 2012-05-31 20:39:43 -0700 | [diff] [blame] | 128 | pressure, |
| 129 | numSensorDrivers, // wake pipe goes here |
| 130 | numFds, |
| 131 | }; |
| 132 | |
| 133 | static const size_t wake = numFds - 1; |
| 134 | static const char WAKE_MESSAGE = 'W'; |
| 135 | struct pollfd mPollFds[numFds]; |
| 136 | int mWritePipeFd; |
| 137 | SensorBase* mSensors[numSensorDrivers]; |
| 138 | |
| 139 | int handleToDriver(int handle) const { |
| 140 | switch (handle) { |
JP Abgrall | 49d4995 | 2012-06-16 00:44:51 -0700 | [diff] [blame] | 141 | case ID_RV: |
| 142 | case ID_LA: |
| 143 | case ID_GR: |
| 144 | case ID_GY: |
JP Abgrall | 87e826c | 2012-10-03 20:50:01 -0700 | [diff] [blame] | 145 | case ID_RG: |
JP Abgrall | 49d4995 | 2012-06-16 00:44:51 -0700 | [diff] [blame] | 146 | case ID_A: |
| 147 | case ID_M: |
| 148 | case ID_O: |
| 149 | return mpl; |
JP Abgrall | 3d96702 | 2012-10-22 12:42:18 -0700 | [diff] [blame] | 150 | #ifdef ENABLE_DMP_DISPL_ORIENT_FEAT |
| 151 | case ID_SO: |
| 152 | return dmpOrient; |
| 153 | #endif |
JP Abgrall | 5dcc6c9 | 2012-05-31 20:39:43 -0700 | [diff] [blame] | 154 | case ID_L: |
| 155 | return light; |
| 156 | case ID_PR: |
| 157 | return pressure; |
| 158 | } |
| 159 | return -EINVAL; |
| 160 | } |
| 161 | }; |
| 162 | |
| 163 | /*****************************************************************************/ |
| 164 | |
| 165 | sensors_poll_context_t::sensors_poll_context_t() |
| 166 | { |
| 167 | FUNC_LOG; |
JP Abgrall | 49d4995 | 2012-06-16 00:44:51 -0700 | [diff] [blame] | 168 | CompassSensor *p_compasssensor = new CompassSensor(); |
| 169 | MPLSensor *p_mplsen = new MPLSensor(p_compasssensor); |
JP Abgrall | acd411c | 2012-06-21 20:01:28 -0700 | [diff] [blame] | 170 | mInitialized = false; |
| 171 | // Must clean this up early or else the destructor will make a mess. |
| 172 | memset(mSensors, 0, sizeof(mSensors)); |
| 173 | |
JP Abgrall | 49d4995 | 2012-06-16 00:44:51 -0700 | [diff] [blame] | 174 | setCallbackObject(p_mplsen); //setup the callback object for handing mpl callbacks |
| 175 | numSensors = |
| 176 | LOCAL_SENSORS + |
| 177 | p_mplsen->populateSensorList(sSensorList + LOCAL_SENSORS, |
| 178 | sizeof(sSensorList[0]) * (ARRAY_SIZE(sSensorList) - LOCAL_SENSORS)); |
| 179 | |
| 180 | mSensors[mpl] = p_mplsen; |
| 181 | mPollFds[mpl].fd = mSensors[mpl]->getFd(); |
| 182 | mPollFds[mpl].events = POLLIN; |
| 183 | mPollFds[mpl].revents = 0; |
| 184 | |
| 185 | mSensors[compass] = p_mplsen; |
| 186 | mPollFds[compass].fd = ((MPLSensor*)mSensors[mpl])->getCompassFd(); |
| 187 | mPollFds[compass].events = POLLIN; |
| 188 | mPollFds[compass].revents = 0; |
JP Abgrall | 5dcc6c9 | 2012-05-31 20:39:43 -0700 | [diff] [blame] | 189 | |
JP Abgrall | 3d96702 | 2012-10-22 12:42:18 -0700 | [diff] [blame] | 190 | #ifdef ENABLE_DMP_DISPL_ORIENT_FEAT |
| 191 | mPollFds[dmpOrient].fd = ((MPLSensor*)mSensors[mpl])->getDmpOrientFd(); |
| 192 | mPollFds[dmpOrient].events = POLLPRI; |
| 193 | mPollFds[dmpOrient].revents = 0; |
| 194 | #endif |
JP Abgrall | 5dcc6c9 | 2012-05-31 20:39:43 -0700 | [diff] [blame] | 195 | mSensors[light] = new LightSensor(); |
| 196 | mPollFds[light].fd = mSensors[light]->getFd(); |
| 197 | mPollFds[light].events = POLLIN; |
| 198 | mPollFds[light].revents = 0; |
| 199 | |
| 200 | mSensors[pressure] = new PressureSensor(); |
| 201 | mPollFds[pressure].fd = mSensors[pressure]->getFd(); |
| 202 | mPollFds[pressure].events = POLLIN; |
| 203 | mPollFds[pressure].revents = 0; |
| 204 | |
| 205 | int wakeFds[2]; |
| 206 | int result = pipe(wakeFds); |
| 207 | ALOGE_IF(result<0, "error creating wake pipe (%s)", strerror(errno)); |
| 208 | fcntl(wakeFds[0], F_SETFL, O_NONBLOCK); |
| 209 | fcntl(wakeFds[1], F_SETFL, O_NONBLOCK); |
| 210 | mWritePipeFd = wakeFds[1]; |
| 211 | |
| 212 | mPollFds[wake].fd = wakeFds[0]; |
| 213 | mPollFds[wake].events = POLLIN; |
| 214 | mPollFds[wake].revents = 0; |
JP Abgrall | acd411c | 2012-06-21 20:01:28 -0700 | [diff] [blame] | 215 | mInitialized = true; |
JP Abgrall | 5dcc6c9 | 2012-05-31 20:39:43 -0700 | [diff] [blame] | 216 | } |
| 217 | |
| 218 | sensors_poll_context_t::~sensors_poll_context_t() |
| 219 | { |
| 220 | FUNC_LOG; |
| 221 | for (int i=0 ; i<numSensorDrivers ; i++) { |
| 222 | delete mSensors[i]; |
| 223 | } |
| 224 | close(mPollFds[wake].fd); |
| 225 | close(mWritePipeFd); |
JP Abgrall | acd411c | 2012-06-21 20:01:28 -0700 | [diff] [blame] | 226 | mInitialized = false; |
JP Abgrall | 5dcc6c9 | 2012-05-31 20:39:43 -0700 | [diff] [blame] | 227 | } |
| 228 | |
| 229 | int sensors_poll_context_t::activate(int handle, int enabled) |
| 230 | { |
| 231 | FUNC_LOG; |
JP Abgrall | 87e826c | 2012-10-03 20:50:01 -0700 | [diff] [blame] | 232 | if (!mInitialized) return -EINVAL; |
JP Abgrall | 5dcc6c9 | 2012-05-31 20:39:43 -0700 | [diff] [blame] | 233 | int index = handleToDriver(handle); |
| 234 | if (index < 0) return index; |
| 235 | int err = mSensors[index]->enable(handle, enabled); |
| 236 | if (!err) { |
| 237 | const char wakeMessage(WAKE_MESSAGE); |
| 238 | int result = write(mWritePipeFd, &wakeMessage, 1); |
| 239 | ALOGE_IF(result<0, "error sending wake message (%s)", strerror(errno)); |
| 240 | } |
| 241 | return err; |
| 242 | } |
| 243 | |
| 244 | int sensors_poll_context_t::setDelay(int handle, int64_t ns) |
| 245 | { |
| 246 | FUNC_LOG; |
| 247 | int index = handleToDriver(handle); |
| 248 | if (index < 0) return index; |
| 249 | return mSensors[index]->setDelay(handle, ns); |
| 250 | } |
| 251 | |
| 252 | int sensors_poll_context_t::pollEvents(sensors_event_t* data, int count) |
| 253 | { |
| 254 | //FUNC_LOG; |
| 255 | int nbEvents = 0; |
| 256 | int n = 0; |
| 257 | int polltime = -1; |
JP Abgrall | 5dcc6c9 | 2012-05-31 20:39:43 -0700 | [diff] [blame] | 258 | do { |
JP Abgrall | 5dcc6c9 | 2012-05-31 20:39:43 -0700 | [diff] [blame] | 259 | for (int i=0 ; count && i<numSensorDrivers ; i++) { |
| 260 | SensorBase* const sensor(mSensors[i]); |
JP Abgrall | db7bdef | 2012-06-21 15:04:34 -0700 | [diff] [blame] | 261 | // See if we have some pending events from the last poll() |
JP Abgrall | 87e826c | 2012-10-03 20:50:01 -0700 | [diff] [blame] | 262 | if ((mPollFds[i].revents & (POLLIN | POLLPRI)) || (sensor->hasPendingEvents())) { |
JP Abgrall | 49d4995 | 2012-06-16 00:44:51 -0700 | [diff] [blame] | 263 | int nb; |
| 264 | if (i == compass) { |
JP Abgrall | db7bdef | 2012-06-21 15:04:34 -0700 | [diff] [blame] | 265 | /* result is hardcoded to 0 */ |
| 266 | ((MPLSensor*) sensor)->readCompassEvents(NULL, count); |
| 267 | nb = ((MPLSensor*) mSensors[mpl])->executeOnData(data, count); |
JP Abgrall | 49d4995 | 2012-06-16 00:44:51 -0700 | [diff] [blame] | 268 | } |
| 269 | else if (i == mpl) { |
JP Abgrall | db7bdef | 2012-06-21 15:04:34 -0700 | [diff] [blame] | 270 | /* result is hardcoded to 0 */ |
| 271 | sensor->readEvents(NULL, count); |
| 272 | nb = ((MPLSensor*) mSensors[mpl])->executeOnData(data, count); |
JP Abgrall | 87e826c | 2012-10-03 20:50:01 -0700 | [diff] [blame] | 273 | mPollFds[i].revents = 0; |
JP Abgrall | 49d4995 | 2012-06-16 00:44:51 -0700 | [diff] [blame] | 274 | } |
JP Abgrall | 3d96702 | 2012-10-22 12:42:18 -0700 | [diff] [blame] | 275 | #ifdef ENABLE_DMP_DISPL_ORIENT_FEAT |
| 276 | else if (i == dmpOrient) { |
| 277 | nb = ((MPLSensor*) mSensors[mpl])->readDmpOrientEvents(data, count); |
| 278 | mPollFds[dmpOrient].revents= 0; |
| 279 | if (!isDmpScreenAutoRotationEnabled()) { |
| 280 | /* ignore the data */ |
| 281 | nb = 0; |
| 282 | } |
| 283 | } |
| 284 | #endif |
JP Abgrall | 49d4995 | 2012-06-16 00:44:51 -0700 | [diff] [blame] | 285 | else { |
| 286 | nb = sensor->readEvents(data, count); |
| 287 | } |
JP Abgrall | 5dcc6c9 | 2012-05-31 20:39:43 -0700 | [diff] [blame] | 288 | if (nb < count) { |
| 289 | // no more data for this sensor |
| 290 | mPollFds[i].revents = 0; |
| 291 | } |
| 292 | count -= nb; |
| 293 | nbEvents += nb; |
| 294 | data += nb; |
| 295 | } |
| 296 | } |
JP Abgrall | 5dcc6c9 | 2012-05-31 20:39:43 -0700 | [diff] [blame] | 297 | if (count) { |
JP Abgrall | 5dcc6c9 | 2012-05-31 20:39:43 -0700 | [diff] [blame] | 298 | do { |
| 299 | n = poll(mPollFds, numFds, nbEvents ? 0 : polltime); |
| 300 | } while (n < 0 && errno == EINTR); |
JP Abgrall | db7bdef | 2012-06-21 15:04:34 -0700 | [diff] [blame] | 301 | if (n < 0) { |
JP Abgrall | 5dcc6c9 | 2012-05-31 20:39:43 -0700 | [diff] [blame] | 302 | ALOGE("poll() failed (%s)", strerror(errno)); |
| 303 | return -errno; |
| 304 | } |
JP Abgrall | 87e826c | 2012-10-03 20:50:01 -0700 | [diff] [blame] | 305 | if (mPollFds[wake].revents & (POLLIN | POLLPRI)) { |
JP Abgrall | 5dcc6c9 | 2012-05-31 20:39:43 -0700 | [diff] [blame] | 306 | char msg; |
| 307 | int result = read(mPollFds[wake].fd, &msg, 1); |
| 308 | ALOGE_IF(result<0, "error reading from wake pipe (%s)", strerror(errno)); |
| 309 | ALOGE_IF(msg != WAKE_MESSAGE, "unknown message on wake queue (0x%02x)", int(msg)); |
| 310 | mPollFds[wake].revents = 0; |
| 311 | } |
| 312 | } |
| 313 | // if we have events and space, go read them |
| 314 | } while (n && count); |
| 315 | |
| 316 | return nbEvents; |
| 317 | } |
| 318 | |
| 319 | /*****************************************************************************/ |
| 320 | |
| 321 | static int poll__close(struct hw_device_t *dev) |
| 322 | { |
| 323 | FUNC_LOG; |
| 324 | sensors_poll_context_t *ctx = (sensors_poll_context_t *)dev; |
| 325 | if (ctx) { |
| 326 | delete ctx; |
| 327 | } |
| 328 | return 0; |
| 329 | } |
| 330 | |
| 331 | static int poll__activate(struct sensors_poll_device_t *dev, |
| 332 | int handle, int enabled) |
| 333 | { |
| 334 | FUNC_LOG; |
| 335 | sensors_poll_context_t *ctx = (sensors_poll_context_t *)dev; |
| 336 | return ctx->activate(handle, enabled); |
| 337 | } |
| 338 | |
| 339 | static int poll__setDelay(struct sensors_poll_device_t *dev, |
| 340 | int handle, int64_t ns) |
| 341 | { |
| 342 | FUNC_LOG; |
| 343 | sensors_poll_context_t *ctx = (sensors_poll_context_t *)dev; |
| 344 | return ctx->setDelay(handle, ns); |
| 345 | } |
| 346 | |
| 347 | static int poll__poll(struct sensors_poll_device_t *dev, |
| 348 | sensors_event_t* data, int count) |
| 349 | { |
| 350 | FUNC_LOG; |
| 351 | sensors_poll_context_t *ctx = (sensors_poll_context_t *)dev; |
| 352 | return ctx->pollEvents(data, count); |
| 353 | } |
| 354 | |
| 355 | /*****************************************************************************/ |
| 356 | |
| 357 | /** Open a new instance of a sensor device using name */ |
| 358 | static int open_sensors(const struct hw_module_t* module, const char* id, |
| 359 | struct hw_device_t** device) |
| 360 | { |
| 361 | FUNC_LOG; |
| 362 | int status = -EINVAL; |
| 363 | sensors_poll_context_t *dev = new sensors_poll_context_t(); |
| 364 | |
JP Abgrall | acd411c | 2012-06-21 20:01:28 -0700 | [diff] [blame] | 365 | if (!dev->isValid()) { |
| 366 | ALOGE("Failed to open the sensors"); |
| 367 | return status; |
| 368 | } |
| 369 | |
JP Abgrall | 5dcc6c9 | 2012-05-31 20:39:43 -0700 | [diff] [blame] | 370 | memset(&dev->device, 0, sizeof(sensors_poll_device_t)); |
| 371 | |
| 372 | dev->device.common.tag = HARDWARE_DEVICE_TAG; |
| 373 | dev->device.common.version = 0; |
| 374 | dev->device.common.module = const_cast<hw_module_t*>(module); |
| 375 | dev->device.common.close = poll__close; |
| 376 | dev->device.activate = poll__activate; |
| 377 | dev->device.setDelay = poll__setDelay; |
| 378 | dev->device.poll = poll__poll; |
| 379 | |
| 380 | *device = &dev->device.common; |
| 381 | status = 0; |
| 382 | |
| 383 | return status; |
| 384 | } |