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 LOG_NDEBUG 0 18 //see also the EXTRA_VERBOSE define in the MPLSensor.h header file 19 20 #include <fcntl.h> 21 #include <errno.h> 22 #include <math.h> 23 #include <float.h> 24 #include <poll.h> 25 #include <unistd.h> 26 #include <dirent.h> 27 #include <stdlib.h> 28 #include <sys/select.h> 29 #include <sys/syscall.h> 30 #include <dlfcn.h> 31 #include <pthread.h> 32 #include <cutils/log.h> 33 #include <utils/KeyedVector.h> 34 #include <utils/String8.h> 35 #include <string.h> 36 #include <linux/input.h> 37 #include <utils/Atomic.h> 38 39 #include "MPLSensor.h" 40 #include "MPLSupport.h" 41 #include "sensor_params.h" 42 #include "local_log_def.h" 43 44 #include "invensense.h" 45 #include "invensense_adv.h" 46 #include "ml_stored_data.h" 47 #include "ml_load_dmp.h" 48 #include "ml_sysfs_helper.h" 49 50 // #define TESTING 51 52 #ifdef THIRD_PARTY_ACCEL 53 # warning "Third party accel" 54 # define USE_THIRD_PARTY_ACCEL (1) 55 #else 56 # define USE_THIRD_PARTY_ACCEL (0) 57 #endif 58 59 #define MAX_SYSFS_ATTRB (sizeof(struct sysfs_attrbs) / sizeof(char*)) 60 61 /******************************************************************************/ 62 /* MPL interface misc. */ 63 /******************************************************************************/ 64 static int hertz_request = 200; 65 66 #define DEFAULT_MPL_GYRO_RATE (20000L) //us 67 #define DEFAULT_MPL_COMPASS_RATE (20000L) //us 68 69 #define DEFAULT_HW_GYRO_RATE (100) //Hz 70 #define DEFAULT_HW_ACCEL_RATE (20) //ms 71 #define DEFAULT_HW_COMPASS_RATE (20000000L) //ns 72 #define DEFAULT_HW_AKMD_COMPASS_RATE (200000000L) //ns 73 74 /* convert ns to hardware units */ 75 #define HW_GYRO_RATE_NS (1000000000LL / rate_request) // to Hz 76 #define HW_ACCEL_RATE_NS (rate_request / (1000000L)) // to ms 77 #define HW_COMPASS_RATE_NS (rate_request) // to ns 78 79 /* convert Hz to hardware units */ 80 #define HW_GYRO_RATE_HZ (hertz_request) 81 #define HW_ACCEL_RATE_HZ (1000 / hertz_request) 82 #define HW_COMPASS_RATE_HZ (1000000000LL / hertz_request) 83 84 #define RATE_200HZ 5000000LL 85 #define RATE_15HZ 66667000LL 86 #define RATE_5HZ 200000000LL 87 88 static struct sensor_t sSensorList[] = 89 { 90 {"MPL Gyroscope", "Invensense", 1, 91 SENSORS_GYROSCOPE_HANDLE, 92 SENSOR_TYPE_GYROSCOPE, 2000.0f, 1.0f, 0.5f, 10000, 0, 0, 0, 0, 0, 0, {}}, 93 {"MPL Raw Gyroscope", "Invensense", 1, 94 SENSORS_RAW_GYROSCOPE_HANDLE, 95 SENSOR_TYPE_GYROSCOPE, 2000.0f, 1.0f, 0.5f, 10000, 0, 0, 0, 0, 0, 0, {}}, 96 {"MPL Accelerometer", "Invensense", 1, 97 SENSORS_ACCELERATION_HANDLE, 98 SENSOR_TYPE_ACCELEROMETER, 10240.0f, 1.0f, 0.5f, 10000, 0, 0, 0, 0, 0, 0, {}}, 99 {"MPL Magnetic Field", "Invensense", 1, 100 SENSORS_MAGNETIC_FIELD_HANDLE, 101 SENSOR_TYPE_MAGNETIC_FIELD, 10240.0f, 1.0f, 0.5f, 10000, 0, 0, 0, 0, 0, 0, {}}, 102 {"MPL Orientation", "Invensense", 1, 103 SENSORS_ORIENTATION_HANDLE, 104 SENSOR_TYPE_ORIENTATION, 360.0f, 1.0f, 9.7f, 10000, 0, 0, 0, 0, 0, 0, {}}, 105 {"MPL Rotation Vector", "Invensense", 1, 106 SENSORS_ROTATION_VECTOR_HANDLE, 107 SENSOR_TYPE_ROTATION_VECTOR, 10240.0f, 1.0f, 0.5f, 10000, 0, 0, 0, 0, 0, 0, {}}, 108 {"MPL Linear Acceleration", "Invensense", 1, 109 SENSORS_LINEAR_ACCEL_HANDLE, 110 SENSOR_TYPE_LINEAR_ACCELERATION, 10240.0f, 1.0f, 0.5f, 10000, 0, 0, 0, 0, 0, 0, {}}, 111 {"MPL Gravity", "Invensense", 1, 112 SENSORS_GRAVITY_HANDLE, 113 SENSOR_TYPE_GRAVITY, 10240.0f, 1.0f, 0.5f, 10000, 0, 0, 0, 0, 0, 0, {}}, 114 115 #ifdef ENABLE_DMP_SCREEN_AUTO_ROTATION 116 {"MPL Screen Orientation", "Invensense ", 1, 117 SENSORS_SCREEN_ORIENTATION_HANDLE, 118 SENSOR_TYPE_SCREEN_ORIENTATION, 100.0f, 1.0f, 1.1f, 0, 0, 0, 0, 0, 0, 0, {}}, 119 #endif 120 }; 121 122 MPLSensor *MPLSensor::gMPLSensor = NULL; 123 124 extern "C" { 125 void procData_cb_wrapper() 126 { 127 if(MPLSensor::gMPLSensor) { 128 MPLSensor::gMPLSensor->cbProcData(); 129 } 130 } 131 132 void setCallbackObject(MPLSensor* gbpt) 133 { 134 MPLSensor::gMPLSensor = gbpt; 135 } 136 137 MPLSensor* getCallbackObject() { 138 return MPLSensor::gMPLSensor; 139 } 140 141 } // end of extern C 142 143 #ifdef INV_PLAYBACK_DBG 144 static FILE *logfile = NULL; 145 #endif 146 147 pthread_mutex_t GlobalHalMutex = PTHREAD_MUTEX_INITIALIZER; 148 149 /******************************************************************************* 150 * MPLSensor class implementation 151 ******************************************************************************/ 152 153 MPLSensor::MPLSensor(CompassSensor *compass, int (*m_pt2AccelCalLoadFunc)(long *)) 154 : SensorBase(NULL, NULL), 155 mNewData(0), 156 mMasterSensorMask(INV_ALL_SENSORS), 157 mLocalSensorMask(0), 158 mPollTime(-1), 159 mHaveGoodMpuCal(0), 160 mGyroAccuracy(0), 161 mAccelAccuracy(0), 162 mCompassAccuracy(0), 163 mSampleCount(0), 164 dmp_orient_fd(-1), 165 mDmpOrientationEnabled(0), 166 mEnabled(0), 167 mOldEnabledMask(0), 168 mAccelInputReader(4), 169 mGyroInputReader(32), 170 mTempScale(0), 171 mTempOffset(0), 172 mTempCurrentTime(0), 173 mAccelScale(2), 174 mPendingMask(0), 175 mSensorMask(0), 176 mFeatureActiveMask(0) { 177 VFUNC_LOG; 178 179 inv_error_t rv; 180 int i, fd; 181 char *port = NULL; 182 char *ver_str; 183 unsigned long mSensorMask; 184 int res; 185 FILE *fptr; 186 187 mCompassSensor = compass; 188 189 LOGV_IF(EXTRA_VERBOSE, 190 "HAL:MPLSensor constructor : numSensors = %d", numSensors); 191 192 pthread_mutex_init(&mMplMutex, NULL); 193 pthread_mutex_init(&mHALMutex, NULL); 194 memset(mGyroOrientation, 0, sizeof(mGyroOrientation)); 195 memset(mAccelOrientation, 0, sizeof(mAccelOrientation)); 196 197 #ifdef INV_PLAYBACK_DBG 198 LOGV_IF(PROCESS_VERBOSE, "HAL:inv_turn_on_data_logging"); 199 logfile = fopen("/data/playback.bin", "wb"); 200 if (logfile) 201 inv_turn_on_data_logging(logfile); 202 #endif 203 204 /* setup sysfs paths */ 205 inv_init_sysfs_attributes(); 206 207 /* get chip name */ 208 if (inv_get_chip_name(chip_ID) != INV_SUCCESS) { 209 LOGE("HAL:ERR- Failed to get chip ID\n"); 210 } else { 211 LOGV_IF(PROCESS_VERBOSE, "HAL:Chip ID= %s\n", chip_ID); 212 } 213 214 enable_iio_sysfs(); 215 216 /* turn on power state */ 217 onPower(1); 218 219 /* reset driver master enable */ 220 masterEnable(0); 221 222 if (isLowPowerQuatEnabled() || isDmpDisplayOrientationOn()) { 223 /* Load DMP image if capable, ie. MPU6xxx/9xxx */ 224 loadDMP(); 225 } 226 227 /* open temperature fd for temp comp */ 228 LOGV_IF(EXTRA_VERBOSE, "HAL:gyro temperature path: %s", mpu.temperature); 229 gyro_temperature_fd = open(mpu.temperature, O_RDONLY); 230 if (gyro_temperature_fd == -1) { 231 LOGE("HAL:could not open temperature node"); 232 } else { 233 LOGV_IF(EXTRA_VERBOSE, 234 "HAL:temperature_fd opened: %s", mpu.temperature); 235 } 236 237 /* read accel FSR to calcuate accel scale later */ 238 if (!USE_THIRD_PARTY_ACCEL) { 239 char buf[3]; 240 int count = 0; 241 LOGV_IF(SYSFS_VERBOSE, 242 "HAL:sysfs:cat %s (%lld)", mpu.accel_fsr, getTimestamp()); 243 244 fd = open(mpu.accel_fsr, O_RDONLY); 245 if(fd < 0) { 246 LOGE("HAL:Error opening accel FSR"); 247 } else { 248 memset(buf, 0, sizeof(buf)); 249 count = read_attribute_sensor(fd, buf, sizeof(buf)); 250 if(count < 1) { 251 LOGE("HAL:Error reading accel FSR"); 252 } else { 253 count = sscanf(buf, "%d", &mAccelScale); 254 if(count) 255 LOGV_IF(EXTRA_VERBOSE, "HAL:Accel FSR used %d", mAccelScale); 256 } 257 close(fd); 258 } 259 } 260 261 /* initialize sensor data */ 262 memset(mPendingEvents, 0, sizeof(mPendingEvents)); 263 264 mPendingEvents[RotationVector].version = sizeof(sensors_event_t); 265 mPendingEvents[RotationVector].sensor = ID_RV; 266 mPendingEvents[RotationVector].type = SENSOR_TYPE_ROTATION_VECTOR; 267 268 mPendingEvents[LinearAccel].version = sizeof(sensors_event_t); 269 mPendingEvents[LinearAccel].sensor = ID_LA; 270 mPendingEvents[LinearAccel].type = SENSOR_TYPE_LINEAR_ACCELERATION; 271 272 mPendingEvents[Gravity].version = sizeof(sensors_event_t); 273 mPendingEvents[Gravity].sensor = ID_GR; 274 mPendingEvents[Gravity].type = SENSOR_TYPE_GRAVITY; 275 276 mPendingEvents[Gyro].version = sizeof(sensors_event_t); 277 mPendingEvents[Gyro].sensor = ID_GY; 278 mPendingEvents[Gyro].type = SENSOR_TYPE_GYROSCOPE; 279 280 mPendingEvents[RawGyro].version = sizeof(sensors_event_t); 281 mPendingEvents[RawGyro].sensor = ID_RG; 282 mPendingEvents[RawGyro].type = SENSOR_TYPE_GYROSCOPE; 283 284 mPendingEvents[Accelerometer].version = sizeof(sensors_event_t); 285 mPendingEvents[Accelerometer].sensor = ID_A; 286 mPendingEvents[Accelerometer].type = SENSOR_TYPE_ACCELEROMETER; 287 288 /* Invensense compass calibration */ 289 mPendingEvents[MagneticField].version = sizeof(sensors_event_t); 290 mPendingEvents[MagneticField].sensor = ID_M; 291 mPendingEvents[MagneticField].type = SENSOR_TYPE_MAGNETIC_FIELD; 292 mPendingEvents[MagneticField].magnetic.status = 293 SENSOR_STATUS_ACCURACY_HIGH; 294 295 mPendingEvents[Orientation].version = sizeof(sensors_event_t); 296 mPendingEvents[Orientation].sensor = ID_O; 297 mPendingEvents[Orientation].type = SENSOR_TYPE_ORIENTATION; 298 mPendingEvents[Orientation].orientation.status 299 = SENSOR_STATUS_ACCURACY_HIGH; 300 301 mHandlers[RotationVector] = &MPLSensor::rvHandler; 302 mHandlers[LinearAccel] = &MPLSensor::laHandler; 303 mHandlers[Gravity] = &MPLSensor::gravHandler; 304 mHandlers[Gyro] = &MPLSensor::gyroHandler; 305 mHandlers[RawGyro] = &MPLSensor::rawGyroHandler; 306 mHandlers[Accelerometer] = &MPLSensor::accelHandler; 307 mHandlers[MagneticField] = &MPLSensor::compassHandler; 308 mHandlers[Orientation] = &MPLSensor::orienHandler; 309 310 for (int i = 0; i < numSensors; i++) { 311 mDelays[i] = 0; 312 } 313 314 (void)inv_get_version(&ver_str); 315 LOGV_IF(PROCESS_VERBOSE, "%s\n", ver_str); 316 317 /* setup MPL */ 318 inv_constructor_init(); 319 320 /* load calibration file from /data/inv_cal_data.bin */ 321 rv = inv_load_calibration(); 322 if(rv == INV_SUCCESS) 323 LOGV_IF(PROCESS_VERBOSE, "HAL:Calibration file successfully loaded"); 324 else 325 LOGE("HAL:Could not open or load MPL calibration file (%d)", rv); 326 327 /* Takes external Accel Calibration Load Method */ 328 if( m_pt2AccelCalLoadFunc != NULL) 329 { 330 long accel_offset[3]; 331 long tmp_offset[3]; 332 int result = m_pt2AccelCalLoadFunc(accel_offset); 333 if(result) 334 LOGW("HAL:Vendor accelerometer calibration file load failed %d\n", result); 335 else 336 { 337 LOGW("HAL:Vendor accelerometer calibration file successfully loaded"); 338 inv_get_accel_bias(tmp_offset, NULL); 339 LOGV_IF(PROCESS_VERBOSE, "HAL:Original accel offset, %ld, %ld, %ld\n", 340 tmp_offset[0], tmp_offset[1], tmp_offset[2]); 341 inv_set_accel_bias(accel_offset, mAccelAccuracy); 342 inv_get_accel_bias(tmp_offset, NULL); 343 LOGV_IF(PROCESS_VERBOSE, "HAL:Set accel offset, %ld, %ld, %ld\n", 344 tmp_offset[0], tmp_offset[1], tmp_offset[2]); 345 } 346 } 347 /* End of Accel Calibration Load Method */ 348 349 inv_set_device_properties(); 350 351 /* disable driver master enable the first sensor goes on */ 352 masterEnable(0); 353 enableGyro(0); 354 enableAccel(0); 355 enableCompass(0); 356 357 if (isLowPowerQuatEnabled()) { 358 enableLPQuaternion(0); 359 } 360 361 onPower(0); 362 363 if (isDmpDisplayOrientationOn()) { 364 enableDmpOrientation(!isDmpScreenAutoRotationEnabled()); 365 } 366 367 } 368 369 void MPLSensor::enable_iio_sysfs() 370 { 371 VFUNC_LOG; 372 373 char iio_trigger_name[MAX_CHIP_ID_LEN], iio_device_node[MAX_CHIP_ID_LEN]; 374 FILE *tempFp = NULL; 375 376 /* ignore failures */ 377 write_sysfs_int(mpu.in_timestamp_en, 1); 378 379 LOGV_IF(SYSFS_VERBOSE, 380 "HAL:sysfs:cat %s (%lld)", 381 mpu.trigger_name, getTimestamp()); 382 tempFp = fopen(mpu.trigger_name, "r"); 383 if (tempFp == NULL) { 384 LOGE("HAL:could not open trigger name"); 385 } else { 386 if (fscanf(tempFp, "%s", iio_trigger_name) < 0) { 387 LOGE("HAL:could not read trigger name"); 388 } 389 fclose(tempFp); 390 } 391 392 LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %s > %s (%lld)", 393 iio_trigger_name, mpu.current_trigger, getTimestamp()); 394 tempFp = fopen(mpu.current_trigger, "w"); 395 if (tempFp == NULL) { 396 LOGE("HAL:could not open current trigger"); 397 } else { 398 if (fprintf(tempFp, "%s", iio_trigger_name) < 0 || fclose(tempFp) < 0) { 399 LOGE("HAL:could not write current trigger %s err=%d", iio_trigger_name, errno); 400 } 401 } 402 403 write_sysfs_int(mpu.buffer_length, IIO_BUFFER_LENGTH); 404 405 if (inv_get_iio_device_node(iio_device_node) < 0) { 406 LOGE("HAL:could retrive the iio device node"); 407 } 408 iio_fd = open(iio_device_node, O_RDONLY); 409 if (iio_fd < 0) { 410 LOGE("HAL:could not open iio device node"); 411 } else { 412 LOGV_IF(PROCESS_VERBOSE, "HAL:iio iio_fd (%s) opened: %d", iio_device_node, iio_fd); 413 } 414 } 415 416 int MPLSensor::inv_constructor_init() 417 { 418 VFUNC_LOG; 419 420 inv_error_t result = inv_init_mpl(); 421 if (result) { 422 LOGE("HAL:inv_init_mpl() failed"); 423 return result; 424 } 425 result = inv_constructor_default_enable(); 426 result = inv_start_mpl(); 427 if (result) { 428 LOGE("HAL:inv_start_mpl() failed"); 429 LOG_RESULT_LOCATION(result); 430 return result; 431 } 432 433 return result; 434 } 435 436 int MPLSensor::inv_constructor_default_enable() 437 { 438 VFUNC_LOG; 439 440 inv_error_t result; 441 442 result = inv_enable_quaternion(); 443 if (result) { 444 LOGE("HAL:Cannot enable quaternion\n"); 445 return result; 446 } 447 448 result = inv_enable_in_use_auto_calibration(); 449 if (result) { 450 return result; 451 } 452 453 // result = inv_enable_motion_no_motion(); 454 result = inv_enable_fast_nomot(); 455 if (result) { 456 return result; 457 } 458 459 result = inv_enable_gyro_tc(); 460 if (result) { 461 return result; 462 } 463 464 result = inv_enable_hal_outputs(); 465 if (result) { 466 return result; 467 } 468 469 if (!mCompassSensor->providesCalibration()) { 470 /* Invensense compass calibration */ 471 LOGV_IF(PROCESS_VERBOSE, "HAL:Invensense vector compass cal enabled"); 472 result = inv_enable_vector_compass_cal(); 473 if (result) { 474 LOG_RESULT_LOCATION(result); 475 return result; 476 } else { 477 mFeatureActiveMask |= INV_COMPASS_CAL; 478 } 479 480 // specify MPL's trust weight, used by compass algorithms 481 inv_vector_compass_cal_sensitivity(3); 482 483 result = inv_enable_compass_bias_w_gyro(); 484 if (result) { 485 LOG_RESULT_LOCATION(result); 486 return result; 487 } 488 489 result = inv_enable_heading_from_gyro(); 490 if (result) { 491 LOG_RESULT_LOCATION(result); 492 return result; 493 } 494 495 result = inv_enable_magnetic_disturbance(); 496 if (result) { 497 LOG_RESULT_LOCATION(result); 498 return result; 499 } 500 } 501 502 result = inv_enable_9x_sensor_fusion(); 503 if (result) { 504 LOG_RESULT_LOCATION(result); 505 return result; 506 } else { 507 // 9x sensor fusion enables Compass fit 508 mFeatureActiveMask |= INV_COMPASS_FIT; 509 } 510 511 result = inv_enable_no_gyro_fusion(); 512 if (result) { 513 LOG_RESULT_LOCATION(result); 514 return result; 515 } 516 517 result = inv_enable_quat_accuracy_monitor(); 518 if (result) { 519 LOG_RESULT_LOCATION(result); 520 return result; 521 } 522 523 return result; 524 } 525 526 /* TODO: create function pointers to calculate scale */ 527 void MPLSensor::inv_set_device_properties() 528 { 529 VFUNC_LOG; 530 531 unsigned short orient; 532 533 inv_get_sensors_orientation(); 534 535 inv_set_gyro_sample_rate(DEFAULT_MPL_GYRO_RATE); 536 inv_set_compass_sample_rate(DEFAULT_MPL_COMPASS_RATE); 537 538 /* gyro setup */ 539 orient = inv_orientation_matrix_to_scalar(mGyroOrientation); 540 inv_set_gyro_orientation_and_scale(orient, 2000L << 15); 541 542 /* accel setup */ 543 orient = inv_orientation_matrix_to_scalar(mAccelOrientation); 544 /* use for third party accel input subsystem driver 545 inv_set_accel_orientation_and_scale(orient, 1LL << 22); 546 */ 547 inv_set_accel_orientation_and_scale(orient, mAccelScale << 15); 548 549 /* compass setup */ 550 signed char orientMtx[9]; 551 mCompassSensor->getOrientationMatrix(orientMtx); 552 orient = 553 inv_orientation_matrix_to_scalar(orientMtx); 554 long sensitivity; 555 sensitivity = mCompassSensor->getSensitivity(); 556 inv_set_compass_orientation_and_scale(orient, sensitivity); 557 } 558 559 void MPLSensor::loadDMP() 560 { 561 int res, fd; 562 FILE *fptr; 563 564 if (isMpu3050()) { 565 //DMP support only for MPU6xxx/9xxx currently 566 return; 567 } 568 569 /* load DMP firmware */ 570 LOGV_IF(SYSFS_VERBOSE, 571 "HAL:sysfs:cat %s (%lld)", mpu.firmware_loaded, getTimestamp()); 572 fd = open(mpu.firmware_loaded, O_RDONLY); 573 if(fd < 0) { 574 LOGE("HAL:could not open dmp state"); 575 return; 576 } 577 if(inv_read_dmp_state(fd)) { 578 LOGV_IF(PROCESS_VERBOSE, "HAL:DMP is already loaded"); 579 return; 580 } 581 582 LOGV_IF(EXTRA_VERBOSE, "HAL:load dmp: %s", mpu.dmp_firmware); 583 fptr = fopen(mpu.dmp_firmware, "w"); 584 if(!fptr) { 585 LOGE("HAL:could open %s for write. %s", mpu.dmp_firmware, strerror(errno)); 586 return; 587 } 588 res = inv_load_dmp(fptr); 589 if(res < 0) { 590 LOGE("HAL:load DMP failed"); 591 } else { 592 LOGV_IF(PROCESS_VERBOSE, "HAL:DMP loaded"); 593 } 594 fclose(fptr); 595 596 // onDMP(1); //Can't enable here. See note onDMP() 597 } 598 599 void MPLSensor::inv_get_sensors_orientation() 600 { 601 FILE *fptr; 602 603 // get gyro orientation 604 LOGV_IF(SYSFS_VERBOSE, 605 "HAL:sysfs:cat %s (%lld)", mpu.gyro_orient, getTimestamp()); 606 fptr = fopen(mpu.gyro_orient, "r"); 607 if (fptr != NULL) { 608 int om[9]; 609 fscanf(fptr, "%d,%d,%d,%d,%d,%d,%d,%d,%d", 610 &om[0], &om[1], &om[2], &om[3], &om[4], &om[5], 611 &om[6], &om[7], &om[8]); 612 fclose(fptr); 613 614 LOGV_IF(EXTRA_VERBOSE, 615 "HAL:gyro mounting matrix: " 616 "%+d %+d %+d %+d %+d %+d %+d %+d %+d", 617 om[0], om[1], om[2], om[3], om[4], om[5], om[6], om[7], om[8]); 618 619 mGyroOrientation[0] = om[0]; 620 mGyroOrientation[1] = om[1]; 621 mGyroOrientation[2] = om[2]; 622 mGyroOrientation[3] = om[3]; 623 mGyroOrientation[4] = om[4]; 624 mGyroOrientation[5] = om[5]; 625 mGyroOrientation[6] = om[6]; 626 mGyroOrientation[7] = om[7]; 627 mGyroOrientation[8] = om[8]; 628 } else { 629 LOGE("HAL:Couldn't read gyro mounting matrix"); 630 } 631 632 // get accel orientation 633 LOGV_IF(SYSFS_VERBOSE, 634 "HAL:sysfs:cat %s (%lld)", mpu.accel_orient, getTimestamp()); 635 fptr = fopen(mpu.accel_orient, "r"); 636 if (fptr != NULL) { 637 int om[9]; 638 fscanf(fptr, "%d,%d,%d,%d,%d,%d,%d,%d,%d", 639 &om[0], &om[1], &om[2], &om[3], &om[4], &om[5], 640 &om[6], &om[7], &om[8]); 641 fclose(fptr); 642 643 LOGV_IF(EXTRA_VERBOSE, 644 "HAL:accel mounting matrix: " 645 "%+d %+d %+d %+d %+d %+d %+d %+d %+d", 646 om[0], om[1], om[2], om[3], om[4], om[5], om[6], om[7], om[8]); 647 648 mAccelOrientation[0] = om[0]; 649 mAccelOrientation[1] = om[1]; 650 mAccelOrientation[2] = om[2]; 651 mAccelOrientation[3] = om[3]; 652 mAccelOrientation[4] = om[4]; 653 mAccelOrientation[5] = om[5]; 654 mAccelOrientation[6] = om[6]; 655 mAccelOrientation[7] = om[7]; 656 mAccelOrientation[8] = om[8]; 657 } else { 658 LOGE("HAL:Couldn't read accel mounting matrix"); 659 } 660 } 661 662 MPLSensor::~MPLSensor() 663 { 664 VFUNC_LOG; 665 666 mCompassSensor = NULL; 667 668 /* Close open fds */ 669 if (iio_fd > 0) 670 close(iio_fd); 671 if( accel_fd > 0 ) 672 close(accel_fd ); 673 if (gyro_temperature_fd > 0) 674 close(gyro_temperature_fd); 675 if (sysfs_names_ptr) 676 free(sysfs_names_ptr); 677 678 if (isDmpDisplayOrientationOn()) { 679 closeDmpOrientFd(); 680 } 681 682 /* Turn off Gyro master enable */ 683 /* A workaround until driver handles it */ 684 /* TODO: Turn off and close all sensors */ 685 if(write_sysfs_int(mpu.chip_enable, 0) < 0) { 686 LOGE("HAL:could not disable gyro master enable"); 687 } 688 689 #ifdef INV_PLAYBACK_DBG 690 inv_turn_off_data_logging(); 691 fclose(logfile); 692 #endif 693 } 694 695 #define GY_ENABLED (((1 << ID_GY) | (1 << ID_RG)) & enabled_sensors) 696 #define A_ENABLED ((1 << ID_A) & enabled_sensors) 697 #define M_ENABLED ((1 << ID_M) & enabled_sensors) 698 #define O_ENABLED ((1 << ID_O) & enabled_sensors) 699 #define LA_ENABLED ((1 << ID_LA) & enabled_sensors) 700 #define GR_ENABLED ((1 << ID_GR) & enabled_sensors) 701 #define RV_ENABLED ((1 << ID_RV) & enabled_sensors) 702 703 /* TODO: this step is optional, remove? */ 704 int MPLSensor::setGyroInitialState() 705 { 706 VFUNC_LOG; 707 708 int res = 0; 709 710 LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)", 711 HW_GYRO_RATE_HZ, mpu.gyro_fifo_rate, getTimestamp()); 712 int fd = open(mpu.gyro_fifo_rate, O_RDWR); 713 res = errno; 714 if(fd < 0) { 715 LOGE("HAL:open of %s failed with '%s' (%d)", 716 mpu.gyro_fifo_rate, strerror(res), res); 717 return res; 718 } 719 res = write_attribute_sensor(fd, HW_GYRO_RATE_HZ); 720 if(res < 0) { 721 LOGE("HAL:write_attribute_sensor : error writing %s with %d", 722 mpu.gyro_fifo_rate, HW_GYRO_RATE_HZ); 723 return res; 724 } 725 726 // Setting LPF is deprecated 727 728 return 0; 729 } 730 731 /* this applies to BMA250 Input Subsystem Driver only */ 732 int MPLSensor::setAccelInitialState() 733 { 734 VFUNC_LOG; 735 736 struct input_absinfo absinfo_x; 737 struct input_absinfo absinfo_y; 738 struct input_absinfo absinfo_z; 739 float value; 740 if (!ioctl(accel_fd, EVIOCGABS(EVENT_TYPE_ACCEL_X), &absinfo_x) && 741 !ioctl(accel_fd, EVIOCGABS(EVENT_TYPE_ACCEL_Y), &absinfo_y) && 742 !ioctl(accel_fd, EVIOCGABS(EVENT_TYPE_ACCEL_Z), &absinfo_z)) { 743 value = absinfo_x.value; 744 mPendingEvents[Accelerometer].data[0] = value * CONVERT_A_X; 745 value = absinfo_y.value; 746 mPendingEvents[Accelerometer].data[1] = value * CONVERT_A_Y; 747 value = absinfo_z.value; 748 mPendingEvents[Accelerometer].data[2] = value * CONVERT_A_Z; 749 //mHasPendingEvent = true; 750 } 751 return 0; 752 } 753 754 int MPLSensor::onPower(int en) 755 { 756 VFUNC_LOG; 757 758 int res; 759 760 int count, curr_power_state; 761 762 LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)", 763 en, mpu.power_state, getTimestamp()); 764 res = read_sysfs_int(mpu.power_state, &curr_power_state); 765 if (res < 0) { 766 LOGE("HAL:Error reading power state"); 767 // will set power_state anyway 768 curr_power_state = -1; 769 } 770 if (en != curr_power_state) { 771 if((res = write_sysfs_int(mpu.power_state, en)) < 0) { 772 LOGE("HAL:Couldn't write power state"); 773 } 774 } else { 775 LOGV_IF(EXTRA_VERBOSE, 776 "HAL:Power state already enable/disable curr=%d new=%d", 777 curr_power_state, en); 778 } 779 return res; 780 } 781 782 int MPLSensor::onDMP(int en) 783 { 784 VFUNC_LOG; 785 786 int res = -1; 787 int status; 788 789 //Sequence to enable DMP 790 //1. Turn On power if not already on 791 //2. Load DMP image if not already loaded 792 //3. Either Gyro or Accel must be enabled/configured before next step 793 //4. Enable DMP 794 795 LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:cat %s (%lld)", 796 mpu.firmware_loaded, getTimestamp()); 797 res = read_sysfs_int(mpu.firmware_loaded, &status); 798 if (res < 0){ 799 LOGE("HAL:ERR can't get firmware_loaded status"); 800 return res; 801 } 802 LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs: %s status=%d", mpu.firmware_loaded, status); 803 804 if (status) { 805 //Write only if curr DMP state <> request 806 LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:cat %s (%lld)", 807 mpu.dmp_on, getTimestamp()); 808 if (read_sysfs_int(mpu.dmp_on, &status) < 0) { 809 LOGE("HAL:ERR can't read DMP state"); 810 } else if (status != en) { 811 res = write_sysfs_int(mpu.dmp_on, en); 812 //Enable DMP interrupt 813 if (write_sysfs_int(mpu.dmp_int_on, en) < 0) { 814 LOGE("HAL:ERR can't en/dis DMP interrupt"); 815 } 816 } else { 817 res = 0; //DMP already set as requested 818 } 819 } else { 820 LOGE("HAL:ERR No DMP image"); 821 } 822 return res; 823 } 824 825 int MPLSensor::checkLPQuaternion(void) 826 { 827 VFUNC_LOG; 828 829 return ((mFeatureActiveMask & INV_DMP_QUATERNION)? 1:0); 830 } 831 832 int MPLSensor::enableLPQuaternion(int en) 833 { 834 VFUNC_LOG; 835 836 if (!en) { 837 enableQuaternionData(0); 838 onDMP(0); 839 mFeatureActiveMask &= ~INV_DMP_QUATERNION; 840 LOGV_IF(PROCESS_VERBOSE, "HAL:LP Quat disabled"); 841 } else { 842 if (enableQuaternionData(1) < 0 || onDMP(1) < 0) { 843 LOGE("HAL:ERR can't enable LP Quaternion"); 844 } else { 845 mFeatureActiveMask |= INV_DMP_QUATERNION; 846 LOGV_IF(PROCESS_VERBOSE, "HAL:LP Quat enabled"); 847 } 848 } 849 return 0; 850 } 851 852 int MPLSensor::enableQuaternionData(int en) 853 { 854 int res = 0; 855 VFUNC_LOG; 856 857 // Enable DMP quaternion 858 res = write_sysfs_int(mpu.quaternion_on, en); 859 860 if (!en) { 861 LOGV_IF(PROCESS_VERBOSE, "HAL:Disabling quat scan elems"); 862 } else { 863 864 LOGV_IF(PROCESS_VERBOSE, "HAL:Enabling quat scan elems"); 865 } 866 write_sysfs_int(mpu.in_quat_r_en, en); 867 write_sysfs_int(mpu.in_quat_x_en, en); 868 write_sysfs_int(mpu.in_quat_y_en, en); 869 write_sysfs_int(mpu.in_quat_z_en, en); 870 871 LOGV_IF(EXTRA_VERBOSE, "HAL:DMP quaternion data was turned off"); 872 873 if (!en) { 874 inv_quaternion_sensor_was_turned_off(); 875 } 876 877 return res; 878 } 879 880 int MPLSensor::enableTap(int /*en*/) 881 { 882 VFUNC_LOG; 883 884 return 0; 885 } 886 887 int MPLSensor::enableFlick(int /*en*/) 888 { 889 VFUNC_LOG; 890 891 return 0; 892 } 893 894 int MPLSensor::enablePedometer(int /*en*/) 895 { 896 VFUNC_LOG; 897 898 return 0; 899 } 900 901 int MPLSensor::masterEnable(int en) 902 { 903 VFUNC_LOG; 904 return write_sysfs_int(mpu.chip_enable, en); 905 } 906 907 int MPLSensor::enableGyro(int en) 908 { 909 VFUNC_LOG; 910 911 /* TODO: FIX error handling. Handle or ignore it appropriately for hw. */ 912 int res; 913 914 /* need to also turn on/off the master enable */ 915 res = write_sysfs_int(mpu.gyro_enable, en); 916 917 if (!en) { 918 LOGV_IF(EXTRA_VERBOSE, "HAL:MPL:inv_gyro_was_turned_off"); 919 inv_gyro_was_turned_off(); 920 } else { 921 write_sysfs_int(mpu.gyro_x_fifo_enable, en); 922 write_sysfs_int(mpu.gyro_y_fifo_enable, en); 923 res = write_sysfs_int(mpu.gyro_z_fifo_enable, en); 924 } 925 926 return res; 927 } 928 929 int MPLSensor::enableAccel(int en) 930 { 931 VFUNC_LOG; 932 933 /* TODO: FIX error handling. Handle or ignore it appropriately for hw. */ 934 int res; 935 936 /* need to also turn on/off the master enable */ 937 res = write_sysfs_int(mpu.accel_enable, en); 938 939 if (!en) { 940 LOGV_IF(EXTRA_VERBOSE, "HAL:MPL:inv_accel_was_turned_off"); 941 inv_accel_was_turned_off(); 942 } else { 943 write_sysfs_int(mpu.accel_x_fifo_enable, en); 944 write_sysfs_int(mpu.accel_y_fifo_enable, en); 945 res = write_sysfs_int(mpu.accel_z_fifo_enable, en); 946 } 947 948 return res; 949 } 950 951 int MPLSensor::enableCompass(int en) 952 { 953 VFUNC_LOG; 954 955 int res = mCompassSensor->enable(ID_M, en); 956 if (!en) { 957 LOGV_IF(EXTRA_VERBOSE, "HAL:MPL:inv_compass_was_turned_off"); 958 inv_compass_was_turned_off(); 959 } 960 return res; 961 } 962 963 void MPLSensor::computeLocalSensorMask(int enabled_sensors) 964 { 965 VFUNC_LOG; 966 967 do { 968 if (LA_ENABLED || GR_ENABLED || RV_ENABLED || O_ENABLED) { 969 LOGV_IF(ENG_VERBOSE, "FUSION ENABLED"); 970 mLocalSensorMask = ALL_MPL_SENSORS_NP; 971 break; 972 } 973 974 if(!A_ENABLED && !M_ENABLED && !GY_ENABLED) { 975 /* Invensense compass cal */ 976 LOGV_IF(ENG_VERBOSE, "ALL DISABLED"); 977 mLocalSensorMask = 0; 978 break; 979 } 980 981 if (GY_ENABLED) { 982 LOGV_IF(ENG_VERBOSE, "G ENABLED"); 983 mLocalSensorMask |= INV_THREE_AXIS_GYRO; 984 } else { 985 LOGV_IF(ENG_VERBOSE, "G DISABLED"); 986 mLocalSensorMask &= ~INV_THREE_AXIS_GYRO; 987 } 988 989 if (A_ENABLED) { 990 LOGV_IF(ENG_VERBOSE, "A ENABLED"); 991 mLocalSensorMask |= INV_THREE_AXIS_ACCEL; 992 } else { 993 LOGV_IF(ENG_VERBOSE, "A DISABLED"); 994 mLocalSensorMask &= ~INV_THREE_AXIS_ACCEL; 995 } 996 997 /* Invensense compass calibration */ 998 if (M_ENABLED) { 999 LOGV_IF(ENG_VERBOSE, "M ENABLED"); 1000 mLocalSensorMask |= INV_THREE_AXIS_COMPASS; 1001 } else { 1002 LOGV_IF(ENG_VERBOSE, "M DISABLED"); 1003 mLocalSensorMask &= ~INV_THREE_AXIS_COMPASS; 1004 } 1005 } while (0); 1006 } 1007 1008 int MPLSensor::enableOneSensor(int en, const char *name, int (MPLSensor::*enabler)(int)) { 1009 LOGV_IF(PROCESS_VERBOSE, "HAL:enableSensors - %s %s", en ? "enabled" : "disable", name); 1010 return (this->*enabler)(en); 1011 } 1012 1013 int MPLSensor::enableSensors(unsigned long sensors, int /*en*/, uint32_t changed) { 1014 VFUNC_LOG; 1015 1016 inv_error_t res = -1; 1017 bool store_cal = false; 1018 bool ext_compass_changed = false; 1019 1020 // Sequence to enable or disable a sensor 1021 // 1. enable Power state 1022 // 2. reset master enable (=0) 1023 // 3. enable or disable a sensor 1024 // 4. set master enable (=1) 1025 1026 pthread_mutex_lock(&GlobalHalMutex); 1027 1028 uint32_t all_changeables = (1 << Gyro) | (1 << RawGyro) | (1 << Accelerometer) 1029 | (1 << MagneticField); 1030 uint32_t all_integrated_changeables = all_changeables; 1031 1032 if (!mCompassSensor->isIntegrated()) { 1033 ext_compass_changed = changed & (1 << MagneticField); 1034 all_integrated_changeables = all_changeables & ~(1 << MagneticField); 1035 } 1036 1037 if (isLowPowerQuatEnabled() || (changed & all_integrated_changeables)) { 1038 /* ensure power state is on */ 1039 onPower(1); 1040 1041 /* reset master enable */ 1042 res = masterEnable(0); 1043 if(res < 0) { 1044 goto unlock_res; 1045 } 1046 } 1047 1048 LOGV_IF(PROCESS_VERBOSE, "HAL:enableSensors - sensors: 0x%0x", (unsigned int)sensors); 1049 1050 if (changed & ((1 << Gyro) | (1 << RawGyro))) { 1051 res = enableOneSensor(sensors & INV_THREE_AXIS_GYRO, "gyro", &MPLSensor::enableGyro); 1052 if(res < 0) { 1053 goto unlock_res; 1054 } 1055 } 1056 1057 if (changed & (1 << Accelerometer)) { 1058 res = enableOneSensor(sensors & INV_THREE_AXIS_ACCEL, "accel", &MPLSensor::enableAccel); 1059 if(res < 0) { 1060 goto unlock_res; 1061 } 1062 } 1063 1064 if (changed & (1 << MagneticField)) { 1065 /* Invensense compass calibration */ 1066 res = enableOneSensor(sensors & INV_THREE_AXIS_COMPASS, "compass", &MPLSensor::enableCompass); 1067 if(res < 0) { 1068 goto unlock_res; 1069 } 1070 } 1071 1072 if ( isLowPowerQuatEnabled() ) { 1073 // Enable LP Quat 1074 if ((mEnabled & ((1 << Orientation) | (1 << RotationVector) | 1075 (1 << LinearAccel) | (1 << Gravity)))) { 1076 if (!(changed & all_integrated_changeables)) { 1077 /* ensure power state is on */ 1078 onPower(1); 1079 /* reset master enable */ 1080 res = masterEnable(0); 1081 if(res < 0) { 1082 goto unlock_res; 1083 } 1084 } 1085 if (!checkLPQuaternion()) { 1086 enableLPQuaternion(1); 1087 } else { 1088 LOGV_IF(PROCESS_VERBOSE, "HAL:LP Quat already enabled"); 1089 } 1090 } else if (checkLPQuaternion()) { 1091 enableLPQuaternion(0); 1092 } 1093 } 1094 1095 if (changed & all_integrated_changeables) { 1096 if (sensors & 1097 (INV_THREE_AXIS_GYRO 1098 | INV_THREE_AXIS_ACCEL 1099 | (INV_THREE_AXIS_COMPASS * mCompassSensor->isIntegrated()))) { 1100 if ( isLowPowerQuatEnabled() || 1101 (isDmpDisplayOrientationOn() && mDmpOrientationEnabled) ) { 1102 // disable DMP event interrupt only (w/ data interrupt) 1103 if (write_sysfs_int(mpu.dmp_event_int_on, 0) < 0) { 1104 res = -1; 1105 LOGE("HAL:ERR can't disable DMP event interrupt"); 1106 goto unlock_res; 1107 } 1108 } 1109 1110 if (isDmpDisplayOrientationOn() && mDmpOrientationEnabled) { 1111 // enable DMP 1112 onDMP(1); 1113 1114 res = enableAccel(1); 1115 if(res < 0) { 1116 goto unlock_res; 1117 } 1118 1119 if ((sensors & INV_THREE_AXIS_ACCEL) == 0) { 1120 res = turnOffAccelFifo(); 1121 } 1122 if(res < 0) { 1123 goto unlock_res; 1124 } 1125 } 1126 1127 res = masterEnable(1); 1128 if(res < 0) { 1129 goto unlock_res; 1130 } 1131 } else { // all sensors idle -> reduce power 1132 if (isDmpDisplayOrientationOn() && mDmpOrientationEnabled) { 1133 // enable DMP 1134 onDMP(1); 1135 // enable DMP event interrupt only (no data interrupt) 1136 if (write_sysfs_int(mpu.dmp_event_int_on, 1) < 0) { 1137 res = -1; 1138 LOGE("HAL:ERR can't enable DMP event interrupt"); 1139 } 1140 res = enableAccel(1); 1141 if(res < 0) { 1142 goto unlock_res; 1143 } 1144 if ((sensors & INV_THREE_AXIS_ACCEL) == 0) { 1145 res = turnOffAccelFifo(); 1146 } 1147 if(res < 0) { 1148 goto unlock_res; 1149 } 1150 res = masterEnable(1); 1151 if(res < 0) { 1152 goto unlock_res; 1153 } 1154 } 1155 else { 1156 res = onPower(0); 1157 if(res < 0) { 1158 goto unlock_res; 1159 } 1160 } 1161 store_cal = true; 1162 } 1163 } else if (ext_compass_changed && 1164 !(sensors & (INV_THREE_AXIS_GYRO | INV_THREE_AXIS_ACCEL 1165 | (INV_THREE_AXIS_COMPASS * (!mCompassSensor->isIntegrated()))))) { 1166 store_cal = true; 1167 } 1168 1169 if (store_cal || ((changed & all_changeables) != all_changeables)) { 1170 storeCalibration(); 1171 } 1172 1173 unlock_res: 1174 pthread_mutex_unlock(&GlobalHalMutex); 1175 return res; 1176 } 1177 1178 /* Store calibration file */ 1179 void MPLSensor::storeCalibration() 1180 { 1181 if(mHaveGoodMpuCal || mAccelAccuracy >= 2 || mCompassAccuracy >= 3) { 1182 int res = inv_store_calibration(); 1183 if (res) { 1184 LOGE("HAL:Cannot store calibration on file"); 1185 } else { 1186 LOGV_IF(PROCESS_VERBOSE, "HAL:Cal file updated"); 1187 } 1188 } 1189 } 1190 1191 void MPLSensor::cbProcData() 1192 { 1193 mNewData = 1; 1194 mSampleCount++; 1195 LOGV_IF(EXTRA_VERBOSE, "HAL:new data"); 1196 } 1197 1198 /* these handlers transform mpl data into one of the Android sensor types */ 1199 int MPLSensor::gyroHandler(sensors_event_t* s) 1200 { 1201 VHANDLER_LOG; 1202 int8_t status; 1203 int update; 1204 update = inv_get_sensor_type_gyroscope(s->gyro.v, &status, &s->timestamp); 1205 LOGV_IF(HANDLER_DATA, "HAL:gyro data : %+f %+f %+f -- %lld - %d", 1206 s->gyro.v[0], s->gyro.v[1], s->gyro.v[2], s->timestamp, update); 1207 return update; 1208 } 1209 1210 int MPLSensor::rawGyroHandler(sensors_event_t* s) 1211 { 1212 VHANDLER_LOG; 1213 int8_t status; 1214 int update; 1215 update = inv_get_sensor_type_gyroscope_raw(s->gyro.v, &status, &s->timestamp); 1216 LOGV_IF(HANDLER_DATA, "HAL:raw gyro data : %+f %+f %+f -- %lld - %d", 1217 s->gyro.v[0], s->gyro.v[1], s->gyro.v[2], s->timestamp, update); 1218 return update; 1219 } 1220 1221 int MPLSensor::accelHandler(sensors_event_t* s) 1222 { 1223 VHANDLER_LOG; 1224 int8_t status; 1225 int update; 1226 update = inv_get_sensor_type_accelerometer( 1227 s->acceleration.v, &status, &s->timestamp); 1228 LOGV_IF(HANDLER_DATA, "HAL:accel data : %+f %+f %+f -- %lld - %d", 1229 s->acceleration.v[0], s->acceleration.v[1], s->acceleration.v[2], 1230 s->timestamp, update); 1231 mAccelAccuracy = status; 1232 return update; 1233 } 1234 1235 int MPLSensor::compassHandler(sensors_event_t* s) 1236 { 1237 VHANDLER_LOG; 1238 int update; 1239 update = inv_get_sensor_type_magnetic_field( 1240 s->magnetic.v, &s->magnetic.status, &s->timestamp); 1241 LOGV_IF(HANDLER_DATA, "HAL:compass data: %+f %+f %+f -- %lld - %d", 1242 s->magnetic.v[0], s->magnetic.v[1], s->magnetic.v[2], s->timestamp, update); 1243 mCompassAccuracy = s->magnetic.status; 1244 return update; 1245 } 1246 1247 int MPLSensor::rvHandler(sensors_event_t* s) 1248 { 1249 // rotation vector does not have an accuracy or status 1250 VHANDLER_LOG; 1251 int8_t status; 1252 int update; 1253 update = inv_get_sensor_type_rotation_vector(s->data, &status, &s->timestamp); 1254 LOGV_IF(HANDLER_DATA, "HAL:rv data: %+f %+f %+f %+f - %+lld - %d", 1255 s->data[0], s->data[1], s->data[2], s->data[3], s->timestamp, update); 1256 return update; 1257 } 1258 1259 int MPLSensor::laHandler(sensors_event_t* s) 1260 { 1261 VHANDLER_LOG; 1262 int8_t status; 1263 int update; 1264 update = inv_get_sensor_type_linear_acceleration( 1265 s->gyro.v, &status, &s->timestamp); 1266 LOGV_IF(HANDLER_DATA, "HAL:la data: %+f %+f %+f - %lld - %d", 1267 s->gyro.v[0], s->gyro.v[1], s->gyro.v[2], s->timestamp, update); 1268 return update; 1269 } 1270 1271 int MPLSensor::gravHandler(sensors_event_t* s) 1272 { 1273 VHANDLER_LOG; 1274 int8_t status; 1275 int update; 1276 update = inv_get_sensor_type_gravity(s->gyro.v, &status, &s->timestamp); 1277 LOGV_IF(HANDLER_DATA, "HAL:gr data: %+f %+f %+f - %lld - %d", 1278 s->gyro.v[0], s->gyro.v[1], s->gyro.v[2], s->timestamp, update); 1279 return update; 1280 } 1281 1282 int MPLSensor::orienHandler(sensors_event_t* s) 1283 { 1284 VHANDLER_LOG; 1285 int update; 1286 update = inv_get_sensor_type_orientation( 1287 s->orientation.v, &s->orientation.status, &s->timestamp); 1288 LOGV_IF(HANDLER_DATA, "HAL:or data: %f %f %f - %lld - %d", 1289 s->orientation.v[0], s->orientation.v[1], s->orientation.v[2], s->timestamp, update); 1290 return update; 1291 } 1292 1293 int MPLSensor::enable(int32_t handle, int en) 1294 { 1295 VFUNC_LOG; 1296 1297 android::String8 sname; 1298 int what = -1, err = 0; 1299 1300 switch (handle) { 1301 case ID_SO: 1302 sname = "Screen Orientation"; 1303 LOGV_IF(PROCESS_VERBOSE, "HAL:enable - sensor %s (handle %d) %s -> %s", sname.string(), handle, 1304 (mDmpOrientationEnabled? "en": "dis"), 1305 (en? "en" : "dis")); 1306 enableDmpOrientation(en && isDmpDisplayOrientationOn()); 1307 /* TODO: stop manually testing/using 0 and 1 instead of 1308 * false and true, but just use 0 and non-0. 1309 * This allows passing 0 and non-0 ints around instead of 1310 * having to convert to 1 and test against 1. 1311 */ 1312 mDmpOrientationEnabled = en; 1313 return 0; 1314 case ID_A: 1315 what = Accelerometer; 1316 sname = "Accelerometer"; 1317 break; 1318 case ID_M: 1319 what = MagneticField; 1320 sname = "MagneticField"; 1321 break; 1322 case ID_O: 1323 what = Orientation; 1324 sname = "Orientation"; 1325 break; 1326 case ID_GY: 1327 what = Gyro; 1328 sname = "Gyro"; 1329 break; 1330 case ID_RG: 1331 what = RawGyro; 1332 sname = "RawGyro"; 1333 break; 1334 case ID_GR: 1335 what = Gravity; 1336 sname = "Gravity"; 1337 break; 1338 case ID_RV: 1339 what = RotationVector; 1340 sname = "RotationVector"; 1341 break; 1342 case ID_LA: 1343 what = LinearAccel; 1344 sname = "LinearAccel"; 1345 break; 1346 default: //this takes care of all the gestures 1347 what = handle; 1348 sname = "Others"; 1349 break; 1350 } 1351 1352 if (uint32_t(what) >= numSensors) 1353 return -EINVAL; 1354 1355 int newState = en ? 1 : 0; 1356 unsigned long sen_mask; 1357 1358 LOGV_IF(PROCESS_VERBOSE, "HAL:enable - sensor %s (handle %d) %s -> %s", sname.string(), handle, 1359 ((mEnabled & (1 << what)) ? "en" : "dis"), 1360 ((uint32_t(newState) << what) ? "en" : "dis")); 1361 LOGV_IF(PROCESS_VERBOSE, 1362 "HAL:%s sensor state change what=%d", sname.string(), what); 1363 1364 // pthread_mutex_lock(&mMplMutex); 1365 // pthread_mutex_lock(&mHALMutex); 1366 1367 if ((uint32_t(newState) << what) != (mEnabled & (1 << what))) { 1368 uint32_t sensor_type; 1369 short flags = newState; 1370 uint32_t lastEnabled = mEnabled, changed = 0; 1371 1372 mEnabled &= ~(1 << what); 1373 mEnabled |= (uint32_t(flags) << what); 1374 1375 LOGV_IF(PROCESS_VERBOSE, "HAL:handle = %d", handle); 1376 LOGV_IF(PROCESS_VERBOSE, "HAL:flags = %d", flags); 1377 computeLocalSensorMask(mEnabled); 1378 LOGV_IF(PROCESS_VERBOSE, "HAL:enable : mEnabled = %d", mEnabled); 1379 sen_mask = mLocalSensorMask & mMasterSensorMask; 1380 mSensorMask = sen_mask; 1381 LOGV_IF(PROCESS_VERBOSE, "HAL:sen_mask= 0x%0lx", sen_mask); 1382 1383 switch (what) { 1384 case Gyro: 1385 case RawGyro: 1386 case Accelerometer: 1387 case MagneticField: 1388 if (!(mEnabled & ((1 << Orientation) | (1 << RotationVector) | 1389 (1 << LinearAccel) | (1 << Gravity))) && 1390 ((lastEnabled & (1 << what)) != (mEnabled & (1 << what)))) { 1391 changed |= (1 << what); 1392 } 1393 break; 1394 1395 case Orientation: 1396 case RotationVector: 1397 case LinearAccel: 1398 case Gravity: 1399 if ((en && !(lastEnabled & ((1 << Orientation) | (1 << RotationVector) | 1400 (1 << LinearAccel) | (1 << Gravity)))) || 1401 (!en && !(mEnabled & ((1 << Orientation) | (1 << RotationVector) | 1402 (1 << LinearAccel) | (1 << Gravity))))) { 1403 for (int i = Gyro; i <= MagneticField; i++) { 1404 if (!(mEnabled & (1 << i))) { 1405 changed |= (1 << i); 1406 } 1407 } 1408 } 1409 break; 1410 } 1411 LOGV_IF(PROCESS_VERBOSE, "HAL:changed = %d", changed); 1412 enableSensors(sen_mask, flags, changed); 1413 } 1414 1415 // pthread_mutex_unlock(&mMplMutex); 1416 // pthread_mutex_unlock(&mHALMutex); 1417 1418 #ifdef INV_PLAYBACK_DBG 1419 /* apparently the logging needs to be go through this sequence 1420 to properly flush the log file */ 1421 inv_turn_off_data_logging(); 1422 fclose(logfile); 1423 logfile = fopen("/data/playback.bin", "ab"); 1424 if (logfile) 1425 inv_turn_on_data_logging(logfile); 1426 #endif 1427 1428 return err; 1429 } 1430 1431 int MPLSensor::setDelay(int32_t handle, int64_t ns) 1432 { 1433 VFUNC_LOG; 1434 1435 android::String8 sname; 1436 int what = -1; 1437 1438 switch (handle) { 1439 case ID_SO: 1440 return update_delay(); 1441 case ID_A: 1442 what = Accelerometer; 1443 sname = "Accelerometer"; 1444 break; 1445 case ID_M: 1446 what = MagneticField; 1447 sname = "MagneticField"; 1448 break; 1449 case ID_O: 1450 what = Orientation; 1451 sname = "Orientation"; 1452 break; 1453 case ID_GY: 1454 what = Gyro; 1455 sname = "Gyro"; 1456 break; 1457 case ID_RG: 1458 what = RawGyro; 1459 sname = "RawGyro"; 1460 break; 1461 case ID_GR: 1462 what = Gravity; 1463 sname = "Gravity"; 1464 break; 1465 case ID_RV: 1466 what = RotationVector; 1467 sname = "RotationVector"; 1468 break; 1469 case ID_LA: 1470 what = LinearAccel; 1471 sname = "LinearAccel"; 1472 break; 1473 default: // this takes care of all the gestures 1474 what = handle; 1475 sname = "Others"; 1476 break; 1477 } 1478 1479 #if 0 1480 // skip the 1st call for enalbing sensors called by ICS/JB sensor service 1481 static int counter_delay = 0; 1482 if (!(mEnabled & (1 << what))) { 1483 counter_delay = 0; 1484 } else { 1485 if (++counter_delay == 1) { 1486 return 0; 1487 } 1488 else { 1489 counter_delay = 0; 1490 } 1491 } 1492 #endif 1493 1494 if (uint32_t(what) >= numSensors) 1495 return -EINVAL; 1496 1497 if (ns < 0) 1498 return -EINVAL; 1499 1500 LOGV_IF(PROCESS_VERBOSE, "setDelay : %llu ns, (%.2f Hz)", ns, 1000000000.f / ns); 1501 1502 // limit all rates to reasonable ones */ 1503 if (ns < 5000000LL) { 1504 ns = 5000000LL; 1505 } 1506 1507 /* store request rate to mDelays array for each sensor */ 1508 mDelays[what] = ns; 1509 1510 switch (what) { 1511 case Gyro: 1512 case RawGyro: 1513 case Accelerometer: 1514 for (int i = Gyro; i <= Accelerometer + mCompassSensor->isIntegrated(); 1515 i++) { 1516 if (i != what && (mEnabled & (1 << i)) && ns > mDelays[i]) { 1517 LOGV_IF(PROCESS_VERBOSE, "HAL:ignore delay set due to sensor %d", i); 1518 return 0; 1519 } 1520 } 1521 break; 1522 1523 case MagneticField: 1524 if (mCompassSensor->isIntegrated() && 1525 (((mEnabled & (1 << Gyro)) && ns > mDelays[Gyro]) || 1526 ((mEnabled & (1 << RawGyro)) && ns > mDelays[RawGyro]) || 1527 ((mEnabled & (1 << Accelerometer)) && ns > mDelays[Accelerometer]))) { 1528 LOGV_IF(PROCESS_VERBOSE, "HAL:ignore delay set due to gyro/accel"); 1529 return 0; 1530 } 1531 break; 1532 1533 case Orientation: 1534 case RotationVector: 1535 case LinearAccel: 1536 case Gravity: 1537 if (isLowPowerQuatEnabled()) { 1538 LOGV_IF(PROCESS_VERBOSE, "HAL:need to update delay due to LPQ"); 1539 break; 1540 } 1541 1542 for (int i = 0; i < numSensors; i++) { 1543 if (i != what && (mEnabled & (1 << i)) && ns > mDelays[i]) { 1544 LOGV_IF(PROCESS_VERBOSE, "HAL:ignore delay set due to sensor %d", i); 1545 return 0; 1546 } 1547 } 1548 break; 1549 } 1550 1551 // pthread_mutex_lock(&mHALMutex); 1552 int res = update_delay(); 1553 // pthread_mutex_unlock(&mHALMutex); 1554 return res; 1555 } 1556 1557 int MPLSensor::update_delay() { 1558 VHANDLER_LOG; 1559 1560 int res = 0; 1561 int64_t got; 1562 1563 pthread_mutex_lock(&GlobalHalMutex); 1564 if (mEnabled) { 1565 int64_t wanted = 1000000000; 1566 int64_t wanted_3rd_party_sensor = 1000000000; 1567 1568 // Sequence to change sensor's FIFO rate 1569 // 1. enable Power state 1570 // 2. reset master enable 1571 // 3. Update delay 1572 // 4. set master enable 1573 1574 // ensure power on 1575 onPower(1); 1576 1577 // reset master enable 1578 masterEnable(0); 1579 1580 /* search the minimum delay requested across all enabled sensors */ 1581 for (int i = 0; i < numSensors; i++) { 1582 if (mEnabled & (1 << i)) { 1583 int64_t ns = mDelays[i]; 1584 wanted = wanted < ns ? wanted : ns; 1585 } 1586 } 1587 1588 // same delay for 3rd party Accel or Compass 1589 wanted_3rd_party_sensor = wanted; 1590 1591 /* mpl rate in us in future maybe different for 1592 gyro vs compass vs accel */ 1593 int rateInus = (int)wanted / 1000LL; 1594 int mplGyroRate = rateInus; 1595 int mplAccelRate = rateInus; 1596 int mplCompassRate = rateInus; 1597 1598 LOGV_IF(PROCESS_VERBOSE, "HAL:wanted rate for all sensors : " 1599 "%llu ns, mpl rate: %d us, (%.2f Hz)", 1600 wanted, rateInus, 1000000000.f / wanted); 1601 1602 /* set rate in MPL */ 1603 /* compass can only do 100Hz max */ 1604 inv_set_gyro_sample_rate(mplGyroRate); 1605 inv_set_accel_sample_rate(mplAccelRate); 1606 inv_set_compass_sample_rate(mplCompassRate); 1607 1608 /* TODO: Test 200Hz */ 1609 // inv_set_gyro_sample_rate(5000); 1610 LOGV_IF(PROCESS_VERBOSE, "HAL:MPL gyro sample rate: %d", mplGyroRate); 1611 LOGV_IF(PROCESS_VERBOSE, "HAL:MPL accel sample rate: %d", mplAccelRate); 1612 LOGV_IF(PROCESS_VERBOSE, "HAL:MPL compass sample rate: %d", mplCompassRate); 1613 1614 int enabled_sensors = mEnabled; 1615 int tempFd = -1; 1616 if (LA_ENABLED || GR_ENABLED || RV_ENABLED || O_ENABLED) { 1617 if (isLowPowerQuatEnabled() || 1618 (isDmpDisplayOrientationOn() && mDmpOrientationEnabled)) { 1619 bool setDMPrate= 0; 1620 // Set LP Quaternion sample rate if enabled 1621 if (checkLPQuaternion()) { 1622 if (wanted < RATE_200HZ) { 1623 enableLPQuaternion(0); 1624 } else { 1625 inv_set_quat_sample_rate(rateInus); 1626 setDMPrate= 1; 1627 } 1628 } 1629 1630 if (checkDMPOrientation() || setDMPrate==1) { 1631 getDmpRate(&wanted); 1632 } 1633 } 1634 1635 int64_t tempRate = wanted; 1636 LOGV_IF(EXTRA_VERBOSE, "HAL:setDelay - Fusion"); 1637 //nsToHz 1638 LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %.0f > %s (%lld)", 1639 1000000000.f / tempRate, mpu.gyro_fifo_rate, 1640 getTimestamp()); 1641 tempFd = open(mpu.gyro_fifo_rate, O_RDWR); 1642 res = write_attribute_sensor(tempFd, 1000000000.f / tempRate); 1643 if(res < 0) { 1644 LOGE("HAL:GYRO update delay error"); 1645 } 1646 1647 //nsToHz (BMA250) 1648 if(USE_THIRD_PARTY_ACCEL) { 1649 LOGV_IF(SYSFS_VERBOSE, "echo %lld > %s (%lld)", 1650 wanted_3rd_party_sensor / 1000000L, mpu.accel_fifo_rate, 1651 getTimestamp()); 1652 tempFd = open(mpu.accel_fifo_rate, O_RDWR); 1653 res = write_attribute_sensor(tempFd, wanted_3rd_party_sensor / 1000000L); 1654 LOGE_IF(res < 0, "HAL:ACCEL update delay error"); 1655 } 1656 1657 if (!mCompassSensor->isIntegrated()) { 1658 LOGV_IF(PROCESS_VERBOSE, "HAL:Ext compass rate %.2f Hz", 1000000000.f / wanted_3rd_party_sensor); 1659 mCompassSensor->setDelay(ID_M, wanted_3rd_party_sensor); 1660 got = mCompassSensor->getDelay(ID_M); 1661 inv_set_compass_sample_rate(got / 1000); 1662 } 1663 1664 } else { 1665 1666 if (GY_ENABLED) { 1667 wanted = (mDelays[Gyro] <= mDelays[RawGyro]? 1668 (mEnabled & (1 << Gyro)? mDelays[Gyro]: mDelays[RawGyro]): 1669 (mEnabled & (1 << RawGyro)? mDelays[RawGyro]: mDelays[Gyro])); 1670 1671 if (isDmpDisplayOrientationOn() && mDmpOrientationEnabled) { 1672 getDmpRate(&wanted); 1673 } 1674 1675 LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %.0f > %s (%lld)", 1676 1000000000.f / wanted, mpu.gyro_fifo_rate, getTimestamp()); 1677 tempFd = open(mpu.gyro_fifo_rate, O_RDWR); 1678 res = write_attribute_sensor(tempFd, 1000000000.f / wanted); 1679 LOGE_IF(res < 0, "HAL:GYRO update delay error"); 1680 } 1681 1682 if (A_ENABLED) { /* else if because there is only 1 fifo rate for MPUxxxx */ 1683 if (GY_ENABLED && mDelays[Gyro] < mDelays[Accelerometer]) { 1684 wanted = mDelays[Gyro]; 1685 } 1686 else if (GY_ENABLED && mDelays[RawGyro] < mDelays[Accelerometer]) { 1687 wanted = mDelays[RawGyro]; 1688 1689 } else { 1690 wanted = mDelays[Accelerometer]; 1691 } 1692 1693 if (isDmpDisplayOrientationOn() && mDmpOrientationEnabled) { 1694 getDmpRate(&wanted); 1695 } 1696 1697 /* TODO: use function pointers to calculate delay value specific to vendor */ 1698 LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %.0f > %s (%lld)", 1699 1000000000.f / wanted, mpu.accel_fifo_rate, getTimestamp()); 1700 tempFd = open(mpu.accel_fifo_rate, O_RDWR); 1701 if(USE_THIRD_PARTY_ACCEL) { 1702 //BMA250 in ms 1703 res = write_attribute_sensor(tempFd, wanted / 1000000L); 1704 } 1705 else { 1706 //MPUxxxx in hz 1707 res = write_attribute_sensor(tempFd, 1000000000.f/wanted); 1708 } 1709 LOGE_IF(res < 0, "HAL:ACCEL update delay error"); 1710 } 1711 1712 /* Invensense compass calibration */ 1713 if (M_ENABLED) { 1714 if (!mCompassSensor->isIntegrated()) { 1715 wanted = mDelays[MagneticField]; 1716 } else { 1717 if (GY_ENABLED && mDelays[Gyro] < mDelays[MagneticField]) { 1718 wanted = mDelays[Gyro]; 1719 } 1720 else if (GY_ENABLED && mDelays[RawGyro] < mDelays[MagneticField]) { 1721 wanted = mDelays[RawGyro]; 1722 } else if (A_ENABLED && mDelays[Accelerometer] < mDelays[MagneticField]) { 1723 wanted = mDelays[Accelerometer]; 1724 } else { 1725 wanted = mDelays[MagneticField]; 1726 } 1727 1728 if (isDmpDisplayOrientationOn() && mDmpOrientationEnabled) { 1729 getDmpRate(&wanted); 1730 } 1731 } 1732 1733 mCompassSensor->setDelay(ID_M, wanted); 1734 got = mCompassSensor->getDelay(ID_M); 1735 inv_set_compass_sample_rate(got / 1000); 1736 } 1737 1738 } 1739 1740 unsigned long sensors = mLocalSensorMask & mMasterSensorMask; 1741 if (sensors & 1742 (INV_THREE_AXIS_GYRO 1743 | INV_THREE_AXIS_ACCEL 1744 | (INV_THREE_AXIS_COMPASS * mCompassSensor->isIntegrated()))) { 1745 res = masterEnable(1); 1746 } else { // all sensors idle -> reduce power 1747 res = onPower(0); 1748 } 1749 } 1750 pthread_mutex_unlock(&GlobalHalMutex); 1751 return res; 1752 } 1753 1754 /* For Third Party Accel Input Subsystem Drivers only */ 1755 /* TODO: FIX! data is not used and count not decremented, results is hardcoded to 0 */ 1756 int MPLSensor::readAccelEvents(sensors_event_t* /*data*/, int count) 1757 { 1758 VHANDLER_LOG; 1759 1760 if (count < 1) 1761 return -EINVAL; 1762 1763 ssize_t n = mAccelInputReader.fill(accel_fd); 1764 if (n < 0) { 1765 LOGE("HAL:missed accel events, exit"); 1766 return n; 1767 } 1768 1769 int numEventReceived = 0; 1770 input_event const* event; 1771 int nb, done = 0; 1772 1773 while (!done && count && mAccelInputReader.readEvent(&event)) { 1774 int type = event->type; 1775 if (type == EV_ABS) { 1776 if (event->code == EVENT_TYPE_ACCEL_X) { 1777 mPendingMask |= 1 << Accelerometer; 1778 mCachedAccelData[0] = event->value; 1779 } else if (event->code == EVENT_TYPE_ACCEL_Y) { 1780 mPendingMask |= 1 << Accelerometer; 1781 mCachedAccelData[1] = event->value; 1782 } else if (event->code == EVENT_TYPE_ACCEL_Z) { 1783 mPendingMask |= 1 << Accelerometer; 1784 mCachedAccelData[2] =event-> value; 1785 } 1786 } else if (type == EV_SYN) { 1787 done = 1; 1788 if (mLocalSensorMask & INV_THREE_AXIS_ACCEL) { 1789 inv_build_accel(mCachedAccelData, 0, getTimestamp()); 1790 } 1791 } else { 1792 LOGE("HAL:AccelSensor: unknown event (type=%d, code=%d)", 1793 type, event->code); 1794 } 1795 mAccelInputReader.next(); 1796 } 1797 1798 return numEventReceived; 1799 } 1800 1801 /** 1802 * Should be called after reading at least one of gyro 1803 * compass or accel data. (Also okay for handling all of them). 1804 * @returns 0, if successful, error number if not. 1805 */ 1806 /* TODO: This should probably be called "int readEvents(...)" 1807 * and readEvents() called "void cacheData(void)". 1808 */ 1809 int MPLSensor::executeOnData(sensors_event_t* data, int count) 1810 { 1811 VFUNC_LOG; 1812 1813 inv_execute_on_data(); 1814 1815 int numEventReceived = 0; 1816 1817 long msg; 1818 msg = inv_get_message_level_0(1); 1819 if (msg) { 1820 if (msg & INV_MSG_MOTION_EVENT) { 1821 LOGV_IF(PROCESS_VERBOSE, "HAL:**** Motion ****\n"); 1822 } 1823 if (msg & INV_MSG_NO_MOTION_EVENT) { 1824 LOGV_IF(PROCESS_VERBOSE, "HAL:***** No Motion *****\n"); 1825 /* after the first no motion, the gyro should be 1826 calibrated well */ 1827 mGyroAccuracy = SENSOR_STATUS_ACCURACY_HIGH; 1828 /* if gyros are on and we got a no motion, set a flag 1829 indicating that the cal file can be written. */ 1830 mHaveGoodMpuCal = true; 1831 } 1832 } 1833 1834 // load up virtual sensors 1835 for (int i = 0; i < numSensors; i++) { 1836 int update; 1837 if (mEnabled & (1 << i)) { 1838 update = CALL_MEMBER_FN(this, mHandlers[i])(mPendingEvents + i); 1839 mPendingMask |= (1 << i); 1840 1841 if (update && (count > 0)) { 1842 *data++ = mPendingEvents[i]; 1843 count--; 1844 numEventReceived++; 1845 } 1846 } 1847 } 1848 1849 return numEventReceived; 1850 } 1851 1852 // collect data for MPL (but NOT sensor service currently), from driver layer 1853 /* TODO: FIX! data and count are not used, results is hardcoded to 0 */ 1854 /* TODO: This should probably be called "void cacheEvents(void)" 1855 * And executeOnData() should be int readEvents(data,count) 1856 */ 1857 int MPLSensor::readEvents(sensors_event_t* /*data*/, int /*count*/) { 1858 1859 1860 int lp_quaternion_on = 0, nbyte; 1861 int i, nb, mask = 0, numEventReceived = 0, 1862 sensors = ((mLocalSensorMask & INV_THREE_AXIS_GYRO)? 1 : 0) + 1863 ((mLocalSensorMask & INV_THREE_AXIS_ACCEL)? 1 : 0) + 1864 (((mLocalSensorMask & INV_THREE_AXIS_COMPASS) && mCompassSensor->isIntegrated())? 1 : 0); 1865 char *rdata = mIIOBuffer; 1866 1867 nbyte= (8 * sensors + 8) * 1; 1868 1869 if (isLowPowerQuatEnabled()) { 1870 lp_quaternion_on = checkLPQuaternion(); 1871 if (lp_quaternion_on) { 1872 nbyte += sizeof(mCachedQuaternionData); //currently 16 bytes for Q data 1873 } 1874 } 1875 1876 // pthread_mutex_lock(&mMplMutex); 1877 // pthread_mutex_lock(&mHALMutex); 1878 1879 ssize_t rsize = read(iio_fd, rdata, nbyte); 1880 if (sensors == 0) { 1881 // read(iio_fd, rdata, nbyte); 1882 rsize = read(iio_fd, rdata, sizeof(mIIOBuffer)); 1883 } 1884 1885 #ifdef TESTING 1886 LOGI("get one sample of IIO data with size: %d", rsize); 1887 LOGI("sensors: %d", sensors); 1888 1889 LOGI_IF(mLocalSensorMask & INV_THREE_AXIS_GYRO, "gyro x/y/z: %d/%d/%d", 1890 *((short *) (rdata + 0)), *((short *) (rdata + 2)), 1891 *((short *) (rdata + 4))); 1892 LOGI_IF(mLocalSensorMask & INV_THREE_AXIS_ACCEL, "accel x/y/z: %d/%d/%d", 1893 *((short *) (rdata + 0 + ((mLocalSensorMask & INV_THREE_AXIS_GYRO)? 6: 0))), 1894 *((short *) (rdata + 2 + ((mLocalSensorMask & INV_THREE_AXIS_GYRO)? 6: 0))), 1895 *((short *) (rdata + 4) + ((mLocalSensorMask & INV_THREE_AXIS_GYRO)? 6: 0))); 1896 1897 LOGI_IF(mLocalSensorMask & INV_THREE_AXIS_COMPASS & 1898 mCompassSensor->isIntegrated(), "compass x/y/z: %d/%d/%d", 1899 *((short *) (rdata + 0 + ((mLocalSensorMask & INV_THREE_AXIS_GYRO)? 6: 0) + 1900 ((mLocalSensorMask & INV_THREE_AXIS_ACCEL)? 6: 0))), 1901 *((short *) (rdata + 2 + ((mLocalSensorMask & INV_THREE_AXIS_GYRO)? 6: 0) + 1902 ((mLocalSensorMask & INV_THREE_AXIS_ACCEL)? 6: 0))), 1903 *((short *) (rdata + 4) + ((mLocalSensorMask & INV_THREE_AXIS_GYRO)? 6: 0) + 1904 ((mLocalSensorMask & INV_THREE_AXIS_ACCEL)? 6: 0))); 1905 #endif 1906 1907 if (rsize < (nbyte - 8)) { 1908 LOGE("HAL:ERR Full data packet was not read. rsize=%zd nbyte=%d sensors=%d errno=%d(%s)", 1909 rsize, nbyte, sensors, errno, strerror(errno)); 1910 return -1; 1911 } 1912 1913 if (isLowPowerQuatEnabled() && lp_quaternion_on) { 1914 1915 for (i=0; i< 4; i++) { 1916 mCachedQuaternionData[i]= *(long*)rdata; 1917 rdata += sizeof(long); 1918 } 1919 } 1920 1921 for (i = 0; i < 3; i++) { 1922 if (mLocalSensorMask & INV_THREE_AXIS_GYRO) { 1923 mCachedGyroData[i] = *((short *) (rdata + i * 2)); 1924 } 1925 if (mLocalSensorMask & INV_THREE_AXIS_ACCEL) { 1926 mCachedAccelData[i] = *((short *) (rdata + i * 2 + 1927 ((mLocalSensorMask & INV_THREE_AXIS_GYRO)? 6: 0))); 1928 } 1929 if ((mLocalSensorMask & INV_THREE_AXIS_COMPASS) && mCompassSensor->isIntegrated()) { 1930 mCachedCompassData[i] = *((short *) (rdata + i * 2 + 6 * (sensors - 1))); 1931 } 1932 } 1933 1934 mask |= (((mLocalSensorMask & INV_THREE_AXIS_GYRO)? 1 << Gyro: 0) + 1935 ((mLocalSensorMask & INV_THREE_AXIS_ACCEL)? 1 << Accelerometer: 0)); 1936 if ((mLocalSensorMask & INV_THREE_AXIS_COMPASS) && mCompassSensor->isIntegrated() && 1937 (mCachedCompassData[0] != 0 || mCachedCompassData[1] != 0 || mCachedCompassData[0] != 0)) { 1938 mask |= 1 << MagneticField; 1939 } 1940 1941 mSensorTimestamp = *((long long *) (rdata + 8 * sensors)); 1942 if (mCompassSensor->isIntegrated()) { 1943 mCompassTimestamp = mSensorTimestamp; 1944 } 1945 1946 if (mask & (1 << Gyro)) { 1947 // send down temperature every 0.5 seconds 1948 // with timestamp measured in "driver" layer 1949 if(mSensorTimestamp - mTempCurrentTime >= 500000000LL) { 1950 mTempCurrentTime = mSensorTimestamp; 1951 long long temperature[2]; 1952 if(inv_read_temperature(temperature) == 0) { 1953 LOGV_IF(INPUT_DATA, 1954 "HAL:inv_read_temperature = %lld, timestamp= %lld", 1955 temperature[0], temperature[1]); 1956 inv_build_temp(temperature[0], temperature[1]); 1957 } 1958 #ifdef TESTING 1959 long bias[3], temp, temp_slope[3]; 1960 inv_get_gyro_bias(bias, &temp); 1961 inv_get_gyro_ts(temp_slope); 1962 1963 LOGI("T: %.3f " 1964 "GB: %+13f %+13f %+13f " 1965 "TS: %+13f %+13f %+13f " 1966 "\n", 1967 (float)temperature[0] / 65536.f, 1968 (float)bias[0] / 65536.f / 16.384f, 1969 (float)bias[1] / 65536.f / 16.384f, 1970 (float)bias[2] / 65536.f / 16.384f, 1971 temp_slope[0] / 65536.f, 1972 temp_slope[1] / 65536.f, 1973 temp_slope[2] / 65536.f); 1974 #endif 1975 } 1976 1977 mPendingMask |= 1 << Gyro; 1978 mPendingMask |= 1 << RawGyro; 1979 1980 if (mLocalSensorMask & INV_THREE_AXIS_GYRO) { 1981 inv_build_gyro(mCachedGyroData, mSensorTimestamp); 1982 LOGV_IF(INPUT_DATA, 1983 "HAL:inv_build_gyro: %+8d %+8d %+8d - %lld", 1984 mCachedGyroData[0], mCachedGyroData[1], 1985 mCachedGyroData[2], mSensorTimestamp); 1986 } 1987 } 1988 1989 if (mask & (1 << Accelerometer)) { 1990 mPendingMask |= 1 << Accelerometer; 1991 if (mLocalSensorMask & INV_THREE_AXIS_ACCEL) { 1992 inv_build_accel(mCachedAccelData, 0, mSensorTimestamp); 1993 LOGV_IF(INPUT_DATA, 1994 "HAL:inv_build_accel: %+8ld %+8ld %+8ld - %lld", 1995 mCachedAccelData[0], mCachedAccelData[1], 1996 mCachedAccelData[2], mSensorTimestamp); 1997 } 1998 } 1999 2000 if ((mask & (1 << MagneticField)) && mCompassSensor->isIntegrated()) { 2001 int status = 0; 2002 if (mCompassSensor->providesCalibration()) { 2003 status = mCompassSensor->getAccuracy(); 2004 status |= INV_CALIBRATED; 2005 } 2006 if (mLocalSensorMask & INV_THREE_AXIS_COMPASS) { 2007 inv_build_compass(mCachedCompassData, status, 2008 mCompassTimestamp); 2009 LOGV_IF(INPUT_DATA, "HAL:inv_build_compass: %+8ld %+8ld %+8ld - %lld", 2010 mCachedCompassData[0], mCachedCompassData[1], 2011 mCachedCompassData[2], mCompassTimestamp); 2012 } 2013 } 2014 2015 if (isLowPowerQuatEnabled() && lp_quaternion_on) { 2016 2017 inv_build_quat(mCachedQuaternionData, 32 /*default 32 for now (16/32bits)*/, mSensorTimestamp); 2018 LOGV_IF(INPUT_DATA, "HAL:inv_build_quat: %+8ld %+8ld %+8ld %+8ld - %lld", 2019 mCachedQuaternionData[0], mCachedQuaternionData[1], 2020 mCachedQuaternionData[2], mCachedQuaternionData[3], mSensorTimestamp); 2021 } 2022 2023 // pthread_mutex_unlock(&mMplMutex); 2024 // pthread_mutex_unlock(&mHALMutex); 2025 2026 return numEventReceived; 2027 } 2028 2029 /* use for both MPUxxxx and third party compass */ 2030 int MPLSensor::readCompassEvents(sensors_event_t* /*data*/, int count) 2031 { 2032 VHANDLER_LOG; 2033 2034 if (count < 1) 2035 return -EINVAL; 2036 2037 int numEventReceived = 0; 2038 int done = 0; 2039 int nb; 2040 2041 // pthread_mutex_lock(&mMplMutex); 2042 // pthread_mutex_lock(&mHALMutex); 2043 2044 done = mCompassSensor->readSample(mCachedCompassData, &mCompassTimestamp); 2045 #ifdef COMPASS_YAS53x 2046 if (mCompassSensor->checkCoilsReset()) { 2047 //Reset relevant compass settings 2048 resetCompass(); 2049 } 2050 #endif 2051 if (done > 0) { 2052 int status = 0; 2053 if (mCompassSensor->providesCalibration()) { 2054 status = mCompassSensor->getAccuracy(); 2055 status |= INV_CALIBRATED; 2056 } 2057 if (mLocalSensorMask & INV_THREE_AXIS_COMPASS) { 2058 inv_build_compass(mCachedCompassData, status, 2059 mCompassTimestamp); 2060 LOGV_IF(INPUT_DATA, "HAL:inv_build_compass: %+8ld %+8ld %+8ld - %lld", 2061 mCachedCompassData[0], mCachedCompassData[1], 2062 mCachedCompassData[2], mCompassTimestamp); 2063 } 2064 } 2065 2066 // pthread_mutex_unlock(&mMplMutex); 2067 // pthread_mutex_unlock(&mHALMutex); 2068 2069 return numEventReceived; 2070 } 2071 2072 #ifdef COMPASS_YAS53x 2073 int MPLSensor::resetCompass() 2074 { 2075 VFUNC_LOG; 2076 2077 //Reset compass cal if enabled 2078 if (mFeatureActiveMask & INV_COMPASS_CAL) { 2079 LOGV_IF(EXTRA_VERBOSE, "HAL:Reset compass cal"); 2080 inv_init_vector_compass_cal(); 2081 } 2082 2083 //Reset compass fit if enabled 2084 if (mFeatureActiveMask & INV_COMPASS_FIT) { 2085 LOGV_IF(EXTRA_VERBOSE, "HAL:Reset compass fit"); 2086 inv_init_compass_fit(); 2087 } 2088 2089 return 0; 2090 } 2091 #endif 2092 2093 int MPLSensor::getFd() const 2094 { 2095 VFUNC_LOG; 2096 LOGV_IF(EXTRA_VERBOSE, "MPLSensor::getFd returning %d", iio_fd); 2097 return iio_fd; 2098 } 2099 2100 int MPLSensor::getAccelFd() const 2101 { 2102 VFUNC_LOG; 2103 LOGV_IF(EXTRA_VERBOSE, "MPLSensor::getAccelFd returning %d", accel_fd); 2104 return accel_fd; 2105 } 2106 2107 int MPLSensor::getCompassFd() const 2108 { 2109 VFUNC_LOG; 2110 int fd = mCompassSensor->getFd(); 2111 LOGV_IF(EXTRA_VERBOSE, "MPLSensor::getCompassFd returning %d", fd); 2112 return fd; 2113 } 2114 2115 int MPLSensor::turnOffAccelFifo() { 2116 int i, res, tempFd; 2117 char *accel_fifo_enable[3] = {mpu.accel_x_fifo_enable, 2118 mpu.accel_y_fifo_enable, mpu.accel_z_fifo_enable}; 2119 2120 for (i = 0; i < 3; i++) { 2121 res = write_sysfs_int(accel_fifo_enable[i], 0); 2122 if (res < 0) { 2123 return res; 2124 } 2125 } 2126 return 0; 2127 } 2128 2129 int MPLSensor::enableDmpOrientation(int en) 2130 { 2131 VFUNC_LOG; 2132 /* TODO: FIX error handling. Handle or ignore it appropriately for hw. */ 2133 int res = 0; 2134 int enabled_sensors = mEnabled; 2135 2136 if (isMpu3050()) 2137 return res; 2138 2139 pthread_mutex_lock(&GlobalHalMutex); 2140 2141 // on power if not already On 2142 res = onPower(1); 2143 // reset master enable 2144 res = masterEnable(0); 2145 2146 if (en) { 2147 //Enable DMP orientation 2148 if (write_sysfs_int(mpu.display_orientation_on, en) < 0) { 2149 LOGE("HAL:ERR can't enable Android orientation"); 2150 res = -1; // indicate an err 2151 } 2152 2153 // open DMP Orient Fd 2154 res = openDmpOrientFd(); 2155 2156 // enable DMP 2157 res = onDMP(1); 2158 2159 // default DMP output rate to FIFO 2160 if (write_sysfs_int(mpu.dmp_output_rate, 5) < 0) { 2161 LOGE("HAL:ERR can't default DMP output rate"); 2162 } 2163 2164 // set DMP rate to 200Hz 2165 if (write_sysfs_int(mpu.accel_fifo_rate, 200) < 0) { 2166 res = -1; 2167 LOGE("HAL:ERR can't set DMP rate to 200Hz"); 2168 } 2169 2170 // enable accel engine 2171 res = enableAccel(1); 2172 2173 // disable accel FIFO 2174 if (!A_ENABLED) { 2175 res = turnOffAccelFifo(); 2176 } 2177 2178 mFeatureActiveMask |= INV_DMP_DISPL_ORIENTATION; 2179 } else { 2180 // disable DMP 2181 res = onDMP(0); 2182 2183 // disable accel engine 2184 if (!A_ENABLED) { 2185 res = enableAccel(0); 2186 } 2187 } 2188 2189 res = masterEnable(1); 2190 pthread_mutex_unlock(&GlobalHalMutex); 2191 return res; 2192 } 2193 2194 int MPLSensor::openDmpOrientFd() 2195 { 2196 VFUNC_LOG; 2197 2198 if (!isDmpDisplayOrientationOn() || dmp_orient_fd >= 0) { 2199 LOGV_IF(PROCESS_VERBOSE, "HAL:DMP display orientation disabled or file desc opened"); 2200 return -1; 2201 } 2202 2203 dmp_orient_fd = open(mpu.event_display_orientation, O_RDONLY| O_NONBLOCK); 2204 if (dmp_orient_fd < 0) { 2205 LOGE("HAL:ERR couldn't open dmpOrient node"); 2206 return -1; 2207 } else { 2208 LOGV_IF(PROCESS_VERBOSE, "HAL:dmp_orient_fd opened : %d", dmp_orient_fd); 2209 return 0; 2210 } 2211 } 2212 2213 int MPLSensor::closeDmpOrientFd() 2214 { 2215 VFUNC_LOG; 2216 if (dmp_orient_fd >= 0) 2217 close(dmp_orient_fd); 2218 return 0; 2219 } 2220 2221 int MPLSensor::dmpOrientHandler(int orient) 2222 { 2223 VFUNC_LOG; 2224 2225 LOGV_IF(PROCESS_VERBOSE, "HAL:orient %x", orient); 2226 return 0; 2227 } 2228 2229 int MPLSensor::readDmpOrientEvents(sensors_event_t* data, int count) { 2230 VFUNC_LOG; 2231 2232 char dummy[4]; 2233 int screen_orientation = 0; 2234 FILE *fp; 2235 2236 fp = fopen(mpu.event_display_orientation, "r"); 2237 if (fp == NULL) { 2238 LOGE("HAL:cannot open event_display_orientation"); 2239 return 0; 2240 } 2241 fscanf(fp, "%d\n", &screen_orientation); 2242 fclose(fp); 2243 2244 int numEventReceived = 0; 2245 2246 if (mDmpOrientationEnabled && count > 0) { 2247 sensors_event_t temp; 2248 2249 bzero(&temp, sizeof(temp)); /* Let's hope that SENSOR_TYPE_NONE is 0 */ 2250 temp.version = sizeof(sensors_event_t); 2251 temp.sensor = ID_SO; 2252 #ifdef ENABLE_DMP_SCREEN_AUTO_ROTATION 2253 temp.type = SENSOR_TYPE_SCREEN_ORIENTATION; 2254 temp.screen_orientation = screen_orientation; 2255 #endif 2256 struct timespec ts; 2257 clock_gettime(CLOCK_MONOTONIC, &ts); 2258 temp.timestamp = (int64_t) ts.tv_sec * 1000000000 + ts.tv_nsec; 2259 2260 *data++ = temp; 2261 count--; 2262 numEventReceived++; 2263 } 2264 2265 // read dummy data per driver's request 2266 dmpOrientHandler(screen_orientation); 2267 read(dmp_orient_fd, dummy, 4); 2268 2269 return numEventReceived; 2270 } 2271 2272 int MPLSensor::getDmpOrientFd() 2273 { 2274 VFUNC_LOG; 2275 2276 LOGV_IF(EXTRA_VERBOSE, "MPLSensor::getDmpOrientFd returning %d", dmp_orient_fd); 2277 return dmp_orient_fd; 2278 2279 } 2280 2281 int MPLSensor::checkDMPOrientation() 2282 { 2283 VFUNC_LOG; 2284 return ((mFeatureActiveMask & INV_DMP_DISPL_ORIENTATION) ? 1 : 0); 2285 } 2286 2287 int MPLSensor::getDmpRate(int64_t *wanted) 2288 { 2289 if (checkDMPOrientation() || checkLPQuaternion()) { 2290 // set DMP output rate to FIFO 2291 write_sysfs_int(mpu.dmp_output_rate, 1000000000.f / *wanted); 2292 LOGV_IF(PROCESS_VERBOSE, "HAL:DMP FIFO rate %.2f Hz", 1000000000.f / *wanted); 2293 2294 //DMP running rate must be @ 200Hz 2295 *wanted= RATE_200HZ; 2296 LOGV_IF(PROCESS_VERBOSE, "HAL:DMP rate= %.2f Hz", 1000000000.f / *wanted); 2297 } 2298 return 0; 2299 } 2300 2301 int MPLSensor::getPollTime() 2302 { 2303 VHANDLER_LOG; 2304 return mPollTime; 2305 } 2306 2307 bool MPLSensor::hasPendingEvents() const 2308 { 2309 VHANDLER_LOG; 2310 // if we are using the polling workaround, force the main 2311 // loop to check for data every time 2312 return (mPollTime != -1); 2313 } 2314 2315 /* TODO: support resume suspend when we gain more info about them*/ 2316 void MPLSensor::sleepEvent() 2317 { 2318 VFUNC_LOG; 2319 } 2320 2321 void MPLSensor::wakeEvent() 2322 { 2323 VFUNC_LOG; 2324 } 2325 2326 int MPLSensor::inv_float_to_q16(float *fdata, long *ldata) 2327 { 2328 VHANDLER_LOG; 2329 2330 if (!fdata || !ldata) 2331 return -1; 2332 ldata[0] = (long)(fdata[0] * 65536.f); 2333 ldata[1] = (long)(fdata[1] * 65536.f); 2334 ldata[2] = (long)(fdata[2] * 65536.f); 2335 return 0; 2336 } 2337 2338 int MPLSensor::inv_long_to_q16(long *fdata, long *ldata) 2339 { 2340 VHANDLER_LOG; 2341 2342 if (!fdata || !ldata) 2343 return -1; 2344 ldata[0] = (fdata[1] * 65536.f); 2345 ldata[1] = (fdata[2] * 65536.f); 2346 ldata[2] = (fdata[3] * 65536.f); 2347 return 0; 2348 } 2349 2350 int MPLSensor::inv_float_to_round(float *fdata, long *ldata) 2351 { 2352 VHANDLER_LOG; 2353 2354 if (!fdata || !ldata) 2355 return -1; 2356 ldata[0] = (long)fdata[0]; 2357 ldata[1] = (long)fdata[1]; 2358 ldata[2] = (long)fdata[2]; 2359 return 0; 2360 } 2361 2362 int MPLSensor::inv_float_to_round2(float *fdata, short *ldata) 2363 { 2364 VHANDLER_LOG; 2365 2366 if (!fdata || !ldata) 2367 return -1; 2368 ldata[0] = (short)fdata[0]; 2369 ldata[1] = (short)fdata[1]; 2370 ldata[2] = (short)fdata[2]; 2371 return 0; 2372 } 2373 2374 int MPLSensor::inv_read_temperature(long long *data) 2375 { 2376 VHANDLER_LOG; 2377 2378 int count = 0; 2379 char raw_buf[40]; 2380 long raw = 0; 2381 2382 long long timestamp = 0; 2383 2384 memset(raw_buf, 0, sizeof(raw_buf)); 2385 count = read_attribute_sensor(gyro_temperature_fd, raw_buf, 2386 sizeof(raw_buf)); 2387 if(count < 1) { 2388 LOGE("HAL:error reading gyro temperature"); 2389 return -1; 2390 } 2391 2392 count = sscanf(raw_buf, "%ld%lld", &raw, ×tamp); 2393 2394 if(count < 0) { 2395 return -1; 2396 } 2397 2398 LOGV_IF(ENG_VERBOSE, 2399 "HAL:temperature raw = %ld, timestamp = %lld, count = %d", 2400 raw, timestamp, count); 2401 data[0] = raw; 2402 data[1] = timestamp; 2403 2404 return 0; 2405 } 2406 2407 int MPLSensor::inv_read_dmp_state(int fd) 2408 { 2409 VFUNC_LOG; 2410 2411 if(fd < 0) 2412 return -1; 2413 2414 int count = 0; 2415 char raw_buf[10]; 2416 short raw = 0; 2417 2418 memset(raw_buf, 0, sizeof(raw_buf)); 2419 count = read_attribute_sensor(fd, raw_buf, sizeof(raw_buf)); 2420 if(count < 1) { 2421 LOGE("HAL:error reading dmp state"); 2422 close(fd); 2423 return -1; 2424 } 2425 count = sscanf(raw_buf, "%hd", &raw); 2426 if(count < 0) { 2427 LOGE("HAL:dmp state data is invalid"); 2428 close(fd); 2429 return -1; 2430 } 2431 LOGV_IF(EXTRA_VERBOSE, "HAL:dmp state = %d, count = %d", raw, count); 2432 close(fd); 2433 return (int)raw; 2434 } 2435 2436 int MPLSensor::inv_read_sensor_bias(int fd, long *data) 2437 { 2438 VFUNC_LOG; 2439 2440 if(fd == -1) { 2441 return -1; 2442 } 2443 2444 char buf[50]; 2445 char x[15], y[15], z[15]; 2446 2447 memset(buf, 0, sizeof(buf)); 2448 int count = read_attribute_sensor(fd, buf, sizeof(buf)); 2449 if(count < 1) { 2450 LOGE("HAL:Error reading gyro bias"); 2451 return -1; 2452 } 2453 count = sscanf(buf, "%[^','],%[^','],%[^',']", x, y, z); 2454 if(count) { 2455 /* scale appropriately for MPL */ 2456 LOGV_IF(ENG_VERBOSE, 2457 "HAL:pre-scaled bias: X:Y:Z (%ld, %ld, %ld)", 2458 atol(x), atol(y), atol(z)); 2459 2460 data[0] = (long)(atol(x) / 10000 * (1L << 16)); 2461 data[1] = (long)(atol(y) / 10000 * (1L << 16)); 2462 data[2] = (long)(atol(z) / 10000 * (1L << 16)); 2463 2464 LOGV_IF(ENG_VERBOSE, 2465 "HAL:scaled bias: X:Y:Z (%ld, %ld, %ld)", 2466 data[0], data[1], data[2]); 2467 } 2468 return 0; 2469 } 2470 2471 /** fill in the sensor list based on which sensors are configured. 2472 * return the number of configured sensors. 2473 * parameter list must point to a memory region of at least 7*sizeof(sensor_t) 2474 * parameter len gives the length of the buffer pointed to by list 2475 */ 2476 int MPLSensor::populateSensorList(struct sensor_t *list, int len) 2477 { 2478 VFUNC_LOG; 2479 2480 int numsensors; 2481 2482 if(len < (int)((sizeof(sSensorList) / sizeof(sensor_t)) * sizeof(sensor_t))) { 2483 LOGE("HAL:sensor list too small, not populating."); 2484 return -(sizeof(sSensorList) / sizeof(sensor_t)); 2485 } 2486 2487 /* fill in the base values */ 2488 memcpy(list, sSensorList, sizeof (struct sensor_t) * (sizeof(sSensorList) / sizeof(sensor_t))); 2489 2490 /* first add gyro, accel and compass to the list */ 2491 2492 /* fill in gyro/accel values */ 2493 if(chip_ID == NULL) { 2494 LOGE("HAL:Can not get gyro/accel id"); 2495 } 2496 fillGyro(chip_ID, list); 2497 fillAccel(chip_ID, list); 2498 2499 // TODO: need fixes for unified HAL and 3rd-party solution 2500 mCompassSensor->fillList(&list[MagneticField]); 2501 2502 if(1) { 2503 numsensors = (sizeof(sSensorList) / sizeof(sensor_t)); 2504 /* all sensors will be added to the list 2505 fill in orientation values */ 2506 fillOrientation(list); 2507 /* fill in rotation vector values */ 2508 fillRV(list); 2509 /* fill in gravity values */ 2510 fillGravity(list); 2511 /* fill in Linear accel values */ 2512 fillLinearAccel(list); 2513 } else { 2514 /* no 9-axis sensors, zero fill that part of the list */ 2515 numsensors = 3; 2516 memset(list + 3, 0, 4 * sizeof(struct sensor_t)); 2517 } 2518 2519 return numsensors; 2520 } 2521 2522 void MPLSensor::fillAccel(const char* accel, struct sensor_t *list) 2523 { 2524 VFUNC_LOG; 2525 2526 if (accel) { 2527 if(accel != NULL && strcmp(accel, "BMA250") == 0) { 2528 list[Accelerometer].maxRange = ACCEL_BMA250_RANGE; 2529 list[Accelerometer].resolution = ACCEL_BMA250_RESOLUTION; 2530 list[Accelerometer].power = ACCEL_BMA250_POWER; 2531 list[Accelerometer].minDelay = ACCEL_BMA250_MINDELAY; 2532 return; 2533 } else if (accel != NULL && strcmp(accel, "MPU6050") == 0) { 2534 list[Accelerometer].maxRange = ACCEL_MPU6050_RANGE; 2535 list[Accelerometer].resolution = ACCEL_MPU6050_RESOLUTION; 2536 list[Accelerometer].power = ACCEL_MPU6050_POWER; 2537 list[Accelerometer].minDelay = ACCEL_MPU6050_MINDELAY; 2538 return; 2539 } else if (accel != NULL && strcmp(accel, "MPU6500") == 0) { 2540 list[Accelerometer].maxRange = ACCEL_MPU6500_RANGE; 2541 list[Accelerometer].resolution = ACCEL_MPU6500_RESOLUTION; 2542 list[Accelerometer].power = ACCEL_MPU6500_POWER; 2543 list[Accelerometer].minDelay = ACCEL_MPU6500_MINDELAY; 2544 2545 return; 2546 } else if (accel != NULL && strcmp(accel, "MPU9150") == 0) { 2547 list[Accelerometer].maxRange = ACCEL_MPU9150_RANGE; 2548 list[Accelerometer].resolution = ACCEL_MPU9150_RESOLUTION; 2549 list[Accelerometer].power = ACCEL_MPU9150_POWER; 2550 list[Accelerometer].minDelay = ACCEL_MPU9150_MINDELAY; 2551 return; 2552 } else if (accel != NULL && strcmp(accel, "MPU3050") == 0) { 2553 list[Accelerometer].maxRange = ACCEL_BMA250_RANGE; 2554 list[Accelerometer].resolution = ACCEL_BMA250_RESOLUTION; 2555 list[Accelerometer].power = ACCEL_BMA250_POWER; 2556 list[Accelerometer].minDelay = ACCEL_BMA250_MINDELAY; 2557 return; 2558 } 2559 } 2560 2561 LOGE("HAL:unknown accel id %s -- " 2562 "params default to bma250 and might be wrong.", 2563 accel); 2564 list[Accelerometer].maxRange = ACCEL_BMA250_RANGE; 2565 list[Accelerometer].resolution = ACCEL_BMA250_RESOLUTION; 2566 list[Accelerometer].power = ACCEL_BMA250_POWER; 2567 list[Accelerometer].minDelay = ACCEL_BMA250_MINDELAY; 2568 } 2569 2570 void MPLSensor::fillGyro(const char* gyro, struct sensor_t *list) 2571 { 2572 VFUNC_LOG; 2573 2574 if ( gyro != NULL && strcmp(gyro, "MPU3050") == 0) { 2575 list[Gyro].maxRange = GYRO_MPU3050_RANGE; 2576 list[Gyro].resolution = GYRO_MPU3050_RESOLUTION; 2577 list[Gyro].power = GYRO_MPU3050_POWER; 2578 list[Gyro].minDelay = GYRO_MPU3050_MINDELAY; 2579 } else if( gyro != NULL && strcmp(gyro, "MPU6050") == 0) { 2580 list[Gyro].maxRange = GYRO_MPU6050_RANGE; 2581 list[Gyro].resolution = GYRO_MPU6050_RESOLUTION; 2582 list[Gyro].power = GYRO_MPU6050_POWER; 2583 list[Gyro].minDelay = GYRO_MPU6050_MINDELAY; 2584 } else if( gyro != NULL && strcmp(gyro, "MPU6500") == 0) { 2585 list[Gyro].maxRange = GYRO_MPU6500_RANGE; 2586 list[Gyro].resolution = GYRO_MPU6500_RESOLUTION; 2587 list[Gyro].power = GYRO_MPU6500_POWER; 2588 list[Gyro].minDelay = GYRO_MPU6500_MINDELAY; 2589 } else if( gyro != NULL && strcmp(gyro, "MPU9150") == 0) { 2590 list[Gyro].maxRange = GYRO_MPU9150_RANGE; 2591 list[Gyro].resolution = GYRO_MPU9150_RESOLUTION; 2592 list[Gyro].power = GYRO_MPU9150_POWER; 2593 list[Gyro].minDelay = GYRO_MPU9150_MINDELAY; 2594 } else { 2595 LOGE("HAL:unknown gyro id -- gyro params will be wrong."); 2596 LOGE("HAL:default to use mpu3050 params"); 2597 list[Gyro].maxRange = GYRO_MPU3050_RANGE; 2598 list[Gyro].resolution = GYRO_MPU3050_RESOLUTION; 2599 list[Gyro].power = GYRO_MPU3050_POWER; 2600 list[Gyro].minDelay = GYRO_MPU3050_MINDELAY; 2601 } 2602 2603 list[RawGyro].maxRange = list[Gyro].maxRange; 2604 list[RawGyro].resolution = list[Gyro].resolution; 2605 list[RawGyro].power = list[Gyro].power; 2606 list[RawGyro].minDelay = list[Gyro].minDelay; 2607 2608 return; 2609 } 2610 2611 /* fillRV depends on values of accel and compass in the list */ 2612 void MPLSensor::fillRV(struct sensor_t *list) 2613 { 2614 VFUNC_LOG; 2615 2616 /* compute power on the fly */ 2617 list[RotationVector].power = list[Gyro].power + 2618 list[Accelerometer].power + 2619 list[MagneticField].power; 2620 list[RotationVector].resolution = .00001; 2621 list[RotationVector].maxRange = 1.0; 2622 list[RotationVector].minDelay = 5000; 2623 2624 return; 2625 } 2626 2627 void MPLSensor::fillOrientation(struct sensor_t *list) 2628 { 2629 VFUNC_LOG; 2630 2631 list[Orientation].power = list[Gyro].power + 2632 list[Accelerometer].power + 2633 list[MagneticField].power; 2634 list[Orientation].resolution = .00001; 2635 list[Orientation].maxRange = 360.0; 2636 list[Orientation].minDelay = 5000; 2637 2638 return; 2639 } 2640 2641 void MPLSensor::fillGravity( struct sensor_t *list) 2642 { 2643 VFUNC_LOG; 2644 2645 list[Gravity].power = list[Gyro].power + 2646 list[Accelerometer].power + 2647 list[MagneticField].power; 2648 list[Gravity].resolution = .00001; 2649 list[Gravity].maxRange = 9.81; 2650 list[Gravity].minDelay = 5000; 2651 2652 return; 2653 } 2654 2655 void MPLSensor::fillLinearAccel(struct sensor_t *list) 2656 { 2657 VFUNC_LOG; 2658 2659 list[LinearAccel].power = list[Gyro].power + 2660 list[Accelerometer].power + 2661 list[MagneticField].power; 2662 list[LinearAccel].resolution = list[Accelerometer].resolution; 2663 list[LinearAccel].maxRange = list[Accelerometer].maxRange; 2664 list[LinearAccel].minDelay = 5000; 2665 2666 return; 2667 } 2668 2669 int MPLSensor::inv_init_sysfs_attributes(void) 2670 { 2671 VFUNC_LOG; 2672 2673 unsigned char i; 2674 char sysfs_path[MAX_SYSFS_NAME_LEN], iio_trigger_path[MAX_SYSFS_NAME_LEN]; 2675 char *sptr; 2676 char **dptr; 2677 int num; 2678 2679 sysfs_names_ptr = 2680 (char*)calloc(1, sizeof(char[MAX_SYSFS_ATTRB][MAX_SYSFS_NAME_LEN])); 2681 sptr = sysfs_names_ptr; 2682 if (sptr == NULL) { 2683 LOGE("HAL:couldn't alloc mem for sysfs paths"); 2684 return -1; 2685 } 2686 2687 dptr = (char**)&mpu; 2688 i = 0; 2689 do { 2690 *dptr++ = sptr; 2691 sptr += sizeof(char[MAX_SYSFS_NAME_LEN]); 2692 } while (++i < MAX_SYSFS_ATTRB); 2693 2694 // get proper (in absolute/relative) IIO path & build MPU's sysfs paths 2695 // inv_get_sysfs_abs_path(sysfs_path); 2696 if(INV_SUCCESS != inv_get_sysfs_path(sysfs_path)) { 2697 ALOGE("MPLSensor failed get sysfs path"); 2698 return -1; 2699 } 2700 2701 if(INV_SUCCESS != inv_get_iio_trigger_path(iio_trigger_path)) { 2702 ALOGE("MPLSensor failed get iio trigger path"); 2703 return -1; 2704 } 2705 2706 sprintf(mpu.key, "%s%s", sysfs_path, "/key"); 2707 sprintf(mpu.chip_enable, "%s%s", sysfs_path, "/buffer/enable"); 2708 sprintf(mpu.buffer_length, "%s%s", sysfs_path, "/buffer/length"); 2709 sprintf(mpu.power_state, "%s%s", sysfs_path, "/power_state"); 2710 sprintf(mpu.in_timestamp_en, "%s%s", sysfs_path, "/scan_elements/in_timestamp_en"); 2711 sprintf(mpu.trigger_name, "%s%s", iio_trigger_path, "/name"); 2712 sprintf(mpu.current_trigger, "%s%s", sysfs_path, "/trigger/current_trigger"); 2713 2714 sprintf(mpu.dmp_firmware, "%s%s", sysfs_path,"/dmp_firmware"); 2715 sprintf(mpu.firmware_loaded,"%s%s", sysfs_path, "/firmware_loaded"); 2716 sprintf(mpu.dmp_on,"%s%s", sysfs_path, "/dmp_on"); 2717 sprintf(mpu.dmp_int_on,"%s%s", sysfs_path, "/dmp_int_on"); 2718 sprintf(mpu.dmp_event_int_on,"%s%s", sysfs_path, "/dmp_event_int_on"); 2719 sprintf(mpu.dmp_output_rate,"%s%s", sysfs_path, "/dmp_output_rate"); 2720 sprintf(mpu.tap_on, "%s%s", sysfs_path, "/tap_on"); 2721 2722 // TODO: for self test 2723 sprintf(mpu.self_test, "%s%s", sysfs_path, "/self_test"); 2724 2725 sprintf(mpu.temperature, "%s%s", sysfs_path, "/temperature"); 2726 sprintf(mpu.gyro_enable, "%s%s", sysfs_path, "/gyro_enable"); 2727 sprintf(mpu.gyro_fifo_rate, "%s%s", sysfs_path, "/sampling_frequency"); 2728 sprintf(mpu.gyro_orient, "%s%s", sysfs_path, "/gyro_matrix"); 2729 sprintf(mpu.gyro_x_fifo_enable, "%s%s", sysfs_path, "/scan_elements/in_anglvel_x_en"); 2730 sprintf(mpu.gyro_y_fifo_enable, "%s%s", sysfs_path, "/scan_elements/in_anglvel_y_en"); 2731 sprintf(mpu.gyro_z_fifo_enable, "%s%s", sysfs_path, "/scan_elements/in_anglvel_z_en"); 2732 2733 sprintf(mpu.accel_enable, "%s%s", sysfs_path, "/accl_enable"); 2734 sprintf(mpu.accel_fifo_rate, "%s%s", sysfs_path, "/sampling_frequency"); 2735 sprintf(mpu.accel_orient, "%s%s", sysfs_path, "/accl_matrix"); 2736 2737 2738 #ifndef THIRD_PARTY_ACCEL //MPUxxxx 2739 sprintf(mpu.accel_fsr, "%s%s", sysfs_path, "/in_accel_scale"); 2740 // TODO: for bias settings 2741 sprintf(mpu.accel_bias, "%s%s", sysfs_path, "/accl_bias"); 2742 #endif 2743 2744 sprintf(mpu.accel_x_fifo_enable, "%s%s", sysfs_path, "/scan_elements/in_accel_x_en"); 2745 sprintf(mpu.accel_y_fifo_enable, "%s%s", sysfs_path, "/scan_elements/in_accel_y_en"); 2746 sprintf(mpu.accel_z_fifo_enable, "%s%s", sysfs_path, "/scan_elements/in_accel_z_en"); 2747 2748 sprintf(mpu.quaternion_on, "%s%s", sysfs_path, "/quaternion_on"); 2749 sprintf(mpu.in_quat_r_en, "%s%s", sysfs_path, "/scan_elements/in_quaternion_r_en"); 2750 sprintf(mpu.in_quat_x_en, "%s%s", sysfs_path, "/scan_elements/in_quaternion_x_en"); 2751 sprintf(mpu.in_quat_y_en, "%s%s", sysfs_path, "/scan_elements/in_quaternion_y_en"); 2752 sprintf(mpu.in_quat_z_en, "%s%s", sysfs_path, "/scan_elements/in_quaternion_z_en"); 2753 2754 sprintf(mpu.display_orientation_on, "%s%s", sysfs_path, "/display_orientation_on"); 2755 sprintf(mpu.event_display_orientation, "%s%s", sysfs_path, "/event_display_orientation"); 2756 2757 #if SYSFS_VERBOSE 2758 // test print sysfs paths 2759 dptr = (char**)&mpu; 2760 for (i = 0; i < MAX_SYSFS_ATTRB; i++) { 2761 LOGE("HAL:sysfs path: %s", *dptr++); 2762 } 2763 #endif 2764 return 0; 2765 } 2766 2767 /* TODO: stop manually testing/using 0 and 1 instead of 2768 * false and true, but just use 0 and non-0. 2769 * This allows passing 0 and non-0 ints around instead of 2770 * having to convert to 1 and test against 1. 2771 */ 2772 bool MPLSensor::isMpu3050() 2773 { 2774 return !strcmp(chip_ID, "mpu3050") || !strcmp(chip_ID, "MPU3050"); 2775 } 2776 2777 int MPLSensor::isLowPowerQuatEnabled() 2778 { 2779 #ifdef ENABLE_LP_QUAT_FEAT 2780 return !isMpu3050(); 2781 #else 2782 return 0; 2783 #endif 2784 } 2785 2786 int MPLSensor::isDmpDisplayOrientationOn() 2787 { 2788 #ifdef ENABLE_DMP_DISPL_ORIENT_FEAT 2789 return !isMpu3050(); 2790 #else 2791 return 0; 2792 #endif 2793 } 2794