1 /* 2 * Copyright (C) 2008 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 #include <fcntl.h> 18 #include <errno.h> 19 #include <math.h> 20 #include <poll.h> 21 #include <unistd.h> 22 #include <dirent.h> 23 #include <sys/select.h> 24 25 #include <linux/akm8975.h> 26 27 #include <cutils/log.h> 28 29 #include "AkmSensor.h" 30 31 /*****************************************************************************/ 32 33 AkmSensor::AkmSensor() 34 : SensorBase(AKM_DEVICE_NAME, "compass"), 35 mEnabled(0), 36 mPendingMask(0), 37 mInputReader(32) 38 { 39 memset(mPendingEvents, 0, sizeof(mPendingEvents)); 40 41 mPendingEvents[Accelerometer].version = sizeof(sensors_event_t); 42 mPendingEvents[Accelerometer].sensor = ID_A; 43 mPendingEvents[Accelerometer].type = SENSOR_TYPE_ACCELEROMETER; 44 mPendingEvents[Accelerometer].acceleration.status = SENSOR_STATUS_ACCURACY_HIGH; 45 46 mPendingEvents[MagneticField].version = sizeof(sensors_event_t); 47 mPendingEvents[MagneticField].sensor = ID_M; 48 mPendingEvents[MagneticField].type = SENSOR_TYPE_MAGNETIC_FIELD; 49 mPendingEvents[MagneticField].magnetic.status = SENSOR_STATUS_ACCURACY_HIGH; 50 51 mPendingEvents[Orientation ].version = sizeof(sensors_event_t); 52 mPendingEvents[Orientation ].sensor = ID_O; 53 mPendingEvents[Orientation ].type = SENSOR_TYPE_ORIENTATION; 54 mPendingEvents[Orientation ].orientation.status = SENSOR_STATUS_ACCURACY_HIGH; 55 56 for (int i=0 ; i<numSensors ; i++) 57 mDelays[i] = 200000000; // 200 ms by default 58 59 // read the actual value of all sensors if they're enabled already 60 struct input_absinfo absinfo; 61 short flags = 0; 62 63 open_device(); 64 65 if (!ioctl(dev_fd, ECS_IOCTL_APP_GET_AFLAG, &flags)) { 66 if (flags) { 67 mEnabled |= 1<<Accelerometer; 68 } 69 } 70 if (!ioctl(dev_fd, ECS_IOCTL_APP_GET_MVFLAG, &flags)) { 71 if (flags) { 72 mEnabled |= 1<<MagneticField; 73 } 74 } 75 if (!ioctl(dev_fd, ECS_IOCTL_APP_GET_MFLAG, &flags)) { 76 if (flags) { 77 mEnabled |= 1<<Orientation; 78 } 79 } 80 if (!mEnabled) { 81 close_device(); 82 } 83 } 84 85 AkmSensor::~AkmSensor() { 86 } 87 88 int AkmSensor::enable(int32_t handle, int en) 89 { 90 int what = -1; 91 switch (handle) { 92 case ID_A: what = Accelerometer; break; 93 case ID_M: what = MagneticField; break; 94 case ID_O: what = Orientation; break; 95 } 96 97 if (uint32_t(what) >= numSensors) 98 return -EINVAL; 99 100 int newState = en ? 1 : 0; 101 int err = 0; 102 103 if ((uint32_t(newState)<<what) != (mEnabled & (1<<what))) { 104 if (!mEnabled) { 105 open_device(); 106 } 107 int cmd; 108 switch (what) { 109 case Accelerometer: cmd = ECS_IOCTL_APP_SET_AFLAG; break; 110 case MagneticField: cmd = ECS_IOCTL_APP_SET_MVFLAG; break; 111 case Orientation: cmd = ECS_IOCTL_APP_SET_MFLAG; break; 112 } 113 short flags = newState; 114 err = ioctl(dev_fd, cmd, &flags); 115 err = err<0 ? -errno : 0; 116 LOGE_IF(err, "ECS_IOCTL_APP_SET_XXX failed (%s)", strerror(-err)); 117 if (!err) { 118 mEnabled &= ~(1<<what); 119 mEnabled |= (uint32_t(flags)<<what); 120 update_delay(); 121 } 122 if (!mEnabled) { 123 close_device(); 124 } 125 } 126 return err; 127 } 128 129 int AkmSensor::setDelay(int32_t handle, int64_t ns) 130 { 131 #ifdef ECS_IOCTL_APP_SET_DELAY 132 int what = -1; 133 switch (handle) { 134 case ID_A: what = Accelerometer; break; 135 case ID_M: what = MagneticField; break; 136 case ID_O: what = Orientation; break; 137 } 138 139 if (uint32_t(what) >= numSensors) 140 return -EINVAL; 141 142 if (ns < 0) 143 return -EINVAL; 144 145 mDelays[what] = ns; 146 return update_delay(); 147 #else 148 return -1; 149 #endif 150 } 151 152 int AkmSensor::update_delay() 153 { 154 if (mEnabled) { 155 uint64_t wanted = -1LLU; 156 for (int i=0 ; i<numSensors ; i++) { 157 if (mEnabled & (1<<i)) { 158 uint64_t ns = mDelays[i]; 159 wanted = wanted < ns ? wanted : ns; 160 } 161 } 162 short delay = int64_t(wanted) / 1000000; 163 if (ioctl(dev_fd, ECS_IOCTL_APP_SET_DELAY, &delay)) { 164 return -errno; 165 } 166 } 167 return 0; 168 } 169 170 int AkmSensor::readEvents(sensors_event_t* data, int count) 171 { 172 if (count < 1) 173 return -EINVAL; 174 175 ssize_t n = mInputReader.fill(data_fd); 176 if (n < 0) 177 return n; 178 179 int numEventReceived = 0; 180 input_event const* event; 181 182 while (count && mInputReader.readEvent(&event)) { 183 int type = event->type; 184 if (type == EV_REL) { 185 processEvent(event->code, event->value); 186 mInputReader.next(); 187 } else if (type == EV_SYN) { 188 int64_t time = timevalToNano(event->time); 189 for (int j=0 ; count && mPendingMask && j<numSensors ; j++) { 190 if (mPendingMask & (1<<j)) { 191 mPendingMask &= ~(1<<j); 192 mPendingEvents[j].timestamp = time; 193 if (mEnabled & (1<<j)) { 194 *data++ = mPendingEvents[j]; 195 count--; 196 numEventReceived++; 197 } 198 } 199 } 200 if (!mPendingMask) { 201 mInputReader.next(); 202 } 203 } else { 204 LOGE("AkmSensor: unknown event (type=%d, code=%d)", 205 type, event->code); 206 mInputReader.next(); 207 } 208 } 209 210 return numEventReceived; 211 } 212 213 void AkmSensor::processEvent(int code, int value) 214 { 215 switch (code) { 216 case EVENT_TYPE_ACCEL_X: 217 mPendingMask |= 1<<Accelerometer; 218 mPendingEvents[Accelerometer].acceleration.x = value * CONVERT_A_X; 219 break; 220 case EVENT_TYPE_ACCEL_Y: 221 mPendingMask |= 1<<Accelerometer; 222 mPendingEvents[Accelerometer].acceleration.y = value * CONVERT_A_Y; 223 break; 224 case EVENT_TYPE_ACCEL_Z: 225 mPendingMask |= 1<<Accelerometer; 226 mPendingEvents[Accelerometer].acceleration.z = value * CONVERT_A_Z; 227 break; 228 229 case EVENT_TYPE_MAGV_X: 230 mPendingMask |= 1<<MagneticField; 231 mPendingEvents[MagneticField].magnetic.x = value * CONVERT_M_X; 232 break; 233 case EVENT_TYPE_MAGV_Y: 234 mPendingMask |= 1<<MagneticField; 235 mPendingEvents[MagneticField].magnetic.y = value * CONVERT_M_Y; 236 break; 237 case EVENT_TYPE_MAGV_Z: 238 mPendingMask |= 1<<MagneticField; 239 mPendingEvents[MagneticField].magnetic.z = value * CONVERT_M_Z; 240 break; 241 242 case EVENT_TYPE_YAW: 243 mPendingMask |= 1<<Orientation; 244 mPendingEvents[Orientation].orientation.azimuth = value * CONVERT_O_Y; 245 break; 246 case EVENT_TYPE_PITCH: 247 mPendingMask |= 1<<Orientation; 248 mPendingEvents[Orientation].orientation.pitch = value * CONVERT_O_P; 249 break; 250 case EVENT_TYPE_ROLL: 251 mPendingMask |= 1<<Orientation; 252 mPendingEvents[Orientation].orientation.roll = value * CONVERT_O_R; 253 break; 254 case EVENT_TYPE_ORIENT_STATUS: 255 mPendingMask |= 1<<Orientation; 256 mPendingEvents[Orientation].orientation.status = 257 uint8_t(value & SENSOR_STATE_MASK); 258 break; 259 } 260 } 261