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 52 static struct sensor_t sSensorList[LOCAL_SENSORS]; 53 static int sensors = (sizeof(sSensorList) / sizeof(sensor_t)); 54 55 static int open_sensors(const struct hw_module_t* module, const char* id, 56 struct hw_device_t** device); 57 58 static 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 65 static struct hw_module_methods_t sensors_module_methods = { 66 open: open_sensors 67 }; 68 69 struct 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 82 struct 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 91 private: 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 }; 103 104 /******************************************************************************/ 105 106 sensors_poll_context_t::sensors_poll_context_t() { 107 VFUNC_LOG; 108 109 mCompassSensor = new CompassSensor(); 110 MPLSensor *mplSensor = new MPLSensor(mCompassSensor); 111 112 /* For Vendor-defined Accel Calibration File Load 113 * Use the Following Constructor and Pass Your Load Cal File Function 114 * 115 * MPLSensor *mplSensor = new MPLSensor(mCompassSensor, AccelLoadConfig); 116 */ 117 118 // setup the callback object for handing mpl callbacks 119 setCallbackObject(mplSensor); 120 121 // populate the sensor list 122 sensors = 123 mplSensor->populateSensorList(sSensorList, sizeof(sSensorList)); 124 125 mSensor = mplSensor; 126 mPollFds[mpl].fd = mSensor->getFd(); 127 mPollFds[mpl].events = POLLIN; 128 mPollFds[mpl].revents = 0; 129 130 mPollFds[compass].fd = mCompassSensor->getFd(); 131 mPollFds[compass].events = POLLIN; 132 mPollFds[compass].revents = 0; 133 134 mPollFds[dmpOrient].fd = ((MPLSensor*) mSensor)->getDmpOrientFd(); 135 mPollFds[dmpOrient].events = POLLPRI; 136 mPollFds[dmpOrient].revents = 0; 137 } 138 139 sensors_poll_context_t::~sensors_poll_context_t() { 140 FUNC_LOG; 141 delete mSensor; 142 } 143 144 int sensors_poll_context_t::activate(int handle, int enabled) { 145 FUNC_LOG; 146 return mSensor->enable(handle, enabled); 147 } 148 149 int sensors_poll_context_t::setDelay(int handle, int64_t ns) 150 { 151 FUNC_LOG; 152 return mSensor->setDelay(handle, ns); 153 } 154 155 int sensors_poll_context_t::pollEvents(sensors_event_t *data, int count) 156 { 157 VHANDLER_LOG; 158 159 int nbEvents = 0; 160 int nb, polltime = -1; 161 162 // look for new events 163 nb = poll(mPollFds, numSensorDrivers, polltime); 164 165 if (nb > 0) { 166 for (int i = 0; count && i < numSensorDrivers; i++) { 167 if (mPollFds[i].revents & (POLLIN | POLLPRI)) { 168 nb = 0; 169 if (i == mpl) { 170 /* Ignore res */ 171 mSensor->readEvents(NULL, 0); 172 mPollFds[i].revents = 0; 173 } 174 else if (i == compass) { 175 /* Ignore res */ 176 ((MPLSensor*) mSensor)->readCompassEvents(NULL, count); 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 204 static 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 214 static 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 221 static 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 229 static 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 */ 239 static 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