sensors_mpl.cpp revision 6a4d9a48ffde124c498496f6dae1e77c2cae6864
1/* 2* Copyright (C) 2012 Invensense, Inc. 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 FUNC_LOG LOGV("%s", __PRETTY_FUNCTION__) 18 19#include <hardware/sensors.h> 20#include <fcntl.h> 21#include <errno.h> 22#include <dirent.h> 23#include <math.h> 24#include <poll.h> 25#include <pthread.h> 26#include <stdlib.h> 27 28#include <linux/input.h> 29 30#include <utils/Atomic.h> 31#include <utils/Log.h> 32 33#include "sensors.h" 34#include "MPLSensor.h" 35 36/*****************************************************************************/ 37/* The SENSORS Module */ 38 39#ifdef ENABLE_DMP_SCREEN_AUTO_ROTATION 40#define LOCAL_SENSORS (MPLSensor::NUMSENSORS + 1) 41#else 42#define LOCAL_SENSORS MPLSensor::NUMSENSORS 43#endif 44 45/* Vendor-defined Accel Load Calibration File Method 46* @param[out] Accel bias, length 3. In HW units scaled by 2^16 in body frame 47* @return '0' for a successful load, '1' otherwise 48* example: int AccelLoadConfig(long* offset); 49* End of Vendor-defined Accel Load Cal Method 50*/ 51 52static struct sensor_t sSensorList[LOCAL_SENSORS]; 53static int sensors = (sizeof(sSensorList) / sizeof(sensor_t)); 54 55static int open_sensors(const struct hw_module_t* module, const char* id, 56 struct hw_device_t** device); 57 58static int sensors__get_sensors_list(struct sensors_module_t* module, 59 struct sensor_t const** list) 60{ 61 *list = sSensorList; 62 return sensors; 63} 64 65static struct hw_module_methods_t sensors_module_methods = { 66 open: open_sensors 67}; 68 69struct sensors_module_t HAL_MODULE_INFO_SYM = { 70 common: { 71 tag: HARDWARE_MODULE_TAG, 72 version_major: 1, 73 version_minor: 0, 74 id: SENSORS_HARDWARE_MODULE_ID, 75 name: "Invensense module", 76 author: "Invensense Inc.", 77 methods: &sensors_module_methods, 78 }, 79 get_sensors_list: sensors__get_sensors_list, 80}; 81 82struct sensors_poll_context_t { 83 struct sensors_poll_device_t device; // must be first 84 85 sensors_poll_context_t(); 86 ~sensors_poll_context_t(); 87 int activate(int handle, int enabled); 88 int setDelay(int handle, int64_t ns); 89 int pollEvents(sensors_event_t* data, int count); 90 91private: 92 enum { 93 mpl = 0, 94 compass, 95 dmpOrient, 96 numSensorDrivers, // wake pipe goes here 97 numFds, 98 }; 99 100 struct pollfd mPollFds[numSensorDrivers]; 101 SensorBase *mSensor; 102 CompassSensor *mCompassSensor; 103}; 104 105/******************************************************************************/ 106 107sensors_poll_context_t::sensors_poll_context_t() { 108 VFUNC_LOG; 109 110 mCompassSensor = new CompassSensor(); 111 MPLSensor *mplSensor = new MPLSensor(mCompassSensor); 112 113 /* For Vendor-defined Accel Calibration File Load 114 * Use the Following Constructor and Pass Your Load Cal File Function 115 * 116 * MPLSensor *mplSensor = new MPLSensor(mCompassSensor, AccelLoadConfig); 117 */ 118 119 // setup the callback object for handing mpl callbacks 120 setCallbackObject(mplSensor); 121 122 // populate the sensor list 123 sensors = 124 mplSensor->populateSensorList(sSensorList, sizeof(sSensorList)); 125 126 mSensor = mplSensor; 127 mPollFds[mpl].fd = mSensor->getFd(); 128 mPollFds[mpl].events = POLLIN; 129 mPollFds[mpl].revents = 0; 130 131 mPollFds[compass].fd = mCompassSensor->getFd(); 132 mPollFds[compass].events = POLLIN; 133 mPollFds[compass].revents = 0; 134 135 mPollFds[dmpOrient].fd = ((MPLSensor*) mSensor)->getDmpOrientFd(); 136 mPollFds[dmpOrient].events = POLLPRI; 137 mPollFds[dmpOrient].revents = 0; 138} 139 140sensors_poll_context_t::~sensors_poll_context_t() { 141 FUNC_LOG; 142 delete mSensor; 143 delete mCompassSensor; 144} 145 146int sensors_poll_context_t::activate(int handle, int enabled) { 147 FUNC_LOG; 148 return mSensor->enable(handle, enabled); 149} 150 151int sensors_poll_context_t::setDelay(int handle, int64_t ns) 152{ 153 FUNC_LOG; 154 return mSensor->setDelay(handle, ns); 155} 156 157int sensors_poll_context_t::pollEvents(sensors_event_t *data, int count) 158{ 159 VHANDLER_LOG; 160 161 int nbEvents = 0; 162 int nb, polltime = -1; 163 164 // look for new events 165 nb = poll(mPollFds, numSensorDrivers, polltime); 166 167 if (nb > 0) { 168 for (int i = 0; count && i < numSensorDrivers; i++) { 169 if (mPollFds[i].revents & (POLLIN | POLLPRI)) { 170 nb = 0; 171 if (i == mpl) { 172 nb = mSensor->readEvents(NULL, 0); 173 mPollFds[i].revents = 0; 174 } 175 else if (i == compass) { 176 nb = ((MPLSensor*) mSensor)->readCompassEvents(NULL, 0); 177 mPollFds[i].revents = 0; 178 } 179 } 180 } 181 nb = ((MPLSensor*) mSensor)->executeOnData(data, count); 182 if (nb > 0) { 183 count -= nb; 184 nbEvents += nb; 185 data += nb; 186 } 187 188 if (mPollFds[dmpOrient].revents & (POLLIN | POLLPRI)) { 189 nb = ((MPLSensor*) mSensor)->readDmpOrientEvents(data, count); 190 mPollFds[dmpOrient].revents= 0; 191 if (isDmpScreenAutoRotationEnabled() && nb > 0) { 192 count -= nb; 193 nbEvents += nb; 194 data += nb; 195 } 196 } 197 } 198 199 return nbEvents; 200} 201 202/******************************************************************************/ 203 204static int poll__close(struct hw_device_t *dev) 205{ 206 FUNC_LOG; 207 sensors_poll_context_t *ctx = (sensors_poll_context_t *)dev; 208 if (ctx) { 209 delete ctx; 210 } 211 return 0; 212} 213 214static int poll__activate(struct sensors_poll_device_t *dev, 215 int handle, int enabled) 216{ 217 sensors_poll_context_t *ctx = (sensors_poll_context_t *)dev; 218 return ctx->activate(handle, enabled); 219} 220 221static int poll__setDelay(struct sensors_poll_device_t *dev, 222 int handle, int64_t ns) 223{ 224 sensors_poll_context_t *ctx = (sensors_poll_context_t *)dev; 225 int s= ctx->setDelay(handle, ns); 226 return s; 227} 228 229static int poll__poll(struct sensors_poll_device_t *dev, 230 sensors_event_t* data, int count) 231{ 232 sensors_poll_context_t *ctx = (sensors_poll_context_t *)dev; 233 return ctx->pollEvents(data, count); 234} 235 236/******************************************************************************/ 237 238/** Open a new instance of a sensor device using name */ 239static int open_sensors(const struct hw_module_t* module, const char* id, 240 struct hw_device_t** device) 241{ 242 FUNC_LOG; 243 int status = -EINVAL; 244 sensors_poll_context_t *dev = new sensors_poll_context_t(); 245 246 memset(&dev->device, 0, sizeof(sensors_poll_device_t)); 247 248 dev->device.common.tag = HARDWARE_DEVICE_TAG; 249 dev->device.common.version = 0; 250 dev->device.common.module = const_cast<hw_module_t*>(module); 251 dev->device.common.close = poll__close; 252 dev->device.activate = poll__activate; 253 dev->device.setDelay = poll__setDelay; 254 dev->device.poll = poll__poll; 255 256 *device = &dev->device.common; 257 status = 0; 258 259 return status; 260} 261