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