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#include "local_log_def.h" 36 37/*****************************************************************************/ 38/* The SENSORS Module */ 39 40#ifdef ENABLE_DMP_SCREEN_AUTO_ROTATION 41#define LOCAL_SENSORS (numSensors + 1) 42#else 43#define LOCAL_SENSORS numSensors 44 45#endif 46 47static struct sensor_t sSensorList[LOCAL_SENSORS]; 48static int sensors = LOCAL_SENSORS; 49 50static int open_sensors(const struct hw_module_t* module, const char* id, 51 struct hw_device_t** device); 52 53static int sensors__get_sensors_list(struct sensors_module_t* module, 54 struct sensor_t const** list) 55{ 56 *list = sSensorList; 57 return sensors; 58} 59 60static struct hw_module_methods_t sensors_module_methods = { 61 open: open_sensors 62}; 63 64struct sensors_module_t HAL_MODULE_INFO_SYM = { 65 common: { 66 tag: HARDWARE_MODULE_TAG, 67 version_major: 1, 68 version_minor: 0, 69 id: SENSORS_HARDWARE_MODULE_ID, 70 name: "Invensense module", 71 author: "Invensense Inc.", 72 methods: &sensors_module_methods, 73 }, 74 get_sensors_list: sensors__get_sensors_list, 75}; 76 77struct sensors_poll_context_t { 78 struct sensors_poll_device_t device; // must be first 79 80 sensors_poll_context_t(); 81 ~sensors_poll_context_t(); 82 int activate(int handle, int enabled); 83 int setDelay(int handle, int64_t ns); 84 int pollEvents(sensors_event_t* data, int count); 85 86private: 87 enum { 88 mpl = 0, 89 compass, 90 dmpOrient, 91 numSensorDrivers, // wake pipe goes here 92 numFds, 93 }; 94 95 struct pollfd mPollFds[numSensorDrivers]; 96 SensorBase *mSensor; 97}; 98 99/******************************************************************************/ 100 101sensors_poll_context_t::sensors_poll_context_t() { 102 VFUNC_LOG; 103 104 CompassSensor *mCompassSensor = new CompassSensor(); 105 MPLSensor *mplSensor = new MPLSensor(mCompassSensor); 106 107 // setup the callback object for handing mpl callbacks 108 setCallbackObject(mplSensor); 109 110 // populate the sensor list 111 sensors = 112 mplSensor->populateSensorList(sSensorList, sizeof(sSensorList)); 113 114 mSensor = mplSensor; 115 mPollFds[mpl].fd = mSensor->getFd(); 116 mPollFds[mpl].events = POLLIN; 117 mPollFds[mpl].revents = 0; 118 119 mPollFds[compass].fd = mCompassSensor->getFd(); 120 mPollFds[compass].events = POLLIN; 121 mPollFds[compass].revents = 0; 122 123 mPollFds[dmpOrient].fd = ((MPLSensor*) mSensor)->getDmpOrientFd(); 124 mPollFds[dmpOrient].events = POLLPRI; 125 mPollFds[dmpOrient].revents = 0; 126} 127 128sensors_poll_context_t::~sensors_poll_context_t() { 129 FUNC_LOG; 130 delete mSensor; 131} 132 133int sensors_poll_context_t::activate(int handle, int enabled) { 134 FUNC_LOG; 135 return mSensor->enable(handle, enabled); 136} 137 138int sensors_poll_context_t::setDelay(int handle, int64_t ns) 139{ 140 FUNC_LOG; 141 return mSensor->setDelay(handle, ns); 142} 143 144int sensors_poll_context_t::pollEvents(sensors_event_t *data, int count) 145{ 146 VHANDLER_LOG; 147 148 int nbEvents = 0; 149 int nb, polltime = -1; 150 151 // look for new events 152 nb = poll(mPollFds, numSensorDrivers, polltime); 153 154 if (nb > 0) { 155 for (int i = 0; count && i < numSensorDrivers; i++) { 156 if (mPollFds[i].revents & (POLLIN | POLLPRI)) { 157 nb = 0; 158 if (i == mpl) { 159 nb = mSensor->readEvents(data, count); 160 mPollFds[i].revents = 0; 161 } 162 else if (i == compass) { 163 nb = ((MPLSensor*) mSensor)->readCompassEvents(data, count); 164 mPollFds[i].revents = 0; 165 } 166 } 167 } 168 nb = ((MPLSensor*) mSensor)->executeOnData(data, count); 169 if (nb > 0) { 170 count -= nb; 171 nbEvents += nb; 172 data += nb; 173 } 174 175 if (mPollFds[dmpOrient].revents & (POLLIN | POLLPRI)) { 176 nb = ((MPLSensor*) mSensor)->readDmpOrientEvents(data, count); 177 mPollFds[dmpOrient].revents= 0; 178 if (isDmpScreenAutoRotationOn() && nb > 0) { 179 count -= nb; 180 nbEvents += nb; 181 data += nb; 182 } 183 } 184 } 185 186 return nbEvents; 187} 188 189/******************************************************************************/ 190 191static int poll__close(struct hw_device_t *dev) 192{ 193 FUNC_LOG; 194 sensors_poll_context_t *ctx = (sensors_poll_context_t *)dev; 195 if (ctx) { 196 delete ctx; 197 } 198 return 0; 199} 200 201static int poll__activate(struct sensors_poll_device_t *dev, 202 int handle, int enabled) 203{ 204 sensors_poll_context_t *ctx = (sensors_poll_context_t *)dev; 205 return ctx->activate(handle, enabled); 206} 207 208static int poll__setDelay(struct sensors_poll_device_t *dev, 209 int handle, int64_t ns) 210{ 211 sensors_poll_context_t *ctx = (sensors_poll_context_t *)dev; 212 int s= ctx->setDelay(handle, ns); 213 return s; 214} 215 216static int poll__poll(struct sensors_poll_device_t *dev, 217 sensors_event_t* data, int count) 218{ 219 sensors_poll_context_t *ctx = (sensors_poll_context_t *)dev; 220 return ctx->pollEvents(data, count); 221} 222 223/******************************************************************************/ 224 225/** Open a new instance of a sensor device using name */ 226static int open_sensors(const struct hw_module_t* module, const char* id, 227 struct hw_device_t** device) 228{ 229 FUNC_LOG; 230 int status = -EINVAL; 231 sensors_poll_context_t *dev = new sensors_poll_context_t(); 232 233 memset(&dev->device, 0, sizeof(sensors_poll_device_t)); 234 235 dev->device.common.tag = HARDWARE_DEVICE_TAG; 236 dev->device.common.version = 0; 237 dev->device.common.module = const_cast<hw_module_t*>(module); 238 dev->device.common.close = poll__close; 239 dev->device.activate = poll__activate; 240 dev->device.setDelay = poll__setDelay; 241 dev->device.poll = poll__poll; 242 243 *device = &dev->device.common; 244 status = 0; 245 246 return status; 247} 248