Home | History | Annotate | Download | only in libsensors_iio
      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 
     19 //#define KLP 1 //Key Lime Pie Temporary Test Define
     20 //see also the EXTRA_VERBOSE define in the MPLSensor.h header file
     21 
     22 #include <fcntl.h>
     23 #include <errno.h>
     24 #include <math.h>
     25 #include <float.h>
     26 #include <poll.h>
     27 #include <unistd.h>
     28 #include <dirent.h>
     29 #include <stdlib.h>
     30 #include <sys/select.h>
     31 #include <sys/syscall.h>
     32 #include <dlfcn.h>
     33 #include <pthread.h>
     34 #include <cutils/log.h>
     35 #include <utils/KeyedVector.h>
     36 #include <utils/String8.h>
     37 #include <string.h>
     38 #include <linux/input.h>
     39 #include <utils/Atomic.h>
     40 
     41 #include "MPLSensor.h"
     42 #include "PressureSensor.IIO.secondary.h"
     43 #include "MPLSupport.h"
     44 #include "sensor_params.h"
     45 
     46 #include "invensense.h"
     47 #include "invensense_adv.h"
     48 #include "ml_stored_data.h"
     49 #include "ml_load_dmp.h"
     50 #include "ml_sysfs_helper.h"
     51 
     52 #define ENABLE_MULTI_RATE
     53 // #define TESTING
     54 // #define USE_LPQ_AT_FASTEST
     55 #define ENABLE_PRESSSURE
     56 
     57 #ifdef THIRD_PARTY_ACCEL
     58 #pragma message("HAL:build third party accel support")
     59 #define USE_THIRD_PARTY_ACCEL (1)
     60 #else
     61 #define USE_THIRD_PARTY_ACCEL (0)
     62 #endif
     63 
     64 #define MAX_SYSFS_ATTRB (sizeof(struct sysfs_attrbs) / sizeof(char*))
     65 
     66 /******************************************************************************/
     67 /*  MPL interface misc.                                                       */
     68 /******************************************************************************/
     69 static int hertz_request = 200;
     70 
     71 #define DEFAULT_MPL_GYRO_RATE           (20000L)     //us
     72 #define DEFAULT_MPL_COMPASS_RATE        (20000L)     //us
     73 
     74 #define DEFAULT_HW_GYRO_RATE            (100)        //Hz
     75 #define DEFAULT_HW_ACCEL_RATE           (20)         //ms
     76 #define DEFAULT_HW_COMPASS_RATE         (20000000L)  //ns
     77 #define DEFAULT_HW_AKMD_COMPASS_RATE    (200000000L) //ns
     78 
     79 /* convert ns to hardware units */
     80 #define HW_GYRO_RATE_NS                 (1000000000LL / rate_request) // to Hz
     81 #define HW_ACCEL_RATE_NS                (rate_request / (1000000L))   // to ms
     82 #define HW_COMPASS_RATE_NS              (rate_request)                // to ns
     83 
     84 /* convert Hz to hardware units */
     85 #define HW_GYRO_RATE_HZ                 (hertz_request)
     86 #define HW_ACCEL_RATE_HZ                (1000 / hertz_request)
     87 #define HW_COMPASS_RATE_HZ              (1000000000LL / hertz_request)
     88 
     89 #define RATE_200HZ                      5000000LL
     90 #define RATE_15HZ                       66667000LL
     91 #define RATE_5HZ                        200000000LL
     92 
     93 // mask of virtual sensors that require gyro + accel + compass data
     94 #define VIRTUAL_SENSOR_9AXES_MASK ( \
     95         (1 << Orientation)          \
     96         | (1 << RotationVector)     \
     97         | (1 << LinearAccel)        \
     98         | (1 << Gravity)            \
     99 )
    100 // mask of virtual sensors that require gyro + accel data (but no compass data)
    101 #define VIRTUAL_SENSOR_GYRO_6AXES_MASK ( \
    102         (1 << GameRotationVector)   \
    103 )
    104 // mask of virtual sensors that require mag + accel data (but no gyro data)
    105 #define VIRTUAL_SENSOR_MAG_6AXES_MASK (    \
    106         (1 << GeomagneticRotationVector)   \
    107 )
    108 // mask of all virtual sensors
    109 #define VIRTUAL_SENSOR_ALL_MASK (       \
    110         VIRTUAL_SENSOR_9AXES_MASK       \
    111         | VIRTUAL_SENSOR_GYRO_6AXES_MASK     \
    112         | VIRTUAL_SENSOR_MAG_6AXES_MASK \
    113 )
    114 
    115 static struct timespec mt_pre;
    116 static struct sensor_t sSensorList[] =
    117 {
    118     {"MPL Gyroscope", "Invensense", 1,
    119      SENSORS_GYROSCOPE_HANDLE,
    120      SENSOR_TYPE_GYROSCOPE, 2000.0f, 1.0f, 0.5f, 10000, 0, 0, {}},
    121     {"MPL Raw Gyroscope", "Invensense", 1,
    122      SENSORS_RAW_GYROSCOPE_HANDLE,
    123      SENSOR_TYPE_GYROSCOPE_UNCALIBRATED, 2000.0f, 1.0f, 0.5f, 10000, 0, 0, {}},
    124     {"MPL Accelerometer", "Invensense", 1,
    125      SENSORS_ACCELERATION_HANDLE,
    126      SENSOR_TYPE_ACCELEROMETER, 10240.0f, 1.0f, 0.5f, 10000, 0, 0, {}},
    127     {"MPL Magnetic Field", "Invensense", 1,
    128      SENSORS_MAGNETIC_FIELD_HANDLE,
    129      SENSOR_TYPE_MAGNETIC_FIELD, 10240.0f, 1.0f, 0.5f, 10000, 0, 0, {}},
    130 #ifdef ENABLE_PRESSURE
    131      {"MPL Pressure", "Invensense", 1,
    132      SENSORS_PRESSURE_HANDLE,
    133      SENSOR_TYPE_PRESSURE, 10240.0f, 1.0f, 0.5f, 10000, 0, 0, {}},
    134 #endif
    135     {"MPL Raw Magnetic Field", "Invensense", 1,
    136      SENSORS_RAW_MAGNETIC_FIELD_HANDLE,
    137      SENSOR_TYPE_MAGNETIC_FIELD_UNCALIBRATED, 10240.0f, 1.0f, 0.5f, 10000, 0, 0, {}},
    138     {"MPL Orientation", "Invensense", 1,
    139      SENSORS_ORIENTATION_HANDLE,
    140      SENSOR_TYPE_ORIENTATION, 360.0f, 1.0f, 9.7f, 10000, 0, 0, {}},
    141     {"MPL Rotation Vector", "Invensense", 1,
    142      SENSORS_ROTATION_VECTOR_HANDLE,
    143      SENSOR_TYPE_ROTATION_VECTOR, 10240.0f, 1.0f, 0.5f, 10000, 0, 0, {}},
    144     {"MPL Game Rotation Vector", "Invensense", 1,
    145      SENSORS_GAME_ROTATION_VECTOR_HANDLE,
    146      SENSOR_TYPE_GAME_ROTATION_VECTOR, 10240.0f, 1.0f, 0.5f, 10000, 0, 0, {}},
    147     {"MPL Linear Acceleration", "Invensense", 1,
    148      SENSORS_LINEAR_ACCEL_HANDLE,
    149      SENSOR_TYPE_LINEAR_ACCELERATION, 10240.0f, 1.0f, 0.5f, 10000, 0, 0, {}},
    150     {"MPL Gravity", "Invensense", 1,
    151      SENSORS_GRAVITY_HANDLE,
    152      SENSOR_TYPE_GRAVITY, 10240.0f, 1.0f, 0.5f, 10000, 0, 0, {}},
    153     {"MPL Significant Motion", "Invensense", 1,
    154      SENSORS_SIGNIFICANT_MOTION_HANDLE,
    155      SENSOR_TYPE_SIGNIFICANT_MOTION, 100.0f, 1.0f, 1.1f, 0, 0, 0, {}},
    156     {"MPL Step Detector", "Invensense", 1,
    157      SENSORS_PEDOMETER_HANDLE,
    158      SENSOR_TYPE_STEP_DETECTOR, 100.0f, 1.0f, 1.1f, 0, 0, 0, {}},
    159     {"MPL Step Counter", "Invensense", 1,
    160      SENSORS_STEP_COUNTER_HANDLE,
    161      SENSOR_TYPE_STEP_COUNTER, 100.0f, 1.0f, 1.1f, 0, 0, 0, {}},
    162     {"MPL Geomagnetic Rotation Vector", "Invensense", 1,
    163      SENSORS_GEOMAGNETIC_ROTATION_VECTOR_HANDLE,
    164      SENSOR_TYPE_GEOMAGNETIC_ROTATION_VECTOR, 10240.0f, 1.0f, 0.5f, 10000, 0, 0, {}},
    165 #ifdef ENABLE_DMP_SCREEN_AUTO_ROTATION
    166     {"MPL Screen Orientation", "Invensense ", 1,
    167      SENSORS_SCREEN_ORIENTATION_HANDLE,
    168      SENSOR_TYPE_SCREEN_ORIENTATION, 100.0f, 1.0f, 1.1f, 0, 0, 0, {}},
    169 #endif
    170 };
    171 
    172 MPLSensor *MPLSensor::gMPLSensor = NULL;
    173 
    174 extern "C" {
    175 void procData_cb_wrapper()
    176 {
    177     if(MPLSensor::gMPLSensor) {
    178         MPLSensor::gMPLSensor->cbProcData();
    179     }
    180 }
    181 
    182 void setCallbackObject(MPLSensor* gbpt)
    183 {
    184     MPLSensor::gMPLSensor = gbpt;
    185 }
    186 
    187 MPLSensor* getCallbackObject() {
    188     return MPLSensor::gMPLSensor;
    189 }
    190 
    191 } // end of extern C
    192 
    193 //#define IINV_PLAYBACK_DBG
    194 #ifdef INV_PLAYBACK_DBG
    195 static FILE *logfile = NULL;
    196 #endif
    197 
    198 /*******************************************************************************
    199  * MPLSensor class implementation
    200  ******************************************************************************/
    201 
    202 // following extended initializer list would only be available with -std=c++11
    203 //  or -std=gnu+11
    204 MPLSensor::MPLSensor(CompassSensor *compass, int (*m_pt2AccelCalLoadFunc)(long *))
    205                        : SensorBase(NULL, NULL),
    206                          mNewData(0),
    207                          mMasterSensorMask(INV_ALL_SENSORS),
    208                          mLocalSensorMask(0),
    209                          mPollTime(-1),
    210                          mStepCountPollTime(-1),
    211                          mHaveGoodMpuCal(0),
    212                          mGyroAccuracy(0),
    213                          mAccelAccuracy(0),
    214                          mCompassAccuracy(0),
    215                          mSampleCount(0),
    216                          dmp_orient_fd(-1),
    217                          mDmpOrientationEnabled(0),
    218                          dmp_sign_motion_fd(-1),
    219                          mDmpSignificantMotionEnabled(0),
    220                          dmp_pedometer_fd(-1),
    221                          mDmpPedometerEnabled(0),
    222                          mDmpStepCountEnabled(0),
    223                          mEnabled(0),
    224                          mBatchEnabled(0),
    225                          mAccelInputReader(4),
    226                          mGyroInputReader(32),
    227                          mTempScale(0),
    228                          mTempOffset(0),
    229                          mTempCurrentTime(0),
    230                          mAccelScale(2),
    231                          mGyroScale(2000),
    232                          mCompassScale(0),
    233                          mFactoryGyroBiasAvailable(false),
    234                          mGyroBiasAvailable(false),
    235                          mGyroBiasApplied(false),
    236                          mFactoryAccelBiasAvailable(false),
    237                          mAccelBiasAvailable(false),
    238                          mAccelBiasApplied(false),
    239                          mPendingMask(0),
    240                          mSensorMask(0),
    241                          mMplFeatureActiveMask(0),
    242                          mFeatureActiveMask(0),
    243                          mDmpOn(0),
    244                          mPedUpdate(0),
    245                          mQuatSensorTimestamp(0),
    246                          mStepSensorTimestamp(0),
    247                          mLastStepCount(0),
    248                          mLeftOverBufferSize(0) {
    249     VFUNC_LOG;
    250 
    251     inv_error_t rv;
    252     int i, fd;
    253     char *port = NULL;
    254     char *ver_str;
    255     unsigned long mSensorMask;
    256     int res;
    257     FILE *fptr;
    258 
    259     mCompassSensor = compass;
    260 
    261     LOGV_IF(EXTRA_VERBOSE,
    262             "HAL:MPLSensor constructor : NumSensors = %d", NumSensors);
    263 
    264     pthread_mutex_init(&mMplMutex, NULL);
    265     pthread_mutex_init(&mHALMutex, NULL);
    266     memset(mGyroOrientation, 0, sizeof(mGyroOrientation));
    267     memset(mAccelOrientation, 0, sizeof(mAccelOrientation));
    268 
    269     /* setup sysfs paths */
    270     inv_init_sysfs_attributes();
    271 
    272     /* get chip name */
    273     if (inv_get_chip_name(chip_ID) != INV_SUCCESS) {
    274         LOGE("HAL:ERR- Failed to get chip ID\n");
    275     } else {
    276         LOGV_IF(PROCESS_VERBOSE, "HAL:Chip ID= %s\n", chip_ID);
    277     }
    278 
    279     enable_iio_sysfs();
    280 
    281     /* instantiate pressure sensor on secondary bus */
    282     if (strcmp(mSysfsPath, "") != 0) {
    283         mPressureSensor = new PressureSensor((const char*)mSysfsPath);
    284     } else {
    285         LOGE("HAL:ERR - Failed to instantiate pressure sensor class");
    286     }
    287 
    288     /* reset driver master enable */
    289     masterEnable(0);
    290 
    291     //Always load DMP for KLP
    292     /* Load DMP image if capable, ie. MPU6xxx/9xxx */
    293     loadDMP();
    294 
    295     /* open temperature fd for temp comp */
    296     LOGV_IF(EXTRA_VERBOSE, "HAL:gyro temperature path: %s", mpu.temperature);
    297     gyro_temperature_fd = open(mpu.temperature, O_RDONLY);
    298     if (gyro_temperature_fd == -1) {
    299         LOGE("HAL:could not open temperature node");
    300     } else {
    301         LOGV_IF(EXTRA_VERBOSE,
    302                 "HAL:temperature_fd opened: %s", mpu.temperature);
    303     }
    304 
    305     /* read gyro FSR to calculate accel scale later */
    306     char gyroBuf[5];
    307     int count = 0;
    308          LOGV_IF(SYSFS_VERBOSE,
    309              "HAL:sysfs:cat %s (%lld)", mpu.gyro_fsr, getTimestamp());
    310 
    311     fd = open(mpu.gyro_fsr, O_RDONLY);
    312     if(fd < 0) {
    313         LOGE("HAL:Error opening gyro FSR");
    314     } else {
    315         memset(gyroBuf, 0, sizeof(gyroBuf));
    316         count = read_attribute_sensor(fd, gyroBuf, sizeof(gyroBuf));
    317         if(count < 1) {
    318             LOGE("HAL:Error reading gyro FSR");
    319         } else {
    320             count = sscanf(gyroBuf, "%ld", &mGyroScale);
    321             if(count)
    322                 LOGV_IF(EXTRA_VERBOSE, "HAL:Gyro FSR used %ld", mGyroScale);
    323         }
    324         close(fd);
    325     }
    326 
    327     /* read gyro self test scale used to calculate factory cal bias later */
    328     char gyroScale[5];
    329          LOGV_IF(SYSFS_VERBOSE,
    330              "HAL:sysfs:cat %s (%lld)", mpu.in_gyro_self_test_scale, getTimestamp());
    331     fd = open(mpu.in_gyro_self_test_scale, O_RDONLY);
    332     if(fd < 0) {
    333         LOGE("HAL:Error opening gyro self test scale");
    334     } else {
    335         memset(gyroBuf, 0, sizeof(gyroBuf));
    336         count = read_attribute_sensor(fd, gyroScale, sizeof(gyroScale));
    337         if(count < 1) {
    338             LOGE("HAL:Error reading gyro self test scale");
    339         } else {
    340             count = sscanf(gyroScale, "%ld", &mGyroSelfTestScale);
    341             if(count)
    342                 LOGV_IF(EXTRA_VERBOSE, "HAL:Gyro self test scale used %ld", mGyroSelfTestScale);
    343         }
    344         close(fd);
    345     }
    346 
    347     /* open Factory Gyro Bias fd */
    348     /* mFactoryGyBias contains bias values that will be used for device offset */
    349     memset(mFactoryGyroBias, 0, sizeof(mFactoryGyroBias));
    350     LOGV_IF(EXTRA_VERBOSE, "HAL:factory gyro x offset path: %s", mpu.in_gyro_x_offset);
    351     LOGV_IF(EXTRA_VERBOSE, "HAL:factory gyro y offset path: %s", mpu.in_gyro_y_offset);
    352     LOGV_IF(EXTRA_VERBOSE, "HAL:factory gyro z offset path: %s", mpu.in_gyro_z_offset);
    353     gyro_x_offset_fd = open(mpu.in_gyro_x_offset, O_RDWR);
    354     gyro_y_offset_fd = open(mpu.in_gyro_y_offset, O_RDWR);
    355     gyro_z_offset_fd = open(mpu.in_gyro_z_offset, O_RDWR);
    356     if (gyro_x_offset_fd == -1 ||
    357              gyro_y_offset_fd == -1 || gyro_z_offset_fd == -1) {
    358             LOGE("HAL:could not open factory gyro calibrated bias");
    359     } else {
    360         LOGV_IF(EXTRA_VERBOSE,
    361              "HAL:gyro_offset opened");
    362     }
    363 
    364     /* open Gyro Bias fd */
    365     /* mGyroBias contains bias values that will be used for framework */
    366     /* mGyroChipBias contains bias values that will be used for dmp */
    367     memset(mGyroBias, 0, sizeof(mGyroBias));
    368     memset(mGyroChipBias, 0, sizeof(mGyroChipBias));
    369     LOGV_IF(EXTRA_VERBOSE, "HAL: gyro x dmp bias path: %s", mpu.in_gyro_x_dmp_bias);
    370     LOGV_IF(EXTRA_VERBOSE, "HAL: gyro y dmp bias path: %s", mpu.in_gyro_y_dmp_bias);
    371     LOGV_IF(EXTRA_VERBOSE, "HAL: gyro z dmp bias path: %s", mpu.in_gyro_z_dmp_bias);
    372     gyro_x_dmp_bias_fd = open(mpu.in_gyro_x_dmp_bias, O_RDWR);
    373     gyro_y_dmp_bias_fd = open(mpu.in_gyro_y_dmp_bias, O_RDWR);
    374     gyro_z_dmp_bias_fd = open(mpu.in_gyro_z_dmp_bias, O_RDWR);
    375     if (gyro_x_dmp_bias_fd == -1 ||
    376              gyro_y_dmp_bias_fd == -1 || gyro_z_dmp_bias_fd == -1) {
    377             LOGE("HAL:could not open gyro DMP calibrated bias");
    378     } else {
    379         LOGV_IF(EXTRA_VERBOSE,
    380              "HAL:gyro_dmp_bias opened");
    381     }
    382 
    383     /* read accel FSR to calcuate accel scale later */
    384     if (USE_THIRD_PARTY_ACCEL == 0) {
    385         char buf[3];
    386         int count = 0;
    387         LOGV_IF(SYSFS_VERBOSE,
    388                 "HAL:sysfs:cat %s (%lld)", mpu.accel_fsr, getTimestamp());
    389 
    390         fd = open(mpu.accel_fsr, O_RDONLY);
    391         if(fd < 0) {
    392             LOGE("HAL:Error opening accel FSR");
    393         } else {
    394            memset(buf, 0, sizeof(buf));
    395            count = read_attribute_sensor(fd, buf, sizeof(buf));
    396            if(count < 1) {
    397                LOGE("HAL:Error reading accel FSR");
    398            } else {
    399                count = sscanf(buf, "%d", &mAccelScale);
    400                if(count)
    401                    LOGV_IF(EXTRA_VERBOSE, "HAL:Accel FSR used %d", mAccelScale);
    402            }
    403            close(fd);
    404         }
    405 
    406         /* open Accel Bias fd */
    407         /* mAccelBias contains bias that will be used for dmp */
    408         memset(mAccelBias, 0, sizeof(mAccelBias));
    409         LOGV_IF(EXTRA_VERBOSE, "HAL:accel x dmp bias path: %s", mpu.in_accel_x_dmp_bias);
    410         LOGV_IF(EXTRA_VERBOSE, "HAL:accel y dmp bias path: %s", mpu.in_accel_y_dmp_bias);
    411         LOGV_IF(EXTRA_VERBOSE, "HAL:accel z dmp bias path: %s", mpu.in_accel_z_dmp_bias);
    412         accel_x_dmp_bias_fd = open(mpu.in_accel_x_dmp_bias, O_RDWR);
    413         accel_y_dmp_bias_fd = open(mpu.in_accel_y_dmp_bias, O_RDWR);
    414         accel_z_dmp_bias_fd = open(mpu.in_accel_z_dmp_bias, O_RDWR);
    415         if (accel_x_dmp_bias_fd == -1 ||
    416                  accel_y_dmp_bias_fd == -1 || accel_z_dmp_bias_fd == -1) {
    417             LOGE("HAL:could not open accel DMP calibrated bias");
    418         } else {
    419             LOGV_IF(EXTRA_VERBOSE,
    420                  "HAL:accel_dmp_bias opened");
    421         }
    422     }
    423 
    424     dmp_sign_motion_fd = open(mpu.event_smd, O_RDONLY | O_NONBLOCK);
    425     if (dmp_sign_motion_fd < 0) {
    426         LOGE("HAL:ERR couldn't open dmp_sign_motion node");
    427     } else {
    428         LOGV_IF(PROCESS_VERBOSE, "HAL:dmp_sign_motion_fd opened : %d", dmp_sign_motion_fd);
    429     }
    430 
    431     dmp_pedometer_fd = open(mpu.event_pedometer, O_RDONLY | O_NONBLOCK);
    432     if (dmp_pedometer_fd < 0) {
    433         LOGE("HAL:ERR couldn't open dmp_pedometer node");
    434     } else {
    435         LOGV_IF(PROCESS_VERBOSE, "HAL:dmp_pedometer_fd opened : %d", dmp_pedometer_fd);
    436     }
    437 
    438     initBias();
    439 
    440     (void)inv_get_version(&ver_str);
    441     LOGV_IF(PROCESS_VERBOSE, "%s\n", ver_str);
    442 
    443     /* setup MPL */
    444     inv_constructor_init();
    445 
    446 #ifdef INV_PLAYBACK_DBG
    447     LOGV_IF(PROCESS_VERBOSE, "HAL:inv_turn_on_data_logging");
    448     logfile = fopen("/data/playback.bin", "w+");
    449     if (logfile)
    450         inv_turn_on_data_logging(logfile);
    451 #endif
    452 
    453     /* setup orientation matrix and scale */
    454     inv_set_device_properties();
    455 
    456     /* initialize sensor data */
    457     memset(mPendingEvents, 0, sizeof(mPendingEvents));
    458 
    459     mPendingEvents[RotationVector].version = sizeof(sensors_event_t);
    460     mPendingEvents[RotationVector].sensor = ID_RV;
    461     mPendingEvents[RotationVector].type = SENSOR_TYPE_ROTATION_VECTOR;
    462     mPendingEvents[RotationVector].acceleration.status
    463             = SENSOR_STATUS_ACCURACY_HIGH;
    464 
    465     mPendingEvents[GameRotationVector].version = sizeof(sensors_event_t);
    466     mPendingEvents[GameRotationVector].sensor = ID_GRV;
    467     mPendingEvents[GameRotationVector].type = SENSOR_TYPE_GAME_ROTATION_VECTOR;
    468     mPendingEvents[GameRotationVector].acceleration.status
    469             = SENSOR_STATUS_ACCURACY_HIGH;
    470 
    471     mPendingEvents[LinearAccel].version = sizeof(sensors_event_t);
    472     mPendingEvents[LinearAccel].sensor = ID_LA;
    473     mPendingEvents[LinearAccel].type = SENSOR_TYPE_LINEAR_ACCELERATION;
    474     mPendingEvents[LinearAccel].acceleration.status
    475             = SENSOR_STATUS_ACCURACY_HIGH;
    476 
    477     mPendingEvents[Gravity].version = sizeof(sensors_event_t);
    478     mPendingEvents[Gravity].sensor = ID_GR;
    479     mPendingEvents[Gravity].type = SENSOR_TYPE_GRAVITY;
    480     mPendingEvents[Gravity].acceleration.status = SENSOR_STATUS_ACCURACY_HIGH;
    481 
    482     mPendingEvents[Gyro].version = sizeof(sensors_event_t);
    483     mPendingEvents[Gyro].sensor = ID_GY;
    484     mPendingEvents[Gyro].type = SENSOR_TYPE_GYROSCOPE;
    485     mPendingEvents[Gyro].gyro.status = SENSOR_STATUS_ACCURACY_HIGH;
    486 
    487     mPendingEvents[RawGyro].version = sizeof(sensors_event_t);
    488     mPendingEvents[RawGyro].sensor = ID_RG;
    489     mPendingEvents[RawGyro].type = SENSOR_TYPE_GYROSCOPE_UNCALIBRATED;
    490     mPendingEvents[RawGyro].gyro.status = SENSOR_STATUS_ACCURACY_HIGH;
    491 
    492     mPendingEvents[Accelerometer].version = sizeof(sensors_event_t);
    493     mPendingEvents[Accelerometer].sensor = ID_A;
    494     mPendingEvents[Accelerometer].type = SENSOR_TYPE_ACCELEROMETER;
    495     mPendingEvents[Accelerometer].acceleration.status
    496             = SENSOR_STATUS_ACCURACY_HIGH;
    497 
    498     /* Invensense compass calibration */
    499     mPendingEvents[MagneticField].version = sizeof(sensors_event_t);
    500     mPendingEvents[MagneticField].sensor = ID_M;
    501     mPendingEvents[MagneticField].type = SENSOR_TYPE_MAGNETIC_FIELD;
    502     mPendingEvents[MagneticField].magnetic.status =
    503         SENSOR_STATUS_ACCURACY_HIGH;
    504 
    505     mPendingEvents[RawMagneticField].version = sizeof(sensors_event_t);
    506     mPendingEvents[RawMagneticField].sensor = ID_RM;
    507     mPendingEvents[RawMagneticField].type = SENSOR_TYPE_MAGNETIC_FIELD_UNCALIBRATED;
    508     mPendingEvents[RawMagneticField].magnetic.status =
    509         SENSOR_STATUS_ACCURACY_HIGH;
    510 
    511     mPendingEvents[Pressure].version = sizeof(sensors_event_t);
    512     mPendingEvents[Pressure].sensor = ID_PS;
    513     mPendingEvents[Pressure].type = SENSOR_TYPE_MAGNETIC_FIELD_UNCALIBRATED;
    514     mPendingEvents[Pressure].magnetic.status =
    515         SENSOR_STATUS_ACCURACY_HIGH;
    516 
    517     mPendingEvents[Orientation].version = sizeof(sensors_event_t);
    518     mPendingEvents[Orientation].sensor = ID_O;
    519     mPendingEvents[Orientation].type = SENSOR_TYPE_ORIENTATION;
    520     mPendingEvents[Orientation].orientation.status
    521             = SENSOR_STATUS_ACCURACY_HIGH;
    522 
    523     mPendingEvents[GeomagneticRotationVector].version = sizeof(sensors_event_t);
    524     mPendingEvents[GeomagneticRotationVector].sensor = ID_GMRV;
    525     mPendingEvents[GeomagneticRotationVector].type
    526             = SENSOR_TYPE_GEOMAGNETIC_ROTATION_VECTOR;
    527     mPendingEvents[GeomagneticRotationVector].acceleration.status
    528             = SENSOR_STATUS_ACCURACY_HIGH;
    529 
    530 #ifndef KLP
    531     mHandlers[RotationVector] = &MPLSensor::rvHandler;
    532 #else
    533     mHandlers[RotationVector] = &MPLSensor::grvHandler;
    534 #endif
    535     mHandlers[GameRotationVector] = &MPLSensor::grvHandler;
    536     mHandlers[LinearAccel] = &MPLSensor::laHandler;
    537     mHandlers[Gravity] = &MPLSensor::gravHandler;
    538 #ifndef KLP
    539     mHandlers[Gyro] = &MPLSensor::gyroHandler;
    540 #else
    541     mHandlers[Gyro] = &MPLSensor::rawGyroHandler;
    542 #endif
    543     mHandlers[RawGyro] = &MPLSensor::rawGyroHandler;
    544     mHandlers[Accelerometer] = &MPLSensor::accelHandler;
    545 #ifndef KLP
    546     mHandlers[MagneticField] = &MPLSensor::compassHandler;
    547 #else
    548     mHandlers[MagneticField] = &MPLSensor::rawCompassHandler;
    549 #endif
    550     mHandlers[RawMagneticField] = &MPLSensor::rawCompassHandler;
    551     mHandlers[Orientation] = &MPLSensor::orienHandler;
    552     mHandlers[GeomagneticRotationVector] = &MPLSensor::gmHandler;
    553     mHandlers[Pressure] = &MPLSensor::psHandler;
    554 
    555     for (int i = 0; i < NumSensors; i++) {
    556         mDelays[i] = 1000000000LL;
    557         mBatchDelays[i] = 1000000000LL;
    558         mBatchTimeouts[i] = 30000000000LL;
    559     }
    560 
    561     /* initialize Compass Bias */
    562     memset(mCompassBias, 0, sizeof(mCompassBias));
    563 
    564     /* initialize Factory Accel Bias */
    565     memset(mFactoryAccelBias, 0, sizeof(mFactoryAccelBias));
    566 
    567     /* initialize Gyro Bias */
    568     memset(mGyroBias, 0, sizeof(mGyroBias));
    569     memset(mGyroChipBias, 0, sizeof(mGyroChipBias));
    570 
    571     /* load calibration file from /data/inv_cal_data.bin */
    572     rv = inv_load_calibration();
    573     if(rv == INV_SUCCESS) {
    574         LOGV_IF(PROCESS_VERBOSE, "HAL:Calibration file successfully loaded");
    575         /* Get initial values */
    576         getCompassBias();
    577         getGyroBias();
    578         getAccelBias();
    579         getFactoryGyroBias();
    580         if (mFactoryGyroBiasAvailable) {
    581             setFactoryGyroBias();
    582         }
    583         /* disabled because no request for factory cal accel data yet */
    584         //getFactoryAccelBias();
    585     }
    586     else
    587         LOGE("HAL:Could not open or load MPL calibration file (%d)", rv);
    588 
    589     /* takes external accel calibration load workflow */
    590     if( m_pt2AccelCalLoadFunc != NULL) {
    591         long accel_offset[3];
    592         long tmp_offset[3];
    593         int result = m_pt2AccelCalLoadFunc(accel_offset);
    594         if(result)
    595             LOGW("HAL:Vendor accelerometer calibration file load failed %d\n",
    596                  result);
    597         else {
    598             LOGW("HAL:Vendor accelerometer calibration file successfully "
    599                  "loaded");
    600             inv_get_accel_bias(tmp_offset, NULL);
    601             LOGV_IF(PROCESS_VERBOSE,
    602                     "HAL:Original accel offset, %ld, %ld, %ld\n",
    603                tmp_offset[0], tmp_offset[1], tmp_offset[2]);
    604             inv_set_accel_bias(accel_offset, mAccelAccuracy);
    605             inv_get_accel_bias(tmp_offset, NULL);
    606             LOGV_IF(PROCESS_VERBOSE, "HAL:Set accel offset, %ld, %ld, %ld\n",
    607                tmp_offset[0], tmp_offset[1], tmp_offset[2]);
    608         }
    609     }
    610     /* end of external accel calibration load workflow */
    611 
    612     /* disable driver master enable the first sensor goes on */
    613     masterEnable(0);
    614     enableGyro(0);
    615     enableAccel(0);
    616     enableCompass(0,0);
    617     enablePressure(0);
    618     enableBatch(0);
    619 
    620     if (isLowPowerQuatEnabled()) {
    621         enableLPQuaternion(0);
    622     }
    623 
    624     if (isDmpDisplayOrientationOn()) {
    625         // open DMP Orient Fd
    626         openDmpOrientFd();
    627         enableDmpOrientation(!isDmpScreenAutoRotationEnabled());
    628     }
    629 }
    630 
    631 void MPLSensor::enable_iio_sysfs(void)
    632 {
    633     VFUNC_LOG;
    634 
    635     char iio_device_node[MAX_CHIP_ID_LEN];
    636     FILE *tempFp = NULL;
    637 
    638     LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo 1 > %s (%lld)",
    639             mpu.in_timestamp_en, getTimestamp());
    640     // Either fopen()/open() are okay for sysfs access
    641     // developers could choose what they want
    642     // with fopen(), the benefit is that fprintf()/fscanf() are available
    643     tempFp = fopen(mpu.in_timestamp_en, "w");
    644     if (tempFp == NULL) {
    645         LOGE("HAL:could not open timestamp enable");
    646     } else {
    647         if(fprintf(tempFp, "%d", 1) < 0 || fclose(tempFp) < 0) {
    648             LOGE("HAL:could not enable timestamp");
    649         }
    650     }
    651 
    652     LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)",
    653             IIO_BUFFER_LENGTH, mpu.buffer_length, getTimestamp());
    654     tempFp = fopen(mpu.buffer_length, "w");
    655     if (tempFp == NULL) {
    656         LOGE("HAL:could not open buffer length");
    657     } else {
    658         if (fprintf(tempFp, "%d", IIO_BUFFER_LENGTH) < 0 || fclose(tempFp) < 0) {
    659             LOGE("HAL:could not write buffer length");
    660         }
    661     }
    662 
    663     inv_get_iio_device_node(iio_device_node);
    664     iio_fd = open(iio_device_node, O_RDONLY);
    665     if (iio_fd < 0) {
    666         LOGE("HAL:could not open iio device node");
    667     } else {
    668         LOGV_IF(PROCESS_VERBOSE, "HAL:iio iio_fd opened : %d", iio_fd);
    669     }
    670 }
    671 
    672 int MPLSensor::inv_constructor_init(void)
    673 {
    674     VFUNC_LOG;
    675 
    676     inv_error_t result = inv_init_mpl();
    677     if (result) {
    678         LOGE("HAL:inv_init_mpl() failed");
    679         return result;
    680     }
    681     result = inv_constructor_default_enable();
    682     result = inv_start_mpl();
    683     if (result) {
    684         LOGE("HAL:inv_start_mpl() failed");
    685         LOG_RESULT_LOCATION(result);
    686         return result;
    687     }
    688 
    689     return result;
    690 }
    691 
    692 int MPLSensor::inv_constructor_default_enable(void)
    693 {
    694     VFUNC_LOG;
    695 
    696     inv_error_t result;
    697 
    698 /*******************************************************************************
    699 
    700 ********************************************************************************
    701 
    702 The InvenSense binary file (libmplmpu.so) is subject to Google's standard terms
    703 and conditions as accepted in the click-through agreement required to download
    704 this library.
    705 The library includes, but is not limited to the following function calls:
    706 inv_enable_quaternion().
    707 
    708 ANY VIOLATION OF SUCH TERMS AND CONDITIONS WILL BE STRICTLY ENFORCED.
    709 
    710 ********************************************************************************
    711 
    712 *******************************************************************************/
    713 
    714     result = inv_enable_quaternion();
    715     if (result) {
    716         LOGE("HAL:Cannot enable quaternion\n");
    717         return result;
    718     }
    719 
    720     result = inv_enable_in_use_auto_calibration();
    721     if (result) {
    722         return result;
    723     }
    724 
    725     result = inv_enable_fast_nomot();
    726     if (result) {
    727         return result;
    728     }
    729 
    730     result = inv_enable_gyro_tc();
    731     if (result) {
    732         return result;
    733     }
    734 
    735     result = inv_enable_hal_outputs();
    736     if (result) {
    737         return result;
    738     }
    739 
    740     if (!mCompassSensor->providesCalibration()) {
    741         /* Invensense compass calibration */
    742         LOGV_IF(PROCESS_VERBOSE, "HAL:Invensense vector compass cal enabled");
    743         result = inv_enable_vector_compass_cal();
    744         if (result) {
    745             LOG_RESULT_LOCATION(result);
    746             return result;
    747         } else {
    748             mMplFeatureActiveMask |= INV_COMPASS_CAL;
    749         }
    750         // specify MPL's trust weight, used by compass algorithms
    751         inv_vector_compass_cal_sensitivity(3);
    752 
    753         /* disabled by default
    754         result = inv_enable_compass_bias_w_gyro();
    755         if (result) {
    756             LOG_RESULT_LOCATION(result);
    757             return result;
    758         }
    759         */
    760 
    761         result = inv_enable_heading_from_gyro();
    762         if (result) {
    763             LOG_RESULT_LOCATION(result);
    764             return result;
    765         }
    766 
    767         result = inv_enable_magnetic_disturbance();
    768         if (result) {
    769             LOG_RESULT_LOCATION(result);
    770             return result;
    771         }
    772         //inv_enable_magnetic_disturbance_logging();
    773     }
    774 
    775     result = inv_enable_9x_sensor_fusion();
    776     if (result) {
    777         LOG_RESULT_LOCATION(result);
    778         return result;
    779     } else {
    780         // 9x sensor fusion enables Compass fit
    781         mMplFeatureActiveMask |= INV_COMPASS_FIT;
    782     }
    783 
    784     result = inv_enable_no_gyro_fusion();
    785     if (result) {
    786         LOG_RESULT_LOCATION(result);
    787         return result;
    788     }
    789 
    790     return result;
    791 }
    792 
    793 /* TODO: create function pointers to calculate scale */
    794 void MPLSensor::inv_set_device_properties(void)
    795 {
    796     VFUNC_LOG;
    797 
    798     unsigned short orient;
    799 
    800     inv_get_sensors_orientation();
    801 
    802     inv_set_gyro_sample_rate(DEFAULT_MPL_GYRO_RATE);
    803     inv_set_compass_sample_rate(DEFAULT_MPL_COMPASS_RATE);
    804 
    805     /* gyro setup */
    806     orient = inv_orientation_matrix_to_scalar(mGyroOrientation);
    807     inv_set_gyro_orientation_and_scale(orient, mGyroScale << 15);
    808     LOGI_IF(EXTRA_VERBOSE, "HAL: Set MPL Gyro Scale %ld", mGyroScale << 15);
    809 
    810     /* accel setup */
    811     orient = inv_orientation_matrix_to_scalar(mAccelOrientation);
    812     /* use for third party accel input subsystem driver
    813     inv_set_accel_orientation_and_scale(orient, 1LL << 22);
    814     */
    815     inv_set_accel_orientation_and_scale(orient, (long)mAccelScale << 15);
    816     LOGI_IF(EXTRA_VERBOSE,
    817             "HAL: Set MPL Accel Scale %ld", (long)mAccelScale << 15);
    818 
    819     /* compass setup */
    820     signed char orientMtx[9];
    821     mCompassSensor->getOrientationMatrix(orientMtx);
    822     orient =
    823         inv_orientation_matrix_to_scalar(orientMtx);
    824     long sensitivity;
    825     sensitivity = mCompassSensor->getSensitivity();
    826     inv_set_compass_orientation_and_scale(orient, sensitivity);
    827     mCompassScale = sensitivity;
    828     LOGI_IF(EXTRA_VERBOSE,
    829             "HAL: Set MPL Compass Scale %ld", mCompassScale);
    830 }
    831 
    832 void MPLSensor::loadDMP(void)
    833 {
    834     int res, fd;
    835     FILE *fptr;
    836 
    837     if (isMpuNonDmp()) {
    838         //DMP support only for MPU6xxx/9xxx currently
    839         return;
    840     }
    841 
    842     /* load DMP firmware */
    843     LOGV_IF(SYSFS_VERBOSE,
    844             "HAL:sysfs:cat %s (%lld)", mpu.firmware_loaded, getTimestamp());
    845     fd = open(mpu.firmware_loaded, O_RDONLY);
    846     if(fd < 0) {
    847         LOGE("HAL:could not open dmp state");
    848     } else {
    849         if(inv_read_dmp_state(fd) == 0) {
    850             LOGV_IF(EXTRA_VERBOSE, "HAL:load dmp: %s", mpu.dmp_firmware);
    851             fptr = fopen(mpu.dmp_firmware, "w");
    852             if(fptr == NULL) {
    853                 LOGE("HAL:could not write to dmp");
    854             } else {
    855                 if (inv_load_dmp(fptr) < 0 || fclose(fptr) < 0) {
    856                     LOGE("HAL:load DMP failed");
    857                 } else {
    858                     fclose(fptr);
    859                     LOGV_IF(PROCESS_VERBOSE, "HAL:DMP loaded");
    860                 };
    861             }
    862         } else {
    863             LOGV_IF(PROCESS_VERBOSE, "HAL:DMP is already loaded");
    864         }
    865     }
    866 
    867     // onDmp(1);    //Can't enable here. See note onDmp()
    868 }
    869 
    870 void MPLSensor::inv_get_sensors_orientation(void)
    871 {
    872     FILE *fptr;
    873 
    874     // get gyro orientation
    875     LOGV_IF(SYSFS_VERBOSE,
    876             "HAL:sysfs:cat %s (%lld)", mpu.gyro_orient, getTimestamp());
    877     fptr = fopen(mpu.gyro_orient, "r");
    878     if (fptr != NULL) {
    879         int om[9];
    880         fscanf(fptr, "%d,%d,%d,%d,%d,%d,%d,%d,%d",
    881                &om[0], &om[1], &om[2], &om[3], &om[4], &om[5],
    882                &om[6], &om[7], &om[8]);
    883         fclose(fptr);
    884 
    885         LOGV_IF(EXTRA_VERBOSE,
    886                 "HAL:gyro mounting matrix: "
    887                 "%+d %+d %+d %+d %+d %+d %+d %+d %+d",
    888                 om[0], om[1], om[2], om[3], om[4], om[5], om[6], om[7], om[8]);
    889 
    890         mGyroOrientation[0] = om[0];
    891         mGyroOrientation[1] = om[1];
    892         mGyroOrientation[2] = om[2];
    893         mGyroOrientation[3] = om[3];
    894         mGyroOrientation[4] = om[4];
    895         mGyroOrientation[5] = om[5];
    896         mGyroOrientation[6] = om[6];
    897         mGyroOrientation[7] = om[7];
    898         mGyroOrientation[8] = om[8];
    899     } else {
    900         LOGE("HAL:Couldn't read gyro mounting matrix");
    901     }
    902 
    903     // get accel orientation
    904     LOGV_IF(SYSFS_VERBOSE,
    905             "HAL:sysfs:cat %s (%lld)", mpu.accel_orient, getTimestamp());
    906     fptr = fopen(mpu.accel_orient, "r");
    907     if (fptr != NULL) {
    908         int om[9];
    909         fscanf(fptr, "%d,%d,%d,%d,%d,%d,%d,%d,%d",
    910                &om[0], &om[1], &om[2], &om[3], &om[4], &om[5],
    911                &om[6], &om[7], &om[8]);
    912         fclose(fptr);
    913 
    914         LOGV_IF(EXTRA_VERBOSE,
    915                 "HAL:accel mounting matrix: "
    916                 "%+d %+d %+d %+d %+d %+d %+d %+d %+d",
    917                 om[0], om[1], om[2], om[3], om[4], om[5], om[6], om[7], om[8]);
    918 
    919         mAccelOrientation[0] = om[0];
    920         mAccelOrientation[1] = om[1];
    921         mAccelOrientation[2] = om[2];
    922         mAccelOrientation[3] = om[3];
    923         mAccelOrientation[4] = om[4];
    924         mAccelOrientation[5] = om[5];
    925         mAccelOrientation[6] = om[6];
    926         mAccelOrientation[7] = om[7];
    927         mAccelOrientation[8] = om[8];
    928     } else {
    929         LOGE("HAL:Couldn't read accel mounting matrix");
    930     }
    931 }
    932 
    933 MPLSensor::~MPLSensor()
    934 {
    935     VFUNC_LOG;
    936 
    937     /* Close open fds */
    938     if (iio_fd > 0)
    939         close(iio_fd);
    940     if( accel_fd > 0 )
    941         close(accel_fd );
    942     if (gyro_temperature_fd > 0)
    943         close(gyro_temperature_fd);
    944     if (sysfs_names_ptr)
    945         free(sysfs_names_ptr);
    946 
    947     closeDmpOrientFd();
    948 
    949     if (accel_x_dmp_bias_fd > 0) {
    950         close(accel_x_dmp_bias_fd);
    951     }
    952     if (accel_y_dmp_bias_fd > 0) {
    953         close(accel_y_dmp_bias_fd);
    954     }
    955     if (accel_z_dmp_bias_fd > 0) {
    956         close(accel_z_dmp_bias_fd);
    957     }
    958 
    959     if (gyro_x_dmp_bias_fd > 0) {
    960         close(gyro_x_dmp_bias_fd);
    961     }
    962     if (gyro_y_dmp_bias_fd > 0) {
    963         close(gyro_y_dmp_bias_fd);
    964     }
    965     if (gyro_z_dmp_bias_fd > 0) {
    966         close(gyro_z_dmp_bias_fd);
    967     }
    968 
    969     if (gyro_x_offset_fd > 0) {
    970         close(gyro_x_dmp_bias_fd);
    971     }
    972     if (gyro_y_offset_fd > 0) {
    973         close(gyro_y_offset_fd);
    974     }
    975     if (gyro_z_offset_fd > 0) {
    976         close(accel_z_offset_fd);
    977     }
    978 
    979     /* Turn off Gyro master enable          */
    980     /* A workaround until driver handles it */
    981     /* TODO: Turn off and close all sensors */
    982     LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)",
    983             0, mpu.chip_enable, getTimestamp());
    984     write_sysfs_int(mpu.chip_enable, 0);
    985 
    986 #ifdef INV_PLAYBACK_DBG
    987     inv_turn_off_data_logging();
    988     fclose(logfile);
    989 #endif
    990 }
    991 
    992 #define GY_ENABLED  ((1 << ID_GY) & enabled_sensors)
    993 #define RGY_ENABLED ((1 << ID_RG) & enabled_sensors)
    994 #define A_ENABLED   ((1 << ID_A)  & enabled_sensors)
    995 #define M_ENABLED   ((1 << ID_M) & enabled_sensors)
    996 #define RM_ENABLED  ((1 << ID_RM) & enabled_sensors)
    997 #define PS_ENABLED  ((1 << ID_PS) & enabled_sensors)
    998 #define O_ENABLED   ((1 << ID_O)  & enabled_sensors)
    999 #define LA_ENABLED  ((1 << ID_LA) & enabled_sensors)
   1000 #define GR_ENABLED  ((1 << ID_GR) & enabled_sensors)
   1001 #define RV_ENABLED  ((1 << ID_RV) & enabled_sensors)
   1002 #define GRV_ENABLED ((1 << ID_GRV) & enabled_sensors)
   1003 #define GMRV_ENABLED ((1 << ID_GMRV) & enabled_sensors)
   1004 
   1005 /* TODO: this step is optional, remove?  */
   1006 int MPLSensor::setGyroInitialState(void)
   1007 {
   1008     VFUNC_LOG;
   1009 
   1010     int res = 0;
   1011 
   1012     LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)",
   1013             HW_GYRO_RATE_HZ, mpu.gyro_rate, getTimestamp());
   1014     int fd = open(mpu.gyro_rate, O_RDWR);
   1015     res = errno;
   1016     if(fd < 0) {
   1017         LOGE("HAL:open of %s failed with '%s' (%d)",
   1018              mpu.gyro_rate, strerror(res), res);
   1019         return res;
   1020     }
   1021     res = write_attribute_sensor(fd, HW_GYRO_RATE_HZ);
   1022     if(res < 0) {
   1023         LOGE("HAL:write_attribute_sensor : error writing %s with %d",
   1024              mpu.gyro_rate, HW_GYRO_RATE_HZ);
   1025         return res;
   1026     }
   1027 
   1028     // Setting LPF is deprecated
   1029 
   1030     return 0;
   1031 }
   1032 
   1033 /* this applies to BMA250 Input Subsystem Driver only */
   1034 int MPLSensor::setAccelInitialState()
   1035 {
   1036     VFUNC_LOG;
   1037 
   1038     struct input_absinfo absinfo_x;
   1039     struct input_absinfo absinfo_y;
   1040     struct input_absinfo absinfo_z;
   1041     float value;
   1042     if (!ioctl(accel_fd, EVIOCGABS(EVENT_TYPE_ACCEL_X), &absinfo_x) &&
   1043         !ioctl(accel_fd, EVIOCGABS(EVENT_TYPE_ACCEL_Y), &absinfo_y) &&
   1044         !ioctl(accel_fd, EVIOCGABS(EVENT_TYPE_ACCEL_Z), &absinfo_z)) {
   1045         value = absinfo_x.value;
   1046         mPendingEvents[Accelerometer].data[0] = value * CONVERT_A_X;
   1047         value = absinfo_y.value;
   1048         mPendingEvents[Accelerometer].data[1] = value * CONVERT_A_Y;
   1049         value = absinfo_z.value;
   1050         mPendingEvents[Accelerometer].data[2] = value * CONVERT_A_Z;
   1051         //mHasPendingEvent = true;
   1052     }
   1053     return 0;
   1054 }
   1055 
   1056 int MPLSensor::onDmp(int en)
   1057 {
   1058     VFUNC_LOG;
   1059 
   1060     int res = -1;
   1061     int status;
   1062     mDmpOn = en;
   1063 
   1064     //Sequence to enable DMP
   1065     //1. Load DMP image if not already loaded
   1066     //2. Either Gyro or Accel must be enabled/configured before next step
   1067     //3. Enable DMP
   1068 
   1069     LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:cat %s (%lld)",
   1070             mpu.firmware_loaded, getTimestamp());
   1071     if(read_sysfs_int(mpu.firmware_loaded, &status) < 0){
   1072         LOGE("HAL:ERR can't get firmware_loaded status");
   1073     } else if (status == 1) {
   1074         //Write only if curr DMP state <> request
   1075         LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:cat %s (%lld)",
   1076                 mpu.dmp_on, getTimestamp());
   1077         if (read_sysfs_int(mpu.dmp_on, &status) < 0) {
   1078             LOGE("HAL:ERR can't read DMP state");
   1079         } else if (status != en) {
   1080             LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)",
   1081                     en, mpu.dmp_on, getTimestamp());
   1082             if (write_sysfs_int(mpu.dmp_on, en) < 0) {
   1083                 LOGE("HAL:ERR can't write dmp_on");
   1084             } else {
   1085                 mDmpOn = en;
   1086                 res = 0;	//Indicate write successful
   1087                 if(!en) {
   1088                     setAccelBias();
   1089                 }
   1090             }
   1091             //Enable DMP interrupt
   1092             LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)",
   1093                     en, mpu.dmp_int_on, getTimestamp());
   1094             if (write_sysfs_int(mpu.dmp_int_on, en) < 0) {
   1095                 LOGE("HAL:ERR can't en/dis DMP interrupt");
   1096             }
   1097 
   1098             // disable DMP event interrupt if needed
   1099             if (!en) {
   1100                 LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)",
   1101                         en, mpu.dmp_event_int_on, getTimestamp());
   1102                 if (write_sysfs_int(mpu.dmp_event_int_on, en) < 0) {
   1103                     res = -1;
   1104                     LOGE("HAL:ERR can't enable DMP event interrupt");
   1105                 }
   1106             }
   1107         } else {
   1108             mDmpOn = en;
   1109             res = 0;  	//DMP already set as requested
   1110             if(!en) {
   1111                 setAccelBias();
   1112             }
   1113         }
   1114     } else {
   1115         LOGE("HAL:ERR No DMP image");
   1116     }
   1117     return res;
   1118 }
   1119 
   1120 /* called when batch and hw sensor enabled*/
   1121 int MPLSensor::enablePedIndicator(int en)
   1122 {
   1123     VFUNC_LOG;
   1124 
   1125     int res = 0;
   1126     if (en) {
   1127         if (!(mFeatureActiveMask & INV_DMP_PED_QUATERNION)) {
   1128             //Disable DMP Pedometer Interrupt
   1129             LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)",
   1130                         0, mpu.pedometer_int_on, getTimestamp());
   1131             if (write_sysfs_int(mpu.pedometer_int_on, 0) < 0) {
   1132                LOGE("HAL:ERR can't enable Android Pedometer Interrupt");
   1133                res = -1;   // indicate an err
   1134                return res;
   1135             }
   1136         }
   1137     }
   1138 
   1139     LOGV_IF(PROCESS_VERBOSE, "HAL:Toggling step indicator to %d", en);
   1140     LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)",
   1141                 en, mpu.step_indicator_on, getTimestamp());
   1142     if (write_sysfs_int(mpu.step_indicator_on, en) < 0) {
   1143         res = -1;
   1144         LOGE("HAL:ERR can't write to DMP step_indicator_on");
   1145     }
   1146     return res;
   1147 }
   1148 
   1149 int MPLSensor::checkPedStandaloneEnabled(void)
   1150 {
   1151     return ((mFeatureActiveMask & INV_DMP_PED_STANDALONE)? 1:0);
   1152 
   1153 }
   1154 
   1155 /* This feature is only used in batch mode */
   1156 /* Stand-alone Step Detector */
   1157 int MPLSensor::enablePedStandalone(int en)
   1158 {
   1159     VFUNC_LOG;
   1160 
   1161     if (!en) {
   1162         enablePedStandaloneData(0);
   1163         mFeatureActiveMask &= ~INV_DMP_PED_STANDALONE;
   1164         if (mFeatureActiveMask == 0) {
   1165             onDmp(0);
   1166         } else if(mFeatureActiveMask & INV_DMP_PEDOMETER) {
   1167              //Re-enable DMP Pedometer Interrupt
   1168              LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)",
   1169                      1, mpu.pedometer_int_on, getTimestamp());
   1170              if (write_sysfs_int(mpu.pedometer_int_on, 1) < 0) {
   1171                  LOGE("HAL:ERR can't enable Android Pedometer Interrupt");
   1172                  return (-1);
   1173              }
   1174             //Disable data interrupt if no continuous data
   1175             if (mEnabled == 0) {
   1176                 LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)",
   1177                        1, mpu.dmp_event_int_on, getTimestamp());
   1178                 if (write_sysfs_int(mpu.dmp_event_int_on, 1) < 0) {
   1179                     LOGE("HAL:ERR can't enable DMP event interrupt");
   1180                     return (-1);
   1181                 }
   1182             }
   1183         }
   1184         LOGV_IF(PROCESS_VERBOSE, "HAL:Ped Standalone disabled");
   1185     } else {
   1186         if (enablePedStandaloneData(1) < 0 || onDmp(1) < 0) {
   1187             LOGE("HAL:ERR can't enable Ped Standalone");
   1188         } else {
   1189             mFeatureActiveMask |= INV_DMP_PED_STANDALONE;
   1190             //Disable DMP Pedometer Interrupt
   1191             LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)",
   1192                     0, mpu.pedometer_int_on, getTimestamp());
   1193             if (write_sysfs_int(mpu.pedometer_int_on, 0) < 0) {
   1194                 LOGE("HAL:ERR can't disable Android Pedometer Interrupt");
   1195                 return (-1);
   1196             }
   1197             //Enable Data Interrupt
   1198             LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)",
   1199                        0, mpu.dmp_event_int_on, getTimestamp());
   1200             if (write_sysfs_int(mpu.dmp_event_int_on, 0) < 0) {
   1201                 LOGE("HAL:ERR can't enable DMP event interrupt");
   1202                 return (-1);
   1203             }
   1204             LOGV_IF(PROCESS_VERBOSE, "HAL:Ped Standalone enabled");
   1205         }
   1206     }
   1207     return 0;
   1208 }
   1209 
   1210 int MPLSensor:: enablePedStandaloneData(int en)
   1211 {
   1212     VFUNC_LOG;
   1213 
   1214     int res = 0;
   1215 
   1216     // Enable DMP Ped standalone
   1217     LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)",
   1218             en, mpu.step_detector_on, getTimestamp());
   1219     if (write_sysfs_int(mpu.step_detector_on, en) < 0) {
   1220         LOGE("HAL:ERR can't write DMP step_detector_on");
   1221         res = -1;   //Indicate an err
   1222     }
   1223 
   1224     // Disable DMP Step indicator
   1225     LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)",
   1226             en, mpu.step_indicator_on, getTimestamp());
   1227     if (write_sysfs_int(mpu.step_indicator_on, en) < 0) {
   1228         LOGE("HAL:ERR can't write DMP step_indicator_on");
   1229         res = -1;   //Indicate an err
   1230     }
   1231 
   1232     if (!en) {
   1233       LOGV_IF(PROCESS_VERBOSE, "HAL:Disabling ped standalone");
   1234       //Disable Accel if no sensor needs it
   1235       if (!(mFeatureActiveMask & DMP_FEATURE_MASK)
   1236                                && (!(mLocalSensorMask & mMasterSensorMask
   1237                                                    & INV_THREE_AXIS_ACCEL))) {
   1238           res = enableAccel(0);
   1239           if (res < 0)
   1240               return res;
   1241       }
   1242       if (!(mFeatureActiveMask & DMP_FEATURE_MASK)
   1243                                && (!(mLocalSensorMask & mMasterSensorMask
   1244                                                    & INV_THREE_AXIS_GYRO))) {
   1245           res = enableGyro(0);
   1246           if (res < 0)
   1247               return res;
   1248       }
   1249     } else {
   1250         LOGV_IF(PROCESS_VERBOSE, "HAL:Enabling ped standalone");
   1251         // enable accel engine
   1252         res = enableAccel(1);
   1253         if (res < 0)
   1254             return res;
   1255         LOGV_IF(EXTRA_VERBOSE, "mLocalSensorMask=0x%lx", mLocalSensorMask);
   1256         // disable accel FIFO
   1257         if (!((mLocalSensorMask & mMasterSensorMask) & INV_THREE_AXIS_ACCEL)) {
   1258             res = turnOffAccelFifo();
   1259             if (res < 0)
   1260                 return res;
   1261         }
   1262     }
   1263 
   1264     return res;
   1265 }
   1266 
   1267 int MPLSensor::checkPedQuatEnabled(void)
   1268 {
   1269     return ((mFeatureActiveMask & INV_DMP_PED_QUATERNION)? 1:0);
   1270 }
   1271 
   1272 /* This feature is only used in batch mode */
   1273 /* Step Detector && Game Rotation Vector */
   1274 int MPLSensor::enablePedQuaternion(int en)
   1275 {
   1276     VFUNC_LOG;
   1277 
   1278     if (!en) {
   1279         enablePedQuaternionData(0);
   1280         mFeatureActiveMask &= ~INV_DMP_PED_QUATERNION;
   1281         if (mFeatureActiveMask == 0) {
   1282             onDmp(0);
   1283         } else if(mFeatureActiveMask & INV_DMP_PEDOMETER) {
   1284              //Re-enable DMP Pedometer Interrupt
   1285              LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)",
   1286                      1, mpu.pedometer_int_on, getTimestamp());
   1287              if (write_sysfs_int(mpu.pedometer_int_on, 1) < 0) {
   1288                  LOGE("HAL:ERR can't enable Android Pedometer Interrupt");
   1289                  return (-1);
   1290              }
   1291             //Disable data interrupt if no continuous data
   1292             if (mEnabled == 0) {
   1293                 LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)",
   1294                        1, mpu.dmp_event_int_on, getTimestamp());
   1295                 if (write_sysfs_int(mpu.dmp_event_int_on, en) < 0) {
   1296                     LOGE("HAL:ERR can't enable DMP event interrupt");
   1297                     return (-1);
   1298                 }
   1299             }
   1300         }
   1301         LOGV_IF(PROCESS_VERBOSE, "HAL:Ped Quat disabled");
   1302     } else {
   1303         if (enablePedQuaternionData(1) < 0 || onDmp(1) < 0) {
   1304             LOGE("HAL:ERR can't enable Ped Quaternion");
   1305         } else {
   1306             mFeatureActiveMask |= INV_DMP_PED_QUATERNION;
   1307             //Disable DMP Pedometer Interrupt
   1308             LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)",
   1309                     0, mpu.pedometer_int_on, getTimestamp());
   1310             if (write_sysfs_int(mpu.pedometer_int_on, 0) < 0) {
   1311                 LOGE("HAL:ERR can't disable Android Pedometer Interrupt");
   1312                 return (-1);
   1313             }
   1314             //Enable Data Interrupt
   1315             LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)",
   1316                        0, mpu.dmp_event_int_on, getTimestamp());
   1317             if (write_sysfs_int(mpu.dmp_event_int_on, 0) < 0) {
   1318                 LOGE("HAL:ERR can't enable DMP event interrupt");
   1319                 return (-1);
   1320             }
   1321             LOGV_IF(PROCESS_VERBOSE, "HAL:Ped Quat enabled");
   1322         }
   1323     }
   1324     return 0;
   1325 }
   1326 
   1327 int MPLSensor::enablePedQuaternionData(int en)
   1328 {
   1329     VFUNC_LOG;
   1330 
   1331     int res = 0;
   1332 
   1333     // Enable DMP quaternion
   1334     LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)",
   1335             en, mpu.ped_q_on, getTimestamp());
   1336     if (write_sysfs_int(mpu.ped_q_on, en) < 0) {
   1337         LOGE("HAL:ERR can't write DMP ped_q_on");
   1338         res = -1;   //Indicate an err
   1339     }
   1340 
   1341     // toggle DMP step indicator
   1342     /*LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)",
   1343             en, mpu.step_indicator_on, getTimestamp());
   1344     if (write_sysfs_int(mpu.step_indicator_on, en) < 0) {
   1345         LOGE("HAL:ERR can't write DMP step_indicator_on");
   1346         res = -1;   //Indicate an err
   1347     }*/
   1348 
   1349     if (!en) {
   1350         LOGV_IF(PROCESS_VERBOSE, "HAL:Disabling ped quat");
   1351         //Disable Accel if no sensor needs it
   1352         if (!(mFeatureActiveMask & DMP_FEATURE_MASK)
   1353                                && (!(mLocalSensorMask & mMasterSensorMask
   1354                                                    & INV_THREE_AXIS_ACCEL))) {
   1355           res = enableAccel(0);
   1356           if (res < 0)
   1357               return res;
   1358         }
   1359         if (!(mFeatureActiveMask & DMP_FEATURE_MASK)
   1360                                && (!(mLocalSensorMask & mMasterSensorMask
   1361                                                    & INV_THREE_AXIS_GYRO))) {
   1362             res = enableGyro(0);
   1363             if (res < 0)
   1364                 return res;
   1365         }
   1366       if (mFeatureActiveMask & INV_DMP_QUATERNION) {
   1367             res = write_sysfs_int(mpu.gyro_fifo_enable, 1);
   1368             res += write_sysfs_int(mpu.accel_fifo_enable, 1);
   1369             if (res < 0)
   1370                 return res;
   1371       }
   1372 //LOGV("before mLocalSensorMask=0x%lx", mLocalSensorMask);
   1373       // reset global mask for buildMpuEvent()
   1374       if (mEnabled & (1 << GameRotationVector)) {
   1375           mLocalSensorMask |= INV_THREE_AXIS_GYRO;
   1376           mLocalSensorMask |= INV_THREE_AXIS_ACCEL;
   1377       } else if (mEnabled & (1 << Accelerometer)) {
   1378           mLocalSensorMask |= INV_THREE_AXIS_ACCEL;
   1379       } else if ((mEnabled & ( 1 << Gyro)) ||
   1380           (mEnabled & (1 << RawGyro))) {
   1381           mLocalSensorMask |= INV_THREE_AXIS_GYRO;
   1382       }
   1383 //LOGV("after mLocalSensorMask=0x%lx", mLocalSensorMask);
   1384     } else {
   1385         LOGV_IF(PROCESS_VERBOSE, "HAL:Enabling ped quat");
   1386         // enable accel engine
   1387         res = enableAccel(1);
   1388         if (res < 0)
   1389             return res;
   1390 
   1391         // enable gyro engine
   1392         res = enableGyro(1);
   1393         if (res < 0)
   1394             return res;
   1395         LOGV_IF(EXTRA_VERBOSE, "mLocalSensorMask=0x%lx", mLocalSensorMask);
   1396         // disable accel FIFO
   1397         if ((!((mLocalSensorMask & mMasterSensorMask) & INV_THREE_AXIS_ACCEL)) ||
   1398                 !(mBatchEnabled & (1 << Accelerometer))) {
   1399             res = turnOffAccelFifo();
   1400             if (res < 0)
   1401                 return res;
   1402             mLocalSensorMask &= ~INV_THREE_AXIS_ACCEL;
   1403         }
   1404 
   1405         // disable gyro FIFO
   1406         if ((!((mLocalSensorMask & mMasterSensorMask) & INV_THREE_AXIS_GYRO)) ||
   1407                 !((mBatchEnabled & (1 << Gyro)) || (mBatchEnabled & (1 << RawGyro)))) {
   1408             res = turnOffGyroFifo();
   1409             if (res < 0)
   1410                 return res;
   1411             mLocalSensorMask &= ~INV_THREE_AXIS_GYRO;
   1412         }
   1413     }
   1414 
   1415     return res;
   1416 }
   1417 
   1418 int MPLSensor::check6AxisQuatEnabled(void)
   1419 {
   1420     return ((mFeatureActiveMask & INV_DMP_6AXIS_QUATERNION)? 1:0);
   1421 }
   1422 
   1423 /* This is used for batch mode only */
   1424 /* GRV is batched but not along with ped */
   1425 int MPLSensor::enable6AxisQuaternion(int en)
   1426 {
   1427     VFUNC_LOG;
   1428 
   1429     if (!en) {
   1430         enable6AxisQuaternionData(0);
   1431         mFeatureActiveMask &= ~INV_DMP_6AXIS_QUATERNION;
   1432         if (mFeatureActiveMask == 0) {
   1433             onDmp(0);
   1434         }
   1435         LOGV_IF(PROCESS_VERBOSE, "HAL:6 Axis Quat disabled");
   1436     } else {
   1437         if (enable6AxisQuaternionData(1) < 0 || onDmp(1) < 0) {
   1438             LOGE("HAL:ERR can't enable 6 Axis Quaternion");
   1439         } else {
   1440             mFeatureActiveMask |= INV_DMP_6AXIS_QUATERNION;
   1441             LOGV_IF(PROCESS_VERBOSE, "HAL:6 Axis Quat enabled");
   1442         }
   1443     }
   1444     return 0;
   1445 }
   1446 
   1447 int MPLSensor::enable6AxisQuaternionData(int en)
   1448 {
   1449     int res = 0;
   1450     VFUNC_LOG;
   1451 
   1452     // Enable DMP quaternion
   1453     LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)",
   1454             en, mpu.six_axis_q_on, getTimestamp());
   1455     if (write_sysfs_int(mpu.six_axis_q_on, en) < 0) {
   1456         LOGE("HAL:ERR can't write DMP six_axis_q_on");
   1457         res = -1;   //Indicate an err
   1458     }
   1459 
   1460     if (!en) {
   1461         LOGV_IF(EXTRA_VERBOSE, "HAL:DMP six axis quaternion data was turned off");
   1462         if (!(mFeatureActiveMask & DMP_FEATURE_MASK)
   1463                                  && (!(mLocalSensorMask & mMasterSensorMask
   1464                                                      & INV_THREE_AXIS_ACCEL))) {
   1465             res = enableAccel(0);
   1466             if (res < 0)
   1467                 return res;
   1468         }
   1469         if (!(mFeatureActiveMask & DMP_FEATURE_MASK)
   1470                                  && (!(mLocalSensorMask & mMasterSensorMask
   1471                                                      & INV_THREE_AXIS_GYRO))) {
   1472             res = enableGyro(0);
   1473             if (res < 0)
   1474                 return res;
   1475         }
   1476         if (mFeatureActiveMask & INV_DMP_QUATERNION) {
   1477             LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)",
   1478                     1, mpu.gyro_fifo_enable, getTimestamp());
   1479             res = write_sysfs_int(mpu.gyro_fifo_enable, 1);
   1480             LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)",
   1481                     1, mpu.accel_fifo_enable, getTimestamp());
   1482             res += write_sysfs_int(mpu.accel_fifo_enable, 1);
   1483             if (res < 0)
   1484                 return res;
   1485         }
   1486 LOGV("before mLocalSensorMask=0x%lx", mLocalSensorMask);
   1487         // reset global mask for buildMpuEvent()
   1488         if (mEnabled & (1 << GameRotationVector)) {
   1489             if (!(mFeatureActiveMask & INV_DMP_PED_QUATERNION)) {
   1490                 mLocalSensorMask |= INV_THREE_AXIS_GYRO;
   1491                 mLocalSensorMask |= INV_THREE_AXIS_ACCEL;
   1492             }
   1493         } else if (mEnabled & (1 << Accelerometer)) {
   1494             mLocalSensorMask |= INV_THREE_AXIS_ACCEL;
   1495         } else if ((mEnabled & ( 1 << Gyro)) ||
   1496                 (mEnabled & (1 << RawGyro))) {
   1497             mLocalSensorMask |= INV_THREE_AXIS_GYRO;
   1498         }
   1499 LOGV("after mLocalSensorMask=0x%lx", mLocalSensorMask);
   1500     } else {
   1501         LOGV_IF(PROCESS_VERBOSE, "HAL:Enabling six axis quat");
   1502         if (mEnabled & ( 1 << GameRotationVector)) {
   1503             // enable accel engine
   1504             res = enableAccel(1);
   1505             if (res < 0)
   1506                 return res;
   1507 
   1508             // enable gyro engine
   1509             res = enableGyro(1);
   1510             if (res < 0)
   1511                 return res;
   1512             LOGV_IF(EXTRA_VERBOSE, "before: mLocalSensorMask=0x%lx", mLocalSensorMask);
   1513             if ((!(mLocalSensorMask & mMasterSensorMask & INV_THREE_AXIS_ACCEL)) ||
   1514                    (!(mBatchEnabled & (1 << Accelerometer)) ||
   1515                        (!(mEnabled & (1 << Accelerometer))))) {
   1516                 res = turnOffAccelFifo();
   1517                 if (res < 0)
   1518                     return res;
   1519                 mLocalSensorMask &= ~INV_THREE_AXIS_ACCEL;
   1520             }
   1521 
   1522             if ((!(mLocalSensorMask & mMasterSensorMask & INV_THREE_AXIS_GYRO)) ||
   1523                     (!(mBatchEnabled & (1 << Gyro)) ||
   1524                        (!(mEnabled & (1 << Gyro))))) {
   1525                 if (!(mBatchEnabled & (1 << RawGyro)) ||
   1526                         (!(mEnabled & (1 << RawGyro)))) {
   1527                     res = turnOffGyroFifo();
   1528                     if (res < 0)
   1529                         return res;
   1530                      mLocalSensorMask &= ~INV_THREE_AXIS_GYRO;
   1531                      }
   1532             }
   1533 LOGV("after: mLocalSensorMask=0x%lx", mLocalSensorMask);
   1534         }
   1535     }
   1536 
   1537     return res;
   1538 }
   1539 
   1540 int MPLSensor::checkLPQuaternion(void)
   1541 {
   1542     return ((mFeatureActiveMask & INV_DMP_QUATERNION)? 1:0);
   1543 }
   1544 
   1545 int MPLSensor::enableLPQuaternion(int en)
   1546 {
   1547     VFUNC_LOG;
   1548 
   1549     if (!en) {
   1550         enableQuaternionData(0);
   1551         onDmp(0);
   1552         mFeatureActiveMask &= ~INV_DMP_QUATERNION;
   1553         LOGV_IF(PROCESS_VERBOSE, "HAL:LP Quat disabled");
   1554     } else {
   1555         if (enableQuaternionData(1) < 0 || onDmp(1) < 0) {
   1556             LOGE("HAL:ERR can't enable LP Quaternion");
   1557         } else {
   1558             mFeatureActiveMask |= INV_DMP_QUATERNION;
   1559             LOGV_IF(PROCESS_VERBOSE, "HAL:LP Quat enabled");
   1560         }
   1561     }
   1562     return 0;
   1563 }
   1564 
   1565 int MPLSensor::enableQuaternionData(int en)
   1566 {
   1567     int res = 0;
   1568     VFUNC_LOG;
   1569 
   1570     // Enable DMP quaternion
   1571     LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)",
   1572             en, mpu.three_axis_q_on, getTimestamp());
   1573     if (write_sysfs_int(mpu.three_axis_q_on, en) < 0) {
   1574         LOGE("HAL:ERR can't write DMP three_axis_q__on");
   1575         res = -1;	//Indicate an err
   1576     }
   1577 
   1578     if (!en) {
   1579         LOGV_IF(EXTRA_VERBOSE, "HAL:DMP quaternion data was turned off");
   1580         inv_quaternion_sensor_was_turned_off();
   1581     } else {
   1582         LOGV_IF(PROCESS_VERBOSE, "HAL:Enabling three axis quat");
   1583     }
   1584 
   1585     return res;
   1586 }
   1587 
   1588 int MPLSensor::enableDmpPedometer(int en, int interruptMode)
   1589 {
   1590     VFUNC_LOG;
   1591     int res = 0;
   1592     int enabled_sensors = mEnabled;
   1593 
   1594     if (isMpuNonDmp())
   1595         return res;
   1596 
   1597     // reset master enable
   1598     res = masterEnable(0);
   1599     if (res < 0) {
   1600         return res;
   1601     }
   1602 
   1603     if (en == 1) {
   1604         //Enable DMP Pedometer Function
   1605         LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)",
   1606                 en, mpu.pedometer_on, getTimestamp());
   1607         if (write_sysfs_int(mpu.pedometer_on, en) < 0) {
   1608             LOGE("HAL:ERR can't enable Android Pedometer");
   1609             res = -1;   // indicate an err
   1610             return res;
   1611         }
   1612 
   1613         if (interruptMode || (mFeatureActiveMask & INV_DMP_PEDOMETER)) {
   1614             //Enable DMP Pedometer Interrupt
   1615             LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)",
   1616                     en, mpu.pedometer_int_on, getTimestamp());
   1617             if (write_sysfs_int(mpu.pedometer_int_on, en) < 0) {
   1618                 LOGE("HAL:ERR can't enable Android Pedometer Interrupt");
   1619                 res = -1;   // indicate an err
   1620                 return res;
   1621             }
   1622         }
   1623         // enable DMP
   1624         res = onDmp(1);
   1625         if (res < 0) {
   1626             return res;
   1627         }
   1628 
   1629         // set DMP rate to 200Hz
   1630         LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)",
   1631                 200, mpu.accel_fifo_rate, getTimestamp());
   1632         if (write_sysfs_int(mpu.accel_fifo_rate, 200) < 0) {
   1633             res = -1;
   1634             LOGE("HAL:ERR can't set rate to 200Hz");
   1635             return res;
   1636         }
   1637 
   1638         // enable accel engine
   1639         res = enableAccel(1);
   1640         if (res < 0) {
   1641             return res;
   1642         }
   1643 
   1644         // disable accel FIFO
   1645         if (!(mLocalSensorMask & mMasterSensorMask & INV_THREE_AXIS_ACCEL)) {
   1646             res = turnOffAccelFifo();
   1647             if (res < 0)
   1648                 return res;
   1649         }
   1650 
   1651         // disable data interrupt
   1652         //if (!batchPed && enabled_sensors == 0) {
   1653         if (enabled_sensors == 0) {
   1654             LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)",
   1655                         en, mpu.dmp_event_int_on, getTimestamp());
   1656             if (write_sysfs_int(mpu.dmp_event_int_on, en) < 0) {
   1657                 res = -1;
   1658                 LOGE("HAL:ERR can't enable DMP event interrupt");
   1659             }
   1660         }
   1661         if (interruptMode) {
   1662             mFeatureActiveMask |= INV_DMP_PEDOMETER;
   1663             /*if (batchPed) {
   1664                 LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)",
   1665                     en, mpu.step_detector_on, getTimestamp());
   1666                 if (write_sysfs_int(mpu.step_detector_on, en) < 0) {
   1667                     LOGE("HAL:ERR can't write DMP step_detector_on");
   1668                     res = -1;   //Indicate an err
   1669                 }
   1670                 mFeatureActiveMask |= INV_DMP_PED_STANDALONE;
   1671             }*/
   1672         }
   1673         else {
   1674             mFeatureActiveMask |= INV_DMP_PEDOMETER_STEP;
   1675         }
   1676 
   1677         clock_gettime(CLOCK_MONOTONIC, &mt_pre);
   1678     } else {
   1679         if (interruptMode) {
   1680             mFeatureActiveMask &= ~INV_DMP_PEDOMETER;
   1681         }
   1682         else {
   1683             mFeatureActiveMask &= ~INV_DMP_PEDOMETER_STEP;
   1684         }
   1685 
   1686         /* if neither step detector or step count is on */
   1687         if (!(mFeatureActiveMask & (INV_DMP_PEDOMETER | INV_DMP_PEDOMETER_STEP))) {
   1688             //Disable DMP Pedometer Function
   1689             LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)",
   1690                     en, mpu.pedometer_on, getTimestamp());
   1691             if (write_sysfs_int(mpu.pedometer_on, en) < 0) {
   1692                 LOGE("HAL:ERR can't enable Android Pedometer");
   1693                 res = -1;   // indicate an err
   1694                 return res;
   1695             }
   1696         }
   1697 
   1698         if (mFeatureActiveMask == 0 ) {
   1699             // disable DMP
   1700             res = onDmp(0);
   1701             if (res < 0) {
   1702                 return res;
   1703             }
   1704 
   1705              // disable accel engine
   1706              if (!(mLocalSensorMask & mMasterSensorMask
   1707                         & INV_THREE_AXIS_ACCEL)) {
   1708                 res = enableAccel(0);
   1709                 if (res < 0) {
   1710                     return res;
   1711                 }
   1712             }
   1713         }
   1714 
   1715         /* if feature is not step detector */
   1716         if (!(mFeatureActiveMask & INV_DMP_PEDOMETER)) {
   1717             //Disable DMP Pedometer Interrupt
   1718             LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)",
   1719                     en, mpu.pedometer_int_on, getTimestamp());
   1720             if (write_sysfs_int(mpu.pedometer_int_on, en) < 0) {
   1721                 LOGE("HAL:ERR can't enable Android Pedometer Interrupt");
   1722                 res = -1;   // indicate an err
   1723                 return res;
   1724             }
   1725         }
   1726 
   1727         //enable data interrupts if applicable
   1728         if (enabled_sensors) {
   1729             LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)",
   1730                         en, mpu.dmp_event_int_on, getTimestamp());
   1731             if (write_sysfs_int(mpu.dmp_event_int_on, en) < 0) {
   1732                 res = -1;
   1733                 LOGE("HAL:ERR can't enable DMP event interrupt");
   1734             }
   1735         }
   1736     }
   1737 
   1738     if(en || enabled_sensors || mFeatureActiveMask) {
   1739         res = masterEnable(1);
   1740     }
   1741     return res;
   1742 }
   1743 
   1744 int MPLSensor::masterEnable(int en)
   1745 {
   1746     VFUNC_LOG;
   1747 
   1748     int res = 0;
   1749     LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)",
   1750             en, mpu.chip_enable, getTimestamp());
   1751     res = write_sysfs_int(mpu.chip_enable, en);
   1752     return res;
   1753 }
   1754 
   1755 int MPLSensor::enableGyro(int en)
   1756 {
   1757     VFUNC_LOG;
   1758 
   1759     int res = 0;
   1760 
   1761     /* need to also turn on/off the master enable */
   1762     LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)",
   1763             en, mpu.gyro_enable, getTimestamp());
   1764     res = write_sysfs_int(mpu.gyro_enable, en);
   1765     LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)",
   1766             en, mpu.gyro_fifo_enable, getTimestamp());
   1767     res += write_sysfs_int(mpu.gyro_fifo_enable, en);
   1768 
   1769     if (!en) {
   1770         LOGV_IF(EXTRA_VERBOSE, "HAL:MPL:inv_gyro_was_turned_off");
   1771         inv_gyro_was_turned_off();
   1772     }
   1773 
   1774     return res;
   1775 }
   1776 
   1777 int MPLSensor::enableAccel(int en)
   1778 {
   1779     VFUNC_LOG;
   1780 
   1781     int res;
   1782 
   1783     /* need to also turn on/off the master enable */
   1784     LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)",
   1785             en, mpu.accel_enable, getTimestamp());
   1786     res = write_sysfs_int(mpu.accel_enable, en);
   1787     LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)",
   1788             en, mpu.accel_fifo_enable, getTimestamp());
   1789     res += write_sysfs_int(mpu.accel_fifo_enable, en);
   1790 
   1791     if (!en) {
   1792         LOGV_IF(EXTRA_VERBOSE, "HAL:MPL:inv_accel_was_turned_off");
   1793         inv_accel_was_turned_off();
   1794     }
   1795 
   1796     return res;
   1797 }
   1798 
   1799 int MPLSensor::enableCompass(int en, int rawSensorRequested)
   1800 {
   1801     VFUNC_LOG;
   1802 
   1803     int res = 0;
   1804     /* handle ID_RM if third party compass cal is used */
   1805     if (rawSensorRequested && mCompassSensor->providesCalibration()) {
   1806         res = mCompassSensor->enable(ID_RM, en);
   1807     } else {
   1808         res = mCompassSensor->enable(ID_M, en);
   1809     }
   1810     if (en == 0 || res != 0) {
   1811         LOGV_IF(EXTRA_VERBOSE, "HAL:MPL:inv_compass_was_turned_off %d", res);
   1812         inv_compass_was_turned_off();
   1813     }
   1814 
   1815     return res;
   1816 }
   1817 
   1818 int MPLSensor::enablePressure(int en)
   1819 {
   1820     VFUNC_LOG;
   1821 
   1822     int res = 0;
   1823 
   1824     if (mPressureSensor) {
   1825         res = mPressureSensor->enable(ID_PS, en);
   1826     } else {
   1827         LOGV_IF(ENG_VERBOSE, "HAL:PRESSURE sensor not detected");
   1828     }
   1829 
   1830     return res;
   1831 }
   1832 
   1833 /* use this function for initialization */
   1834 int MPLSensor::enableBatch(int64_t timeout)
   1835 {
   1836     VFUNC_LOG;
   1837 
   1838     int res = 0;
   1839 
   1840     res = write_sysfs_int(mpu.batchmode_timeout, timeout);
   1841     if (timeout == 0) {
   1842         res = write_sysfs_int(mpu.six_axis_q_on, 0);
   1843         res = write_sysfs_int(mpu.ped_q_on, 0);
   1844         res = write_sysfs_int(mpu.step_detector_on, 0);
   1845         res = write_sysfs_int(mpu.step_indicator_on, 0);
   1846     }
   1847 
   1848     if (timeout == 0) {
   1849         LOGV_IF(EXTRA_VERBOSE, "HAL:MPL:batchmode timeout is zero");
   1850     }
   1851 
   1852     return res;
   1853 }
   1854 
   1855 void MPLSensor::computeLocalSensorMask(int enabled_sensors)
   1856 {
   1857     VFUNC_LOG;
   1858 
   1859     do {
   1860         /* Invensense Pressure on secondary bus */
   1861         if (PS_ENABLED) {
   1862             LOGV_IF(ENG_VERBOSE, "PS ENABLED");
   1863             mLocalSensorMask |= INV_ONE_AXIS_PRESSURE;
   1864         } else {
   1865             LOGV_IF(ENG_VERBOSE, "PS DISABLED");
   1866             mLocalSensorMask &= ~INV_ONE_AXIS_PRESSURE;
   1867         }
   1868 
   1869         if (LA_ENABLED || GR_ENABLED || RV_ENABLED || O_ENABLED
   1870                        || (GRV_ENABLED && GMRV_ENABLED)) {
   1871             LOGV_IF(ENG_VERBOSE, "FUSION ENABLED");
   1872             mLocalSensorMask = ALL_MPL_SENSORS_NP;
   1873             break;
   1874         }
   1875 
   1876         if (GRV_ENABLED) {
   1877             if (!(mBatchEnabled & (1 << GameRotationVector))) {
   1878                 LOGV_IF(ENG_VERBOSE, "6 Axis Fusion ENABLED");
   1879                 mLocalSensorMask |= INV_THREE_AXIS_GYRO;
   1880                 mLocalSensorMask |= INV_THREE_AXIS_ACCEL;
   1881             } else {
   1882                 if (GY_ENABLED || RGY_ENABLED) {
   1883                     LOGV_IF(ENG_VERBOSE, "G ENABLED");
   1884                     mLocalSensorMask |= INV_THREE_AXIS_GYRO;
   1885                 } else {
   1886                     LOGV_IF(ENG_VERBOSE, "G DISABLED");
   1887                     mLocalSensorMask &= ~INV_THREE_AXIS_GYRO;
   1888                 }
   1889                 if (A_ENABLED) {
   1890                     LOGV_IF(ENG_VERBOSE, "A ENABLED");
   1891                     mLocalSensorMask |= INV_THREE_AXIS_ACCEL;
   1892                 } else {
   1893                     LOGV_IF(ENG_VERBOSE, "A DISABLED");
   1894                     mLocalSensorMask &= ~INV_THREE_AXIS_ACCEL;
   1895                 }
   1896             }
   1897             /* takes care of MAG case */
   1898             if (M_ENABLED || RM_ENABLED) {
   1899                 LOGV_IF(1, "M ENABLED");
   1900                 mLocalSensorMask |= INV_THREE_AXIS_COMPASS;
   1901             } else {
   1902                 LOGV_IF(1, "M DISABLED");
   1903                 mLocalSensorMask &= ~INV_THREE_AXIS_COMPASS;
   1904             }
   1905             break;
   1906         }
   1907 
   1908         if (GMRV_ENABLED) {
   1909             LOGV_IF(ENG_VERBOSE, "6 Axis Geomagnetic Fusion ENABLED");
   1910             mLocalSensorMask |= INV_THREE_AXIS_ACCEL;
   1911             mLocalSensorMask |= INV_THREE_AXIS_COMPASS;
   1912 
   1913             /* takes care of Gyro case */
   1914             if (GY_ENABLED || RGY_ENABLED) {
   1915                 LOGV_IF(1, "G ENABLED");
   1916                 mLocalSensorMask |= INV_THREE_AXIS_GYRO;
   1917             } else {
   1918                 LOGV_IF(1, "G DISABLED");
   1919                 mLocalSensorMask &= ~INV_THREE_AXIS_GYRO;
   1920             }
   1921             break;
   1922         }
   1923 
   1924         if(!A_ENABLED && !M_ENABLED && !RM_ENABLED &&
   1925                !GRV_ENABLED && !GMRV_ENABLED && !GY_ENABLED && !RGY_ENABLED &&
   1926                !PS_ENABLED) {
   1927             /* Invensense compass cal */
   1928             LOGV_IF(ENG_VERBOSE, "ALL DISABLED");
   1929             mLocalSensorMask = 0;
   1930             break;
   1931         }
   1932 
   1933         if (GY_ENABLED || RGY_ENABLED) {
   1934             LOGV_IF(ENG_VERBOSE, "G ENABLED");
   1935             mLocalSensorMask |= INV_THREE_AXIS_GYRO;
   1936         } else {
   1937             LOGV_IF(ENG_VERBOSE, "G DISABLED");
   1938             mLocalSensorMask &= ~INV_THREE_AXIS_GYRO;
   1939         }
   1940 
   1941         if (A_ENABLED) {
   1942             LOGV_IF(ENG_VERBOSE, "A ENABLED");
   1943             mLocalSensorMask |= INV_THREE_AXIS_ACCEL;
   1944         } else {
   1945             LOGV_IF(ENG_VERBOSE, "A DISABLED");
   1946             mLocalSensorMask &= ~INV_THREE_AXIS_ACCEL;
   1947         }
   1948 
   1949         /* Invensense compass calibration */
   1950         if (M_ENABLED || RM_ENABLED) {
   1951             LOGV_IF(ENG_VERBOSE, "M ENABLED");
   1952             mLocalSensorMask |= INV_THREE_AXIS_COMPASS;
   1953         } else {
   1954             LOGV_IF(ENG_VERBOSE, "M DISABLED");
   1955             mLocalSensorMask &= ~INV_THREE_AXIS_COMPASS;
   1956         }
   1957     } while (0);
   1958 }
   1959 
   1960 int MPLSensor::enableSensors(unsigned long sensors, int en, uint32_t changed)
   1961 {
   1962     VFUNC_LOG;
   1963 
   1964     inv_error_t res = -1;
   1965     int on = 1;
   1966     int off = 0;
   1967     int cal_stored = 0;
   1968 
   1969     // Sequence to enable or disable a sensor
   1970     // 1. reset master enable (=0)
   1971     // 2. enable or disable a sensor
   1972     // 3. set master enable (=1)
   1973 
   1974     if (isLowPowerQuatEnabled() ||
   1975         changed & ((1 << Gyro) | (1 << RawGyro) | (1 << Accelerometer) |
   1976         (mCompassSensor->isIntegrated() << MagneticField) |
   1977         (mCompassSensor->isIntegrated() << RawMagneticField) |
   1978         (mPressureSensor->isIntegrated() << Pressure))) {
   1979 
   1980         /* reset master enable */
   1981         res = masterEnable(0);
   1982         if(res < 0) {
   1983             return res;
   1984         }
   1985     }
   1986 
   1987     LOGV_IF(PROCESS_VERBOSE, "HAL:enableSensors - sensors: 0x%0x",
   1988             (unsigned int)sensors);
   1989 
   1990     if (changed & ((1 << Gyro) | (1 << RawGyro))) {
   1991         LOGV_IF(PROCESS_VERBOSE, "HAL:enableSensors - gyro %s",
   1992             (sensors & INV_THREE_AXIS_GYRO? "enable": "disable"));
   1993         res = enableGyro(!!(sensors & INV_THREE_AXIS_GYRO));
   1994         if(res < 0) {
   1995             return res;
   1996         }
   1997 
   1998         if (!cal_stored && (!en && (changed & (1 << Gyro)))) {
   1999             storeCalibration();
   2000             cal_stored = 1;
   2001         }
   2002     }
   2003 
   2004     if (changed & (1 << Accelerometer)) {
   2005         LOGV_IF(PROCESS_VERBOSE, "HAL:enableSensors - accel %s",
   2006             (sensors & INV_THREE_AXIS_ACCEL? "enable": "disable"));
   2007         res = enableAccel(!!(sensors & INV_THREE_AXIS_ACCEL));
   2008         if(res < 0) {
   2009             return res;
   2010         }
   2011 
   2012         if (!(sensors & INV_THREE_AXIS_ACCEL) && !cal_stored) {
   2013             storeCalibration();
   2014             cal_stored = 1;
   2015         }
   2016     }
   2017 
   2018     if (changed & ((1 << MagneticField) | (1 << RawMagneticField))) {
   2019         LOGV_IF(PROCESS_VERBOSE, "HAL:enableSensors - compass %s",
   2020             (sensors & INV_THREE_AXIS_COMPASS? "enable": "disable"));
   2021         res = enableCompass(!!(sensors & INV_THREE_AXIS_COMPASS), changed & (1 << RawMagneticField));
   2022         if(res < 0) {
   2023             return res;
   2024         }
   2025 
   2026         if (!cal_stored && (!en && (changed & (1 << MagneticField)))) {
   2027             storeCalibration();
   2028             cal_stored = 1;
   2029         }
   2030     }
   2031 
   2032      if (changed & (1 << Pressure)) {
   2033         LOGV_IF(PROCESS_VERBOSE, "HAL:enableSensors - pressure %s",
   2034             (sensors & INV_ONE_AXIS_PRESSURE? "enable": "disable"));
   2035         res = enablePressure(!!(sensors & INV_ONE_AXIS_PRESSURE));
   2036         if(res < 0) {
   2037             return res;
   2038         }
   2039     }
   2040 
   2041     if (isLowPowerQuatEnabled()) {
   2042         // Enable LP Quat
   2043         if ((mEnabled & VIRTUAL_SENSOR_9AXES_MASK)
   2044                       || (mEnabled & VIRTUAL_SENSOR_GYRO_6AXES_MASK)) {
   2045   LOGI("HAL: 9 axis or game rot enabled");
   2046             if (!(changed & ((1 << Gyro)
   2047                            | (1 << RawGyro)
   2048                            | (1 << Accelerometer)
   2049                            | (mCompassSensor->isIntegrated() << MagneticField)
   2050                            | (mCompassSensor->isIntegrated() << RawMagneticField)))
   2051             ) {
   2052                 /* reset master enable */
   2053                 res = masterEnable(0);
   2054                 if(res < 0) {
   2055                     return res;
   2056                 }
   2057             }
   2058             if (!checkLPQuaternion()) {
   2059                 enableLPQuaternion(1);
   2060             } else {
   2061                 LOGV_IF(PROCESS_VERBOSE, "HAL:LP Quat already enabled");
   2062             }
   2063         } else if (checkLPQuaternion()) {
   2064             enableLPQuaternion(0);
   2065         }
   2066     }
   2067 
   2068     /* apply accel/gyro bias to DMP bias                        */
   2069     /* precondition: masterEnable(0), mGyroBiasAvailable=true   */
   2070     /* postcondition: bias is applied upon masterEnable(1)      */
   2071     if(!(sensors & INV_THREE_AXIS_GYRO)) {
   2072         setGyroBias();
   2073     }
   2074     if(!(sensors & INV_THREE_AXIS_ACCEL)) {
   2075         setAccelBias();
   2076     }
   2077 
   2078     /* to batch or not to batch */
   2079     int batchMode = computeBatchSensorMask(mEnabled, mBatchEnabled);
   2080     setBatch(batchMode,0);
   2081 
   2082     if (changed & ((1 << Gyro) | (1 << RawGyro) | (1 << Accelerometer) |
   2083             (mCompassSensor->isIntegrated() << MagneticField) |
   2084             (mCompassSensor->isIntegrated() << RawMagneticField) |
   2085             (mPressureSensor->isIntegrated() << Pressure))) {
   2086         LOGV_IF(ENG_VERBOSE, "HAL DEBUG: Gyro, Accel, Compass, Pressure changes");
   2087         if ((checkSmdSupport() == 1) || (checkPedometerSupport() == 1) || (sensors &
   2088             (INV_THREE_AXIS_GYRO
   2089                 | INV_THREE_AXIS_ACCEL
   2090                 | (INV_THREE_AXIS_COMPASS * mCompassSensor->isIntegrated())
   2091                 | (INV_ONE_AXIS_PRESSURE * mPressureSensor->isIntegrated())))) {
   2092             LOGV_IF(ENG_VERBOSE, "SMD or Hardware sensors enabled");
   2093             LOGV_IF(ENG_VERBOSE, "mFeatureActiveMask=%016llx", mFeatureActiveMask);
   2094             if (mFeatureActiveMask & DMP_FEATURE_MASK) {
   2095                 LOGV_IF(ENG_VERBOSE, "HAL DEBUG: LPQ, SMD, SO enabled");
   2096                 // disable DMP event interrupt only (w/ data interrupt)
   2097                 LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)",
   2098                         0, mpu.dmp_event_int_on, getTimestamp());
   2099                 if (write_sysfs_int(mpu.dmp_event_int_on, 0) < 0) {
   2100                     res = -1;
   2101                     LOGE("HAL:ERR can't disable DMP event interrupt");
   2102                     return res;
   2103                 }
   2104             }
   2105 
   2106             if ((mFeatureActiveMask & DMP_FEATURE_MASK) &&
   2107                     !((mFeatureActiveMask & 0x240) ||
   2108                         (mFeatureActiveMask & 0x220) ||
   2109                         (mFeatureActiveMask & 0x280))) {
   2110 LOGI("mFeatureActiveMask=%lld", mFeatureActiveMask);
   2111                 // enable DMP
   2112                 onDmp(1);
   2113                 res = enableAccel(on);
   2114                 if(res < 0) {
   2115                     return res;
   2116                 }
   2117                 if ((sensors & INV_THREE_AXIS_ACCEL) == 0) {
   2118                     res = turnOffAccelFifo();
   2119                 }
   2120                 if(res < 0) {
   2121                     return res;
   2122                 }
   2123             }
   2124             res = masterEnable(1);
   2125             if(res < 0) {
   2126                 return res;
   2127             }
   2128         } else { // all sensors idle -> reduce power
   2129             LOGV_IF(ENG_VERBOSE, "HAL DEBUG: not SMD or Hardware sensors");
   2130             if (isDmpDisplayOrientationOn()
   2131                     && (mDmpOrientationEnabled
   2132                             || !isDmpScreenAutoRotationEnabled())) {
   2133                 enableDmpOrientation(1);
   2134             }
   2135 
   2136             if (!cal_stored) {
   2137                 storeCalibration();
   2138                 cal_stored = 1;
   2139             }
   2140         }
   2141     } else if ((changed &
   2142                     ((!mCompassSensor->isIntegrated()) << MagneticField) ||
   2143                     ((!mCompassSensor->isIntegrated()) << RawMagneticField))
   2144                     &&
   2145               !(sensors & (INV_THREE_AXIS_GYRO | INV_THREE_AXIS_ACCEL
   2146                 | (INV_THREE_AXIS_COMPASS * (!mCompassSensor->isIntegrated()))))
   2147     ) {
   2148         LOGV_IF(ENG_VERBOSE, "HAL DEBUG: Gyro, Accel, Compass no change");
   2149         if (!cal_stored) {
   2150             storeCalibration();
   2151             cal_stored = 1;
   2152         }
   2153     } else {
   2154       LOGV_IF(ENG_VERBOSE, "HAL DEBUG: mEnabled");
   2155       if (sensors &
   2156             (INV_THREE_AXIS_GYRO
   2157                 | INV_THREE_AXIS_ACCEL
   2158                 | (INV_THREE_AXIS_COMPASS * mCompassSensor->isIntegrated()))) {
   2159             res = masterEnable(1);
   2160             if(res < 0)
   2161                 return res;
   2162         }
   2163     }
   2164 
   2165     return res;
   2166 }
   2167 
   2168 /* check if batch mode should be turned on or not */
   2169 int MPLSensor::computeBatchSensorMask(int enableSensors, int tempBatchSensor)
   2170 {
   2171     VFUNC_LOG;
   2172     int batchMode = 1;
   2173 
   2174     LOGV("HAL:computeBatchSensorMask: enableSensors=%d tempBatchSensor=%d", enableSensors, tempBatchSensor);
   2175 
   2176     // check for possible continuous data mode
   2177     for(int i = 0; i <= Pressure; i++) {
   2178         if ((enableSensors & (1 << i)) && !(tempBatchSensor & (1 << i))) {
   2179             LOGV("HAL:computeBatchSensorMask: hardware sensor on continuous mode:%d", i);
   2180             // if any one of the hardware sensor is in continuous data mode
   2181             // turn off batch mode.
   2182             return 0;
   2183         }
   2184         if ((enableSensors & (1 << i)) && (tempBatchSensor & (1 << i))) {
   2185             LOGV("HAL:computeBatchSensorMask: hardware sensor is batch:%d", i);
   2186             // if hardware sensor is batched, check if virtual sensor is batched
   2187             if ((enableSensors & (1 << GameRotationVector))
   2188                             && !(tempBatchSensor & (1 << GameRotationVector))) {
   2189             LOGV("HAL:computeBatchSensorMask: but virtual sensor is not:%d", i);
   2190                 return 0;
   2191             }
   2192         }
   2193     }
   2194 
   2195     for(int i = Orientation; i <= GeomagneticRotationVector; i++) {
   2196         if ((enableSensors & (1 << i)) && !(tempBatchSensor & (1 << i))) {
   2197              LOGV("HAL:computeBatchSensorMask: composite sensor on continuous mode:%d", i);
   2198             // if composite sensors are on but not batched
   2199             // turn off batch mode.
   2200             return 0;
   2201         }
   2202     }
   2203 
   2204     LOGV_IF(EXTRA_VERBOSE, "HAL:computeBatchSensorMask: batchMode=%d, mBatchEnabled=%0x", batchMode, tempBatchSensor);
   2205     return (batchMode && tempBatchSensor);
   2206 }
   2207 
   2208 /* This function is called by enable() */
   2209 int MPLSensor::setBatch(int en, int toggleEnable)
   2210 {
   2211     VFUNC_LOG;
   2212 
   2213     int res = 0;
   2214     int64_t wanted = 1000000000LL;
   2215     int64_t timeout = 0;
   2216     int timeoutInMs = 0;
   2217     int featureMask = computeBatchDataOutput();
   2218 
   2219     // reset master enable
   2220     res = masterEnable(0);
   2221     if (res < 0) {
   2222         return res;
   2223     }
   2224 
   2225     if (en) {
   2226         /* take the minimum batchmode timeout */
   2227         int64_t timeout = 30000000000LL;
   2228         int64_t ns;
   2229         for (int i = 0; i < NumSensors; i++) {
   2230             LOGV_IF(0, "mFeatureActiveMask=0x%016llx, mEnabled=0x%01x, mBatchEnabled=0x%x",
   2231                             mFeatureActiveMask, mEnabled, mBatchEnabled);
   2232             if ((mEnabled & (1 << i)) && (mBatchEnabled & (1 << i)) ||
   2233                     (((featureMask & INV_DMP_PED_STANDALONE) && (mBatchEnabled & (1 << StepDetector))))) {
   2234                 LOGV_IF(ENG_VERBOSE, "sensor=%d, timeout=%lld", i, mBatchTimeouts[i]);
   2235                 ns = mBatchTimeouts[i];
   2236                 timeout = (ns < timeout) ? ns : timeout;
   2237             }
   2238         }
   2239         /* Convert ns to millisecond */
   2240         timeoutInMs = timeout / 1000000;
   2241     } else {
   2242         timeoutInMs = 0;
   2243     }
   2244 
   2245     LOGV_IF(PROCESS_VERBOSE, "HAL: batch timeout set to %dms", timeoutInMs);
   2246 
   2247     /* step detector is enabled and */
   2248     /* batch mode is standalone */
   2249     if (en && (mFeatureActiveMask & INV_DMP_PEDOMETER) &&
   2250             (featureMask & INV_DMP_PED_STANDALONE)) {
   2251         LOGI("ID_P only = 0x%x", mBatchEnabled);
   2252         enablePedStandalone(1);
   2253     } else {
   2254         enablePedStandalone(0);
   2255     }
   2256 
   2257     /* step detector and GRV are enabled and */
   2258     /* batch mode is ped q */
   2259     if (en && (mFeatureActiveMask & INV_DMP_PEDOMETER) &&
   2260             (mEnabled & (1 << GameRotationVector)) &&
   2261             (featureMask & INV_DMP_PED_QUATERNION)) {
   2262         LOGI("ID_P and GRV or ALL = 0x%x", mBatchEnabled);
   2263         LOGI("ID_P is enabled for batching, PED quat will be automatically enabled");
   2264         enableLPQuaternion(0);
   2265         enablePedQuaternion(1);
   2266     } else if (!(featureMask & INV_DMP_PED_STANDALONE)){
   2267         enablePedQuaternion(0);
   2268     }
   2269 
   2270     /* step detector and hardware sensors enabled */
   2271     if (en && (featureMask & INV_DMP_PED_INDICATOR) &&
   2272             ((mEnabled) ||
   2273             (mFeatureActiveMask & INV_DMP_PED_STANDALONE))) {
   2274         enablePedIndicator(1);
   2275     } else {
   2276         enablePedIndicator(0);
   2277     }
   2278 
   2279     /* GRV is enabled and */
   2280     /* batch mode is 6axis q */
   2281     if (en && (mEnabled & (1 << GameRotationVector)) &&
   2282             (featureMask & INV_DMP_6AXIS_QUATERNION)) {
   2283         LOGI("GRV = 0x%x", mBatchEnabled);
   2284         enableLPQuaternion(0);
   2285         enable6AxisQuaternion(1);
   2286     } else if (!(featureMask & INV_DMP_PED_QUATERNION)){
   2287         LOGI("Toggle back to normal 6 axis");
   2288         if (mEnabled & (1 << GameRotationVector)) {
   2289             enableLPQuaternion(1);
   2290         }
   2291         enable6AxisQuaternion(0);
   2292     }
   2293 
   2294     /* write required timeout to sysfs */
   2295     LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)",
   2296             timeoutInMs, mpu.batchmode_timeout, getTimestamp());
   2297     if (write_sysfs_int(mpu.batchmode_timeout, timeoutInMs) < 0) {
   2298         LOGE("HAL:ERR can't write batchmode_timeout");
   2299     }
   2300 
   2301     if (en) {
   2302         // enable DMP
   2303         res = onDmp(1);
   2304         if (res < 0) {
   2305             return res;
   2306         }
   2307 
   2308         // set batch rates
   2309         if (setBatchDataRates() < 0) {
   2310             LOGE("HAL:ERR can't set batch data rates");
   2311         }
   2312 
   2313         // default fifo rate to 200Hz
   2314         LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)",
   2315                 200, mpu.gyro_fifo_rate, getTimestamp());
   2316         if (write_sysfs_int(mpu.gyro_fifo_rate, 200) < 0) {
   2317             res = -1;
   2318             LOGE("HAL:ERR can't set rate to 200Hz");
   2319             return res;
   2320         }
   2321     } else {
   2322         if (mFeatureActiveMask == 0) {
   2323             // disable DMP
   2324             res = onDmp(0);
   2325             if (res < 0) {
   2326                 return res;
   2327             }
   2328         }
   2329         /* reset sensor rate */
   2330         /*if (resetDataRates() < 0) {
   2331             LOGE("HAL:ERR can't reset output rate back to original setting");
   2332         }*/
   2333     }
   2334     if (toggleEnable == 1) {
   2335         if (mFeatureActiveMask || mEnabled)
   2336             masterEnable(1);
   2337     }
   2338     return res;
   2339 }
   2340 
   2341 /* Store calibration file */
   2342 void MPLSensor::storeCalibration(void)
   2343 {
   2344     if(mHaveGoodMpuCal == true
   2345         || mAccelAccuracy >= 2
   2346         || mCompassAccuracy >= 3) {
   2347        int res = inv_store_calibration();
   2348        if (res) {
   2349            LOGE("HAL:Cannot store calibration on file");
   2350        } else {
   2351            LOGV_IF(PROCESS_VERBOSE, "HAL:Cal file updated");
   2352        }
   2353     }
   2354 }
   2355 
   2356 void MPLSensor::cbProcData(void)
   2357 {
   2358     mNewData = 1;
   2359     mSampleCount++;
   2360     LOGV_IF(EXTRA_VERBOSE, "HAL:new data");
   2361 }
   2362 
   2363 /*  these handlers transform mpl data into one of the Android sensor types */
   2364 int MPLSensor::gyroHandler(sensors_event_t* s)
   2365 {
   2366     VHANDLER_LOG;
   2367     int update;
   2368     update = inv_get_sensor_type_gyroscope(s->gyro.v, &s->gyro.status,
   2369                                            &s->timestamp);
   2370     LOGV_IF(HANDLER_DATA, "HAL:gyro data : %+f %+f %+f -- %lld - %d",
   2371             s->gyro.v[0], s->gyro.v[1], s->gyro.v[2], s->timestamp, update);
   2372     return update;
   2373 }
   2374 
   2375 int MPLSensor::rawGyroHandler(sensors_event_t* s)
   2376 {
   2377     VHANDLER_LOG;
   2378     int update;
   2379     update = inv_get_sensor_type_gyroscope_raw(s->uncalibrated_gyro.uncalib,
   2380                                                &s->gyro.status, &s->timestamp);
   2381     if(update) {
   2382         memcpy(s->uncalibrated_gyro.bias, mGyroBias, sizeof(mGyroBias));
   2383         LOGV_IF(HANDLER_DATA,"HAL:gyro bias data : %+f %+f %+f -- %lld - %d",
   2384             s->uncalibrated_gyro.bias[0], s->uncalibrated_gyro.bias[1],
   2385             s->uncalibrated_gyro.bias[2], s->timestamp, update);
   2386     }
   2387     s->gyro.status = SENSOR_STATUS_UNRELIABLE;
   2388     LOGV_IF(HANDLER_DATA, "HAL:raw gyro data : %+f %+f %+f -- %lld - %d",
   2389             s->uncalibrated_gyro.uncalib[0], s->uncalibrated_gyro.uncalib[1],
   2390             s->uncalibrated_gyro.uncalib[2], s->timestamp, update);
   2391     return update;
   2392 }
   2393 
   2394 int MPLSensor::accelHandler(sensors_event_t* s)
   2395 {
   2396     VHANDLER_LOG;
   2397     int update;
   2398     update = inv_get_sensor_type_accelerometer(
   2399         s->acceleration.v, &s->acceleration.status, &s->timestamp);
   2400     LOGV_IF(HANDLER_DATA, "HAL:accel data : %+f %+f %+f -- %lld - %d",
   2401             s->acceleration.v[0], s->acceleration.v[1], s->acceleration.v[2],
   2402             s->timestamp, update);
   2403     mAccelAccuracy = s->acceleration.status;
   2404     return update;
   2405 }
   2406 
   2407 int MPLSensor::compassHandler(sensors_event_t* s)
   2408 {
   2409     VHANDLER_LOG;
   2410     int update;
   2411     update = inv_get_sensor_type_magnetic_field(
   2412         s->magnetic.v, &s->magnetic.status, &s->timestamp);
   2413     LOGV_IF(HANDLER_DATA, "HAL:compass data: %+f %+f %+f -- %lld - %d",
   2414             s->magnetic.v[0], s->magnetic.v[1], s->magnetic.v[2],
   2415             s->timestamp, update);
   2416     mCompassAccuracy = s->magnetic.status;
   2417     return update;
   2418 }
   2419 
   2420 int MPLSensor::rawCompassHandler(sensors_event_t* s)
   2421 {
   2422     VHANDLER_LOG;
   2423     int update;
   2424     //TODO:: need to handle uncalib data and bias for 3rd party compass
   2425     if(mCompassSensor->providesCalibration()) {
   2426         update = mCompassSensor->readRawSample(s->uncalibrated_magnetic.uncalib, &s->timestamp);
   2427     }
   2428     else {
   2429         update = inv_get_sensor_type_magnetic_field_raw(s->uncalibrated_magnetic.uncalib,
   2430                      &s->magnetic.status, &s->timestamp);
   2431     }
   2432     if(update) {
   2433         memcpy(s->uncalibrated_magnetic.bias, mCompassBias, sizeof(mCompassBias));
   2434         LOGV_IF(HANDLER_DATA, "HAL:compass bias data: %+f %+f %+f -- %lld - %d",
   2435                 s->uncalibrated_magnetic.bias[0], s->uncalibrated_magnetic.bias[1],
   2436                 s->uncalibrated_magnetic.bias[2], s->timestamp, update);
   2437     }
   2438     s->magnetic.status = SENSOR_STATUS_UNRELIABLE;
   2439     LOGV_IF(HANDLER_DATA, "HAL:compass raw data: %+f %+f %+f %d -- %lld - %d",
   2440         s->uncalibrated_magnetic.uncalib[0], s->uncalibrated_magnetic.uncalib[1],
   2441                     s->uncalibrated_magnetic.uncalib[2], s->magnetic.status, s->timestamp, update);
   2442     return update;
   2443 }
   2444 
   2445 /*
   2446     Rotation Vector handler.
   2447     NOTE: rotation vector does not have an accuracy or status
   2448 */
   2449 int MPLSensor::rvHandler(sensors_event_t* s)
   2450 {
   2451     VHANDLER_LOG;
   2452     int8_t status;
   2453     int update;
   2454     update = inv_get_sensor_type_rotation_vector(s->data, &status,
   2455                                                  &s->timestamp);
   2456     update |= isCompassDisabled();
   2457     LOGV_IF(HANDLER_DATA, "HAL:rv data: %+f %+f %+f %+f %+f- %+lld - %d",
   2458             s->data[0], s->data[1], s->data[2], s->data[3], s->data[4], s->timestamp,
   2459             update);
   2460 
   2461     return update;
   2462 }
   2463 
   2464 /*
   2465     Game Rotation Vector handler.
   2466     NOTE: rotation vector does not have an accuracy or status
   2467 */
   2468 int MPLSensor::grvHandler(sensors_event_t* s)
   2469 {
   2470     VHANDLER_LOG;
   2471     int8_t status;
   2472     int update;
   2473     update = inv_get_sensor_type_rotation_vector_6_axis(s->data, &status,
   2474                                                      &s->timestamp);
   2475     /*hack*/
   2476     /*s->data[0] =  mCached6AxisQuaternionData[0];
   2477     s->data[1] =  mCached6AxisQuaternionData[1];
   2478     s->data[2] =  mCached6AxisQuaternionData[2];
   2479     update = 1;*/
   2480 
   2481 
   2482     LOGV_IF(HANDLER_DATA, "HAL:grv data: %+f %+f %+f %+f %+f - %+lld - %d",
   2483             s->data[0], s->data[1], s->data[2], s->data[3], s->data[4], s->timestamp,
   2484             update);
   2485     return update;
   2486 }
   2487 
   2488 int MPLSensor::laHandler(sensors_event_t* s)
   2489 {
   2490     VHANDLER_LOG;
   2491     int update;
   2492     update = inv_get_sensor_type_linear_acceleration(
   2493             s->gyro.v, &s->gyro.status, &s->timestamp);
   2494     update |= isCompassDisabled();
   2495     LOGV_IF(HANDLER_DATA, "HAL:la data: %+f %+f %+f - %lld - %d",
   2496             s->gyro.v[0], s->gyro.v[1], s->gyro.v[2], s->timestamp, update);
   2497     return update;
   2498 }
   2499 
   2500 int MPLSensor::gravHandler(sensors_event_t* s)
   2501 {
   2502     VHANDLER_LOG;
   2503     int update;
   2504     update = inv_get_sensor_type_gravity(s->gyro.v, &s->gyro.status,
   2505                                          &s->timestamp);
   2506     update |= isCompassDisabled();
   2507     LOGV_IF(HANDLER_DATA, "HAL:gr data: %+f %+f %+f - %lld - %d",
   2508             s->gyro.v[0], s->gyro.v[1], s->gyro.v[2], s->timestamp, update);
   2509     return update;
   2510 }
   2511 
   2512 int MPLSensor::orienHandler(sensors_event_t* s)
   2513 {
   2514     VHANDLER_LOG;
   2515     int update;
   2516     update = inv_get_sensor_type_orientation(
   2517             s->orientation.v, &s->orientation.status, &s->timestamp);
   2518     update |= isCompassDisabled();
   2519     LOGV_IF(HANDLER_DATA, "HAL:or data: %f %f %f - %lld - %d",
   2520             s->orientation.v[0], s->orientation.v[1], s->orientation.v[2],
   2521             s->timestamp, update);
   2522     return update;
   2523 }
   2524 
   2525 int MPLSensor::smHandler(sensors_event_t* s)
   2526 {
   2527     VHANDLER_LOG;
   2528     int update = 1;
   2529 
   2530     /* When event is triggered, set data to 1 */
   2531     s->data[0] = 1.f;
   2532     s->data[1] = 0.f;
   2533     s->data[2] = 0.f;
   2534     s->acceleration.status
   2535             = SENSOR_STATUS_UNRELIABLE;
   2536 
   2537     /* Capture timestamp in HAL */
   2538     struct timespec ts;
   2539     clock_gettime(CLOCK_MONOTONIC, &ts);
   2540     s->timestamp = (int64_t) ts.tv_sec * 1000000000 + ts.tv_nsec;
   2541 
   2542     /* Identify which sensor this event is for */
   2543     s->version = sizeof(sensors_event_t);
   2544     s->sensor = ID_SM;
   2545     s->type = SENSOR_TYPE_SIGNIFICANT_MOTION;
   2546 
   2547     LOGV_IF(HANDLER_DATA, "HAL:sm data: %f - %lld - %d",
   2548             s->data[0], s->timestamp, update);
   2549     return update;
   2550 }
   2551 
   2552 int MPLSensor::scHandler(sensors_event_t* s)
   2553 {
   2554     VHANDLER_LOG;
   2555     int update = 0;
   2556 
   2557     //update = readDmpPedometerEvents(s, 1);
   2558     LOGV_IF(HANDLER_DATA, "HAL:sc data: %f - %lld - %d",
   2559             s->data[0], s->timestamp, update);
   2560     return update < 1 ? 0 :1;
   2561 }
   2562 
   2563 int MPLSensor::gmHandler(sensors_event_t* s)
   2564 {
   2565     VHANDLER_LOG;
   2566     int8_t status;
   2567     int update = 0;
   2568     update = inv_get_sensor_type_geomagnetic_rotation_vector(s->data, &status,
   2569                                                              &s->timestamp);
   2570 
   2571     LOGV_IF(HANDLER_DATA, "HAL:gm data: %+f %+f %+f %+f %+f- %+lld - %d",
   2572             s->data[0], s->data[1], s->data[2], s->data[3], s->data[4], s->timestamp, update);
   2573     return update < 1 ? 0 :1;
   2574 
   2575 }
   2576 
   2577 int MPLSensor::psHandler(sensors_event_t* s)
   2578 {
   2579     VHANDLER_LOG;
   2580     int8_t status;
   2581     int update = 0;
   2582 
   2583     s->data[0] = mCachedPressureData / 100; //hpa (millibar)
   2584     s->data[1] = 0;
   2585     s->data[2] = 0;
   2586     s->timestamp = mPressureTimestamp;
   2587     s->magnetic.status = 0;
   2588     update = 1;
   2589 
   2590     LOGV_IF(HANDLER_DATA, "HAL:ps data: %+f %+f %+f %+f- %+lld - %d",
   2591             s->data[0], s->data[1], s->data[2], s->data[3], s->timestamp, update);
   2592     return update < 1 ? 0 :1;
   2593 
   2594 }
   2595 
   2596 int MPLSensor::enable(int32_t handle, int en)
   2597 {
   2598     VFUNC_LOG;
   2599 
   2600     android::String8 sname;
   2601     int what = -1, err = 0;
   2602     int batchMode = 0;
   2603 
   2604     switch (handle) {
   2605     case ID_SC:
   2606          what = StepCounter;
   2607          sname = "Step Counter";
   2608          LOGV_IF(PROCESS_VERBOSE, "HAL:enable - sensor %s (handle %d) %s -> %s",
   2609                 sname.string(), handle,
   2610                 (mDmpStepCountEnabled? "en": "dis"),
   2611                 (en? "en" : "dis"));
   2612         enableDmpPedometer(en, 0);
   2613         mDmpStepCountEnabled = !!en;
   2614         return 0;
   2615     case ID_P:
   2616         sname = "StepDetector";
   2617         LOGV_IF(PROCESS_VERBOSE, "HAL:enable - sensor %s (handle %d) %s -> %s",
   2618                 sname.string(), handle,
   2619                 (mDmpPedometerEnabled? "en": "dis"),
   2620                 (en? "en" : "dis"));
   2621         enableDmpPedometer(en, 1);
   2622         mDmpPedometerEnabled = !!en;
   2623         batchMode = computeBatchSensorMask(mEnabled, mBatchEnabled);
   2624         setBatch(batchMode,1);
   2625         return 0;
   2626     case ID_SM:
   2627         sname = "Significant Motion";
   2628         LOGV_IF(PROCESS_VERBOSE, "HAL:enable - sensor %s (handle %d) %s -> %s",
   2629                 sname.string(), handle,
   2630                 (mDmpSignificantMotionEnabled? "en": "dis"),
   2631                 (en? "en" : "dis"));
   2632         enableDmpSignificantMotion(en);
   2633         mDmpSignificantMotionEnabled = !!en;
   2634         return 0;
   2635     case ID_SO:
   2636         sname = "Screen Orientation";
   2637         LOGV_IF(PROCESS_VERBOSE, "HAL:enable - sensor %s (handle %d) %s -> %s",
   2638                 sname.string(), handle,
   2639                 (mDmpOrientationEnabled? "en": "dis"),
   2640                 (en? "en" : "dis"));
   2641         enableDmpOrientation(en && isDmpDisplayOrientationOn());
   2642         mDmpOrientationEnabled = !!en;
   2643         return 0;
   2644     case ID_A:
   2645         what = Accelerometer;
   2646         sname = "Accelerometer";
   2647         break;
   2648     case ID_M:
   2649         what = MagneticField;
   2650         sname = "MagneticField";
   2651         break;
   2652     case ID_RM:
   2653         what = RawMagneticField;
   2654         sname = "MagneticField Uncalibrated";
   2655         break;
   2656     case ID_O:
   2657         what = Orientation;
   2658         sname = "Orientation";
   2659         break;
   2660     case ID_GY:
   2661         what = Gyro;
   2662         sname = "Gyro";
   2663         break;
   2664     case ID_RG:
   2665         what = RawGyro;
   2666         sname = "Gyro Uncalibrated";
   2667         break;
   2668     case ID_GR:
   2669         what = Gravity;
   2670         sname = "Gravity";
   2671         break;
   2672     case ID_RV:
   2673         what = RotationVector;
   2674         sname = "RotationVector";
   2675         break;
   2676     case ID_GRV:
   2677         what = GameRotationVector;
   2678         sname = "GameRotationVector";
   2679         break;
   2680     case ID_LA:
   2681         what = LinearAccel;
   2682         sname = "LinearAccel";
   2683         break;
   2684     case ID_GMRV:
   2685         what = GeomagneticRotationVector;
   2686         sname = "GeomagneticRotationVector";
   2687         break;
   2688     case ID_PS:
   2689         what = Pressure;
   2690         sname = "Pressure";
   2691         break;
   2692     default: //this takes care of all the gestures
   2693         what = handle;
   2694         sname = "Others";
   2695         break;
   2696     }
   2697 
   2698     if (uint32_t(what) >= NumSensors)
   2699         return -EINVAL;
   2700 
   2701     int newState = en ? 1 : 0;
   2702     unsigned long sen_mask;
   2703 
   2704     LOGV_IF(PROCESS_VERBOSE, "HAL:enable - sensor %s (handle %d) %s -> %s",
   2705             sname.string(), handle,
   2706             ((mEnabled & (1 << what)) ? "en" : "dis"),
   2707             ((uint32_t(newState) << what) ? "en" : "dis"));
   2708     LOGV_IF(PROCESS_VERBOSE,
   2709             "HAL:%s sensor state change what=%d", sname.string(), what);
   2710 
   2711     // pthread_mutex_lock(&mMplMutex);
   2712     // pthread_mutex_lock(&mHALMutex);
   2713 
   2714     if ((uint32_t(newState) << what) != (mEnabled & (1 << what))) {
   2715         uint32_t sensor_type;
   2716         short flags = newState;
   2717         uint32_t lastEnabled = mEnabled, changed = 0;
   2718 
   2719         mEnabled &= ~(1 << what);
   2720         mEnabled |= (uint32_t(flags) << what);
   2721 
   2722         LOGV_IF(PROCESS_VERBOSE, "HAL:handle = %d", handle);
   2723         LOGV_IF(PROCESS_VERBOSE, "HAL:flags = %d", flags);
   2724         computeLocalSensorMask(mEnabled);
   2725         LOGV_IF(PROCESS_VERBOSE, "HAL:enable : mEnabled = %d", mEnabled);
   2726         LOGV_IF(ENG_VERBOSE, "HAL:last enable : lastEnabled = %d", lastEnabled);
   2727         sen_mask = mLocalSensorMask & mMasterSensorMask;
   2728         mSensorMask = sen_mask;
   2729         LOGV_IF(PROCESS_VERBOSE, "HAL:sen_mask= 0x%0lx", sen_mask);
   2730 
   2731         switch (what) {
   2732             case Gyro:
   2733             case RawGyro:
   2734             case Accelerometer:
   2735                 if ((!(mEnabled & VIRTUAL_SENSOR_GYRO_6AXES_MASK) &&
   2736                     !(mEnabled & VIRTUAL_SENSOR_9AXES_MASK)) &&
   2737                     ((lastEnabled & (1 << what)) != (mEnabled & (1 << what)))) {
   2738                     changed |= (1 << what);
   2739                 }
   2740                 if (mFeatureActiveMask & INV_DMP_6AXIS_QUATERNION) {
   2741                      changed |= (1 << what);
   2742                 }
   2743                 break;
   2744             case MagneticField:
   2745             case RawMagneticField:
   2746                 if (!(mEnabled & VIRTUAL_SENSOR_9AXES_MASK) &&
   2747                     ((lastEnabled & (1 << what)) != (mEnabled & (1 << what)))) {
   2748                     changed |= (1 << what);
   2749                 }
   2750                 break;
   2751             case Pressure:
   2752                 if ((lastEnabled & (1 << what)) != (mEnabled & (1 << what))) {
   2753                     changed |= (1 << what);
   2754                 }
   2755                 break;
   2756             case GameRotationVector:
   2757                 if (!en)
   2758                     storeCalibration();
   2759                 if ((en && !(lastEnabled & VIRTUAL_SENSOR_ALL_MASK))
   2760                          ||
   2761                     (en && !(lastEnabled & VIRTUAL_SENSOR_9AXES_MASK))
   2762                          ||
   2763                     (!en && !(mEnabled & VIRTUAL_SENSOR_ALL_MASK))
   2764                          ||
   2765                     (!en && (mEnabled & VIRTUAL_SENSOR_MAG_6AXES_MASK))) {
   2766                     for (int i = Gyro; i <= RawMagneticField; i++) {
   2767                         if (!(mEnabled & (1 << i))) {
   2768                             changed |= (1 << i);
   2769                         }
   2770                     }
   2771                 }
   2772                 break;
   2773 
   2774             case Orientation:
   2775             case RotationVector:
   2776             case LinearAccel:
   2777             case Gravity:
   2778                 if (!en)
   2779                     storeCalibration();
   2780                 if ((en && !(lastEnabled & VIRTUAL_SENSOR_9AXES_MASK))
   2781                          ||
   2782                     (!en && !(mEnabled & VIRTUAL_SENSOR_9AXES_MASK))) {
   2783                     for (int i = Gyro; i <= RawMagneticField; i++) {
   2784                         if (!(mEnabled & (1 << i))) {
   2785                             changed |= (1 << i);
   2786                         }
   2787                     }
   2788                 }
   2789                 break;
   2790             case GeomagneticRotationVector:
   2791                 if (!en)
   2792                     storeCalibration();
   2793                 if ((en && !(lastEnabled & VIRTUAL_SENSOR_ALL_MASK))
   2794                         ||
   2795                     (en && !(lastEnabled & VIRTUAL_SENSOR_9AXES_MASK))
   2796                          ||
   2797                    (!en && !(mEnabled & VIRTUAL_SENSOR_ALL_MASK))
   2798                          ||
   2799                    (!en && (mEnabled & VIRTUAL_SENSOR_GYRO_6AXES_MASK))) {
   2800                    for (int i = Accelerometer; i <= RawMagneticField; i++) {
   2801                        if (!(mEnabled & (1<<i))) {
   2802                           changed |= (1 << i);
   2803                        }
   2804                    }
   2805                 }
   2806                 break;
   2807         }
   2808         LOGV_IF(PROCESS_VERBOSE, "HAL:changed = %d", changed);
   2809         enableSensors(sen_mask, flags, changed);
   2810     }
   2811 
   2812     // pthread_mutex_unlock(&mMplMutex);
   2813     // pthread_mutex_unlock(&mHALMutex);
   2814 
   2815 #ifdef INV_PLAYBACK_DBG
   2816     /* apparently the logging needs to go through this sequence
   2817        to properly flush the log file */
   2818     inv_turn_off_data_logging();
   2819     fclose(logfile);
   2820     logfile = fopen("/data/playback.bin", "ab");
   2821     if (logfile)
   2822         inv_turn_on_data_logging(logfile);
   2823 #endif
   2824 
   2825     return err;
   2826 }
   2827 
   2828 void MPLSensor::getHandle(int32_t handle, int &what, android::String8 &sname)
   2829 {
   2830    VFUNC_LOG;
   2831 
   2832    what = -1;
   2833 
   2834    switch (handle) {
   2835    case ID_P:
   2836         what = StepDetector;
   2837         sname = "StepDetector";
   2838         break;
   2839    case ID_SC:
   2840         what = StepCounter;
   2841         sname = "StepCounter";
   2842         break;
   2843    case ID_SM:
   2844         what = SignificantMotion;
   2845         sname = "SignificantMotion";
   2846         break;
   2847    case ID_SO:
   2848         what = handle;
   2849         sname = "ScreenOrienation";
   2850    case ID_A:
   2851         what = Accelerometer;
   2852         sname = "Accelerometer";
   2853         break;
   2854    case ID_M:
   2855         what = MagneticField;
   2856         sname = "MagneticField";
   2857         break;
   2858    case ID_RM:
   2859         what = RawMagneticField;
   2860         sname = "MagneticField Uncalibrated";
   2861         break;
   2862    case ID_O:
   2863         what = Orientation;
   2864         sname = "Orientation";
   2865         break;
   2866    case ID_GY:
   2867         what = Gyro;
   2868         sname = "Gyro";
   2869         break;
   2870    case ID_RG:
   2871         what = RawGyro;
   2872         sname = "Gyro Uncalibrated";
   2873         break;
   2874    case ID_GR:
   2875         what = Gravity;
   2876         sname = "Gravity";
   2877         break;
   2878    case ID_RV:
   2879         what = RotationVector;
   2880         sname = "RotationVector";
   2881         break;
   2882    case ID_GRV:
   2883         what = GameRotationVector;
   2884         sname = "GameRotationVector";
   2885         break;
   2886    case ID_LA:
   2887         what = LinearAccel;
   2888         sname = "LinearAccel";
   2889         break;
   2890    case ID_PS:
   2891         what = Pressure;
   2892         sname = "Pressure";
   2893         break;
   2894    default: // this takes care of all the gestures
   2895         what = handle;
   2896         sname = "Others";
   2897         break;
   2898     }
   2899 
   2900     LOGI_IF(EXTRA_VERBOSE, "HAL:getHandle - what=%d, sname=%s", what, sname.string());
   2901     return;
   2902 }
   2903 
   2904 int MPLSensor::setDelay(int32_t handle, int64_t ns)
   2905 {
   2906     VFUNC_LOG;
   2907 
   2908     android::String8 sname;
   2909     int what = -1;
   2910 
   2911 #if 0
   2912     // skip the 1st call for enalbing sensors called by ICS/JB sensor service
   2913     static int counter_delay = 0;
   2914     if (!(mEnabled & (1 << what))) {
   2915         counter_delay = 0;
   2916     } else {
   2917         if (++counter_delay == 1) {
   2918             return 0;
   2919         }
   2920         else {
   2921             counter_delay = 0;
   2922         }
   2923     }
   2924 #endif
   2925 
   2926     getHandle(handle, what, sname);
   2927     if (uint32_t(what) >= NumSensors)
   2928         return -EINVAL;
   2929 
   2930     if (ns < 0)
   2931         return -EINVAL;
   2932 
   2933     LOGV_IF(PROCESS_VERBOSE,
   2934             "setDelay : %llu ns, (%.2f Hz)", ns, 1000000000.f / ns);
   2935 
   2936     // limit all rates to reasonable ones */
   2937     if (ns < 5000000LL) {
   2938         ns = 5000000LL;
   2939     }
   2940 
   2941     /* store request rate to mDelays arrary for each sensor */
   2942     mDelays[what] = ns;
   2943 
   2944     switch (what) {
   2945         case ID_SC:
   2946             /* set limits of delivery rate of events */
   2947             mStepCountPollTime = ns;
   2948             LOGV_IF(ENG_VERBOSE, "step count rate =%lld ns", ns);
   2949             break;
   2950         case ID_P:
   2951         case SignificantMotion:
   2952         case ID_SO:
   2953             update_delay();
   2954             break;
   2955         case Gyro:
   2956         case RawGyro:
   2957         case Accelerometer:
   2958             for (int i = Gyro;
   2959                     i <= Accelerometer + mCompassSensor->isIntegrated();
   2960                     i++) {
   2961                 if (i != what && (mEnabled & (1 << i)) && ns > mDelays[i]) {
   2962                     LOGV_IF(PROCESS_VERBOSE,
   2963                             "HAL:ignore delay set due to sensor %d", i);
   2964                     return 0;
   2965                 }
   2966             }
   2967             break;
   2968 
   2969         case MagneticField:
   2970         case RawMagneticField:
   2971             if (mCompassSensor->isIntegrated() &&
   2972                     (((mEnabled & (1 << Gyro)) && ns > mDelays[Gyro]) ||
   2973                     ((mEnabled & (1 << RawGyro)) && ns > mDelays[RawGyro]) ||
   2974                     ((mEnabled & (1 << Accelerometer)) &&
   2975                         ns > mDelays[Accelerometer]))) {
   2976                  LOGV_IF(PROCESS_VERBOSE,
   2977                          "HAL:ignore delay set due to gyro/accel");
   2978                  return 0;
   2979             }
   2980             break;
   2981 
   2982         case Orientation:
   2983         case RotationVector:
   2984         case GameRotationVector:
   2985         case GeomagneticRotationVector:
   2986         case LinearAccel:
   2987         case Gravity:
   2988             if (isLowPowerQuatEnabled()) {
   2989                 LOGV_IF(PROCESS_VERBOSE,
   2990                         "HAL:need to update delay due to LPQ");
   2991                 break;
   2992             }
   2993 
   2994             for (int i = 0; i < NumSensors; i++) {
   2995                 if (i != what && (mEnabled & (1 << i)) && ns > mDelays[i]) {
   2996                     LOGV_IF(PROCESS_VERBOSE,
   2997                             "HAL:ignore delay set due to sensor %d", i);
   2998                     return 0;
   2999                 }
   3000             }
   3001             break;
   3002     }
   3003 
   3004     // pthread_mutex_lock(&mHALMutex);
   3005     int res = update_delay();
   3006     // pthread_mutex_unlock(&mHALMutex);
   3007     return res;
   3008 }
   3009 
   3010 int MPLSensor::update_delay(void)
   3011 {
   3012     VHANDLER_LOG;
   3013 
   3014     int res = 0;
   3015     int64_t got;
   3016 
   3017     if (mEnabled) {
   3018         int64_t wanted = 1000000000LL;
   3019         int64_t wanted_3rd_party_sensor = 1000000000LL;
   3020 
   3021         // Sequence to change sensor's FIFO rate
   3022         // 1. reset master enable
   3023         // 2. Update delay
   3024         // 3. set master enable
   3025 
   3026         // reset master enable
   3027         masterEnable(0);
   3028 
   3029         int64_t gyroRate;
   3030         int64_t accelRate;
   3031         int64_t compassRate;
   3032         int64_t pressureRate;
   3033 
   3034         int rateInus;
   3035         int mplGyroRate;
   3036         int mplAccelRate;
   3037         int mplCompassRate;
   3038         int tempRate = wanted;
   3039 
   3040         /* search the minimum delay requested across all enabled sensors */
   3041         for (int i = 0; i < NumSensors; i++) {
   3042             if (mEnabled & (1 << i)) {
   3043                 int64_t ns = mDelays[i];
   3044                 wanted = wanted < ns ? wanted : ns;
   3045             }
   3046         }
   3047 
   3048         if (mDmpOn) {
   3049             gyroRate = mDelays[Gyro] < mDelays[RawGyro] ? mDelays[Gyro] : mDelays[RawGyro];
   3050             accelRate = mDelays[Accelerometer];
   3051             compassRate = mDelays[MagneticField] < mDelays[RawMagneticField] ? mDelays[MagneticField] : mDelays[RawMagneticField];
   3052             pressureRate = mDelays[Pressure];
   3053 
   3054 #ifdef ENABLE_MULTI_RATE
   3055             gyroRate = wanted;
   3056             accelRate = wanted;
   3057             compassRate = wanted;
   3058             pressureRate = wanted;
   3059             // same delay for 3rd party Accel or Compass
   3060             wanted_3rd_party_sensor = wanted;
   3061 #endif
   3062 
   3063         }
   3064         else {
   3065             gyroRate = wanted;
   3066             accelRate = wanted;
   3067             compassRate = wanted;
   3068             pressureRate = wanted;
   3069             // same delay for 3rd party Accel or Compass
   3070             wanted_3rd_party_sensor = wanted;
   3071         }
   3072 
   3073         /* mpl rate in us in future maybe different for
   3074            gyro vs compass vs accel */
   3075  /*       rateInus = (int)wanted / 1000LL;
   3076         mplGyroRate = (int)gyroRate / 1000LL;
   3077         mplAccelRate = (int)accelRate / 1000LL;
   3078         mplCompassRate = (int)compassRate / 1000LL;
   3079 
   3080         LOGV_IF(PROCESS_VERBOSE, "HAL:wanted rate for all sensors : "
   3081              "%llu ns, mpl rate: %d us, (%.2f Hz)",
   3082              wanted, rateInus, 1000000000.f / wanted);
   3083 
   3084         /* set rate in MPL */
   3085         /* compass can only do 100Hz max */
   3086  /*       inv_set_gyro_sample_rate(mplGyroRate);
   3087         inv_set_accel_sample_rate(mplAccelRate);
   3088         inv_set_compass_sample_rate(mplCompassRate);
   3089 
   3090         LOGV_IF(PROCESS_VERBOSE,
   3091                 "HAL:MPL gyro sample rate: (mpl)=%d us (mpu)=%.2f Hz", mplGyroRate, 1000000000.f / gyroRate);
   3092         LOGV_IF(PROCESS_VERBOSE,
   3093                 "HAL:MPL accel sample rate: (mpl)=%d us (mpu)=%.2f Hz", mplAccelRate, 1000000000.f / accelRate);
   3094         LOGV_IF(PROCESS_VERBOSE,
   3095                 "HAL:MPL compass sample rate: (mpl)=%d us (mpu)=%.2f Hz", mplCompassRate, 1000000000.f / compassRate);
   3096 */
   3097         int enabled_sensors = mEnabled;
   3098         int tempFd = -1;
   3099 
   3100         if(mFeatureActiveMask & INV_DMP_BATCH_MODE) {
   3101             // set batch rates
   3102             LOGV_IF(ENG_VERBOSE, "HAL: mFeatureActiveMask=%016llx", mFeatureActiveMask);
   3103             LOGV("HAL: batch mode is set, set batch data rates");
   3104             if (setBatchDataRates() < 0) {
   3105                 LOGE("HAL:ERR can't set batch data rates");
   3106             }
   3107         } else {
   3108         if (LA_ENABLED || GR_ENABLED || RV_ENABLED
   3109                        || GRV_ENABLED || O_ENABLED || GMRV_ENABLED) {
   3110             LOGV_IF(ENG_VERBOSE, "mFeatureActiveMask=%016llx", mFeatureActiveMask);
   3111             //TODO: may be able to combine DMP_FEATURE_MASK, DMP_SENSOR_MASK in the future
   3112             if(mFeatureActiveMask & DMP_FEATURE_MASK) {
   3113                 bool setDMPrate= 0;
   3114                 gyroRate = wanted;
   3115                 accelRate = wanted;
   3116                 compassRate = wanted;
   3117                 // same delay for 3rd party Accel or Compass
   3118                 wanted_3rd_party_sensor = wanted;
   3119                 rateInus = (int)wanted / 1000LL;
   3120 
   3121                  /* set rate in MPL */
   3122                  /* compass can only do 100Hz max */
   3123                  inv_set_gyro_sample_rate(rateInus);
   3124                  inv_set_accel_sample_rate(rateInus);
   3125                  inv_set_compass_sample_rate(rateInus);
   3126 
   3127                  LOGV_IF(PROCESS_VERBOSE,
   3128                 "HAL:MPL gyro sample rate: (mpl)=%d us (mpu)=%.2f Hz", rateInus, 1000000000.f / gyroRate);
   3129                  LOGV_IF(PROCESS_VERBOSE,
   3130                 "HAL:MPL accel sample rate: (mpl)=%d us (mpu)=%.2f Hz", rateInus, 1000000000.f / accelRate);
   3131                  LOGV_IF(PROCESS_VERBOSE,
   3132                 "HAL:MPL compass sample rate: (mpl)=%d us (mpu)=%.2f Hz", rateInus, 1000000000.f / compassRate);
   3133 
   3134                 // Set LP Quaternion sample rate if enabled
   3135                 if (checkLPQuaternion()) {
   3136                     if (wanted <= RATE_200HZ) {
   3137 #ifndef USE_LPQ_AT_FASTEST
   3138                         enableLPQuaternion(0);
   3139 #endif
   3140                     } else {
   3141                         inv_set_quat_sample_rate(rateInus);
   3142                         setDMPrate= 1;
   3143                     }
   3144                 }
   3145                 //if((mFeatureActiveMask & DMP_SENSOR_MASK) || setDMPrate==1) {
   3146                 //    getDmpRate(&wanted);
   3147                 //}
   3148             }
   3149 
   3150             LOGV_IF(EXTRA_VERBOSE, "HAL:setDelay - Fusion");
   3151             //nsToHz
   3152             LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %.0f > %s (%lld)",
   3153                     1000000000.f / gyroRate, mpu.gyro_rate,
   3154                     getTimestamp());
   3155             tempFd = open(mpu.gyro_rate, O_RDWR);
   3156             res = write_attribute_sensor(tempFd, 1000000000.f / gyroRate);
   3157             if(res < 0) {
   3158                 LOGE("HAL:GYRO update delay error");
   3159             }
   3160 
   3161             if(USE_THIRD_PARTY_ACCEL == 1) {
   3162             // 3rd party accelerometer - if applicable
   3163             // nsToHz (BMA250)
   3164                 LOGV_IF(SYSFS_VERBOSE, "echo %lld > %s (%lld)",
   3165                         wanted_3rd_party_sensor / 1000000L, mpu.accel_rate,
   3166                         getTimestamp());
   3167                 tempFd = open(mpu.accel_rate, O_RDWR);
   3168                 res = write_attribute_sensor(tempFd,
   3169                         wanted_3rd_party_sensor / 1000000L);
   3170                 LOGE_IF(res < 0, "HAL:ACCEL update delay error");
   3171             } else {
   3172             // mpu accel
   3173                LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %.0f > %s (%lld)",
   3174                         1000000000.f / accelRate, mpu.accel_rate,
   3175                         getTimestamp());
   3176                 tempFd = open(mpu.accel_rate, O_RDWR);
   3177                 res = write_attribute_sensor(tempFd, 1000000000.f / accelRate);
   3178                 LOGE_IF(res < 0, "HAL:ACCEL update delay error");
   3179             }
   3180 
   3181             if (!mCompassSensor->isIntegrated()) {
   3182             // stand-alone compass - if applicable
   3183                 LOGV_IF(PROCESS_VERBOSE,
   3184                         "HAL:Ext compass delay %lld", wanted_3rd_party_sensor);
   3185                 LOGV_IF(PROCESS_VERBOSE, "HAL:Ext compass rate %.2f Hz",
   3186                         1000000000.f / wanted_3rd_party_sensor);
   3187                 if (wanted_3rd_party_sensor <
   3188                         mCompassSensor->getMinDelay() * 1000LL) {
   3189                     wanted_3rd_party_sensor =
   3190                         mCompassSensor->getMinDelay() * 1000LL;
   3191                 }
   3192                 LOGV_IF(PROCESS_VERBOSE,
   3193                         "HAL:Ext compass delay %lld", wanted_3rd_party_sensor);
   3194                 LOGV_IF(PROCESS_VERBOSE, "HAL:Ext compass rate %.2f Hz",
   3195                         1000000000.f / wanted_3rd_party_sensor);
   3196                 mCompassSensor->setDelay(ID_M, wanted_3rd_party_sensor);
   3197                 got = mCompassSensor->getDelay(ID_M);
   3198                 inv_set_compass_sample_rate(got / 1000);
   3199             } else {
   3200             // compass on secondary bus
   3201                 if (compassRate < mCompassSensor->getMinDelay() * 1000LL) {
   3202                     compassRate = mCompassSensor->getMinDelay() * 1000LL;
   3203                 }
   3204                 mCompassSensor->setDelay(ID_M, compassRate);
   3205             }
   3206 
   3207             /*
   3208             //nsTons - nothing to be done
   3209             strcpy(&compass_sensor_sysfs_path[compass_sensor_sysfs_path_len],
   3210                    COMPASS_SENSOR_DELAY);
   3211             tempFd = open(compass_sensor_sysfs_path, O_RDWR);
   3212             LOGV_IF(PROCESS_VERBOSE,
   3213                     "setDelay - open path: %s", compass_sensor_sysfs_path);
   3214             wanted = 20000000LLU;
   3215             res = write_attribute_sensor(tempFd, wanted);
   3216             if(res < 0) {
   3217                 LOGE("Compass update delay error");
   3218             }
   3219             */
   3220 
   3221         } else {
   3222 
   3223             if (GY_ENABLED || RGY_ENABLED) {
   3224                 wanted = (mDelays[Gyro] <= mDelays[RawGyro]?
   3225                     (mEnabled & (1 << Gyro)? mDelays[Gyro]: mDelays[RawGyro]):
   3226                     (mEnabled & (1 << RawGyro)? mDelays[RawGyro]: mDelays[Gyro]));
   3227                 LOGV_IF(ENG_VERBOSE, "mFeatureActiveMask=%016llx", mFeatureActiveMask);
   3228                 if (mFeatureActiveMask & DMP_FEATURE_MASK) {
   3229                     //int64_t tempWanted;
   3230                     //getDmpRate(&tempWanted);
   3231                 }
   3232 
   3233                 inv_set_gyro_sample_rate((int)wanted/1000LL);
   3234                 LOGV_IF(PROCESS_VERBOSE,
   3235                     "HAL:MPL gyro sample rate: (mpl)=%d us", int(wanted/1000LL));
   3236                 LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %.0f > %s (%lld)",
   3237                         1000000000.f / wanted, mpu.gyro_rate, getTimestamp());
   3238                 tempFd = open(mpu.gyro_rate, O_RDWR);
   3239                 res = write_attribute_sensor(tempFd, 1000000000.f / wanted);
   3240                 LOGE_IF(res < 0, "HAL:GYRO update delay error");
   3241             }
   3242 
   3243             if (A_ENABLED) { /* there is only 1 fifo rate for MPUxxxx */
   3244 
   3245 #if (0)
   3246                 wanted = mDelays[Accelerometer];
   3247 #else
   3248                 if (GY_ENABLED && mDelays[Gyro] < mDelays[Accelerometer]) {
   3249                     wanted = mDelays[Gyro];
   3250                 } else if (RGY_ENABLED && mDelays[RawGyro]
   3251                             < mDelays[Accelerometer]) {
   3252                     wanted = mDelays[RawGyro];
   3253                 } else {
   3254                     wanted = mDelays[Accelerometer];
   3255                 }
   3256 #endif
   3257                 LOGV_IF(ENG_VERBOSE, "mFeatureActiveMask=%016llx", mFeatureActiveMask);
   3258                 if (mFeatureActiveMask & DMP_FEATURE_MASK) {
   3259                     //int64_t tempWanted;
   3260                     //getDmpRate(&tempWanted);
   3261                 }
   3262 
   3263                 inv_set_accel_sample_rate((int)wanted/1000LL);
   3264                 LOGV_IF(PROCESS_VERBOSE,
   3265                     "HAL:MPL accel sample rate: (mpl)=%d us", int(wanted/1000LL));
   3266                 /* TODO: use function pointers to calculate delay value specific
   3267                    to vendor */
   3268                 LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %.0f > %s (%lld)",
   3269                         1000000000.f / wanted, mpu.accel_rate,
   3270                         getTimestamp());
   3271                 tempFd = open(mpu.accel_rate, O_RDWR);
   3272                 if(USE_THIRD_PARTY_ACCEL == 1) {
   3273                     //BMA250 in ms
   3274                     res = write_attribute_sensor(tempFd, wanted / 1000000L);
   3275                 }
   3276                 else {
   3277                     //MPUxxxx in hz
   3278                     res = write_attribute_sensor(tempFd, 1000000000.f/wanted);
   3279                 }
   3280                 LOGE_IF(res < 0, "HAL:ACCEL update delay error");
   3281             }
   3282 
   3283             /* Invensense compass calibration */
   3284             if (M_ENABLED || RM_ENABLED) {
   3285                 int64_t compassWanted = (mDelays[MagneticField] <= mDelays[RawMagneticField]?
   3286                     (mEnabled & (1 << MagneticField)? mDelays[MagneticField]: mDelays[RawMagneticField]):
   3287                     (mEnabled & (1 << RawMagneticField)? mDelays[RawMagneticField]: mDelays[MagneticField]));
   3288                 if (!mCompassSensor->isIntegrated()) {
   3289                     wanted = compassWanted;
   3290                 } else {
   3291 #if (0)
   3292                     wanted = compassWanted;
   3293 #else
   3294                     if (GY_ENABLED
   3295                         && (mDelays[Gyro] < compassWanted)) {
   3296                         wanted = mDelays[Gyro];
   3297                     } else if (RGY_ENABLED
   3298                                && mDelays[RawGyro] < compassWanted) {
   3299                         wanted = mDelays[RawGyro];
   3300                     } else if (A_ENABLED && mDelays[Accelerometer]
   3301                                 < compassWanted) {
   3302                         wanted = mDelays[Accelerometer];
   3303                     } else {
   3304                         wanted = compassWanted;
   3305                     }
   3306 #endif
   3307                     LOGV_IF(ENG_VERBOSE, "mFeatureActiveMask=%016llx", mFeatureActiveMask);
   3308                     if (mFeatureActiveMask & DMP_FEATURE_MASK) {
   3309                         //int64_t tempWanted;
   3310                         //getDmpRate(&tempWanted);
   3311                     }
   3312                 }
   3313 
   3314                 mCompassSensor->setDelay(ID_M, wanted);
   3315                 got = mCompassSensor->getDelay(ID_M);
   3316                 inv_set_compass_sample_rate(got / 1000);
   3317                 LOGV_IF(PROCESS_VERBOSE,
   3318                     "HAL:MPL compass sample rate: (mpl)=%d us", int(got/1000LL));
   3319             }
   3320 
   3321             if (PS_ENABLED) {
   3322 #if (0)
   3323                 wanted = mDelays[Pressure];
   3324 #else
   3325                 wanted = mDelays[Pressure];
   3326 #endif
   3327                 LOGV_IF(ENG_VERBOSE, "mFeatureActiveMask=%016llx", mFeatureActiveMask);
   3328                 if (mFeatureActiveMask & DMP_FEATURE_MASK) {
   3329                     //int64_t tempWanted;
   3330                     //getDmpRate(&tempWanted);
   3331                 }
   3332 
   3333                 if (mPressureSensor) {
   3334                     mPressureSensor->setDelay(ID_PS, wanted);
   3335                 } else {
   3336                     LOGV_IF(ENG_VERBOSE, "HAL:PRESSURE sensor not detected");
   3337                 }
   3338                 LOGE_IF(res < 0, "HAL:PRESSURE update delay error");
   3339             }
   3340         }
   3341 
   3342         /* set master sampling frequency */
   3343         /* only use for non multi rate */
   3344         int64_t tempWanted = wanted;
   3345         getDmpRate(&tempWanted);
   3346         /* driver only looks at sampling frequency if DMP is off */
   3347         LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %.0f > %s (%lld)",
   3348                 1000000000.f / tempWanted, mpu.gyro_fifo_rate, getTimestamp());
   3349         tempFd = open(mpu.gyro_fifo_rate, O_RDWR);
   3350         res = write_attribute_sensor(tempFd, 1000000000.f / tempWanted);
   3351             LOGE_IF(res < 0, "HAL:sampling frequency update delay error");
   3352         } //end of non batch mode
   3353 
   3354         unsigned long sensors = mLocalSensorMask & mMasterSensorMask;
   3355         if (sensors &
   3356             (INV_THREE_AXIS_GYRO
   3357                 | INV_THREE_AXIS_ACCEL
   3358                 | (INV_THREE_AXIS_COMPASS * mCompassSensor->isIntegrated()
   3359                 | (INV_ONE_AXIS_PRESSURE * mPressureSensor->isIntegrated())))) {
   3360             LOGV_IF(ENG_VERBOSE, "sensors=%lu", sensors);
   3361             res = masterEnable(1);
   3362             if(res < 0)
   3363                 return res;
   3364         } else { // all sensors idle -> reduce power, unless DMP is needed
   3365             LOGV_IF(ENG_VERBOSE, "mFeatureActiveMask=%016llx", mFeatureActiveMask);
   3366             if(mFeatureActiveMask & DMP_FEATURE_MASK) {
   3367                 res = masterEnable(1);
   3368                 if(res < 0)
   3369                     return res;
   3370             }
   3371         }
   3372     }
   3373 
   3374     return res;
   3375 }
   3376 
   3377 /* For Third Party Accel Input Subsystem Drivers only */
   3378 int MPLSensor::readAccelEvents(sensors_event_t* data, int count)
   3379 {
   3380     VHANDLER_LOG;
   3381 
   3382     if (count < 1)
   3383         return -EINVAL;
   3384 
   3385     ssize_t n = mAccelInputReader.fill(accel_fd);
   3386     if (n < 0) {
   3387         LOGE("HAL:missed accel events, exit");
   3388         return n;
   3389     }
   3390 
   3391     int numEventReceived = 0;
   3392     input_event const* event;
   3393     int nb, done = 0;
   3394 
   3395     while (done == 0 && count && mAccelInputReader.readEvent(&event)) {
   3396         int type = event->type;
   3397         if (type == EV_ABS) {
   3398             if (event->code == EVENT_TYPE_ACCEL_X) {
   3399                 mPendingMask |= 1 << Accelerometer;
   3400                 mCachedAccelData[0] = event->value;
   3401             } else if (event->code == EVENT_TYPE_ACCEL_Y) {
   3402                 mPendingMask |= 1 << Accelerometer;
   3403                 mCachedAccelData[1] = event->value;
   3404             } else if (event->code == EVENT_TYPE_ACCEL_Z) {
   3405                 mPendingMask |= 1 << Accelerometer;
   3406                 mCachedAccelData[2] =event-> value;
   3407             }
   3408         } else if (type == EV_SYN) {
   3409             done = 1;
   3410             if (mLocalSensorMask & INV_THREE_AXIS_ACCEL) {
   3411                 inv_build_accel(mCachedAccelData, 0, getTimestamp());
   3412             }
   3413         } else {
   3414             LOGE("HAL:AccelSensor: unknown event (type=%d, code=%d)",
   3415                     type, event->code);
   3416         }
   3417         mAccelInputReader.next();
   3418     }
   3419 
   3420     return numEventReceived;
   3421 }
   3422 
   3423 /**
   3424  *  Should be called after reading at least one of gyro
   3425  *  compass or accel data. (Also okay for handling all of them).
   3426  *  @returns 0, if successful, error number if not.
   3427  */
   3428 int MPLSensor::readEvents(sensors_event_t* data, int count)
   3429 {
   3430     //VFUNC_LOG;
   3431 
   3432     inv_execute_on_data();
   3433 
   3434     int numEventReceived = 0;
   3435 
   3436     long msg;
   3437     msg = inv_get_message_level_0(1);
   3438     if (msg) {
   3439         if (msg & INV_MSG_MOTION_EVENT) {
   3440             LOGV_IF(PROCESS_VERBOSE, "HAL:**** Motion ****\n");
   3441         }
   3442         if (msg & INV_MSG_NO_MOTION_EVENT) {
   3443             LOGV_IF(PROCESS_VERBOSE, "HAL:***** No Motion *****\n");
   3444             /* after the first no motion, the gyro should be
   3445                calibrated well */
   3446             mGyroAccuracy = SENSOR_STATUS_ACCURACY_HIGH;
   3447             /* if gyros are on and we got a no motion, set a flag
   3448                indicating that the cal file can be written. */
   3449             mHaveGoodMpuCal = true;
   3450         }
   3451         if(msg & INV_MSG_NEW_AB_EVENT) {
   3452             getAccelBias();
   3453             mAccelAccuracy = inv_get_accel_accuracy();
   3454         }
   3455         if(msg & INV_MSG_NEW_GB_EVENT) {
   3456             getGyroBias();
   3457         }
   3458         if(msg & INV_MSG_NEW_FGB_EVENT) {
   3459             getFactoryGyroBias();
   3460         }
   3461         if(msg & INV_MSG_NEW_CB_EVENT) {
   3462             getCompassBias();
   3463             mCompassAccuracy = inv_get_mag_accuracy();
   3464         }
   3465     }
   3466 
   3467     for (int i = 0; i < NumSensors; i++) {
   3468         int update = 0;
   3469         // handle step detector when ped_q is enabled
   3470         if ((i == StepDetector) && (mPedUpdate == 1)) {
   3471             mPedUpdate = 0;
   3472             update = readDmpPedometerEvents(data, count, ID_P, SENSOR_TYPE_STEP_DETECTOR, 1);
   3473             if(update == 1 && count > 0) {
   3474                 data->timestamp = mStepSensorTimestamp;
   3475                 //LOGI("sensor=%d type=%d data=%d", data->sensor, data->type, data->data[0]);
   3476                 count--;
   3477                 numEventReceived++;
   3478                 continue;
   3479             }
   3480         }
   3481 
   3482         // load up virtual sensors
   3483         if (mEnabled & (1 << i)) {
   3484             update = CALL_MEMBER_FN(this, mHandlers[i])(mPendingEvents + i);
   3485             mPendingMask |= (1 << i);
   3486 
   3487             if (update && (count > 0)) {
   3488                 *data++ = mPendingEvents[i];
   3489                 count--;
   3490                 numEventReceived++;
   3491             }
   3492         }
   3493     }
   3494 
   3495     return numEventReceived;
   3496 }
   3497 
   3498 // collect data for MPL (but NOT sensor service currently), from driver layer
   3499 void MPLSensor::buildMpuEvent(void)
   3500 {
   3501     int64_t mGyroSensorTimestamp=0, mAccelSensorTimestamp=0, latestTimestamp=0;
   3502     int lp_quaternion_on = 0, sixAxis_quaternion_on = 0,
   3503         ped_quaternion_on = 0, ped_standalone_on = 0;
   3504     size_t nbyte;
   3505     unsigned short data_format = 0;
   3506     int i, nb, mask = 0,
   3507         sensors = ((mLocalSensorMask & INV_THREE_AXIS_GYRO)? 1 : 0) +
   3508             ((mLocalSensorMask & INV_THREE_AXIS_ACCEL)? 1 : 0) +
   3509             (((mLocalSensorMask & INV_THREE_AXIS_COMPASS)
   3510                 && mCompassSensor->isIntegrated())? 1 : 0) +
   3511             ((mLocalSensorMask & INV_ONE_AXIS_PRESSURE)? 1 : 0);
   3512     //LOGV("mLocalSensorMask=0x%lx", mLocalSensorMask);
   3513     char *rdata = mIIOBuffer;
   3514     ssize_t rsize = 0;
   3515     size_t readCounter = 0;
   3516     char *rdataP = NULL;
   3517 
   3518     /* 2 Bytes header + 6 Bytes x,y,z data | 8 bytes timestamp */
   3519     nbyte= (BYTES_PER_SENSOR + 8) * sensors * 1;
   3520 
   3521     /* special case for 6 Axis or LPQ */
   3522     /* 2 Bytes header + 4 Bytes x data + 2 Bytes n/a */
   3523     /* 4 Bytes y data | 4 Bytes z data */
   3524     /* 8 Bytes timestamp */
   3525     if (isLowPowerQuatEnabled()) {
   3526         lp_quaternion_on = checkLPQuaternion();
   3527         if (lp_quaternion_on == 1) {
   3528             nbyte += BYTES_QUAT_DATA;
   3529         }
   3530     }
   3531 
   3532     if ((sixAxis_quaternion_on = check6AxisQuatEnabled())) {
   3533         // sixAxis is mutually exclusive to LPQ
   3534         // and it is also never enabled when continuous data is enabled
   3535         // mLocalSensorMask does not need to be accounted for here
   3536         // because accel/gyro are turned off anyway
   3537         nbyte += BYTES_QUAT_DATA;
   3538     }
   3539 
   3540     if ((ped_quaternion_on = checkPedQuatEnabled())) {
   3541         nbyte += BYTES_PER_SENSOR_PACKET;
   3542     }
   3543 
   3544     if ((ped_standalone_on = checkPedStandaloneEnabled())) {
   3545         nbyte += BYTES_PER_SENSOR_PACKET;
   3546     }
   3547 
   3548     /* check previous copied buffer */
   3549     /* append with just read data */
   3550     if (mLeftOverBufferSize > 0) {
   3551         LOGV_IF(0, "append old buffer size=%d", mLeftOverBufferSize);
   3552         memcpy(rdata, mLeftOverBuffer, mLeftOverBufferSize);
   3553             LOGV_IF(0,
   3554             "HAL:input retrieve rdata=:%d, %d, %d, %d,%d, %d, %d, %d,%d, %d, "
   3555             "%d, %d,%d, %d, %d, %d\n",
   3556             rdata[0], rdata[1], rdata[2], rdata[3],
   3557             rdata[4], rdata[5], rdata[6], rdata[7],
   3558             rdata[8], rdata[9], rdata[10], rdata[11],
   3559             rdata[12], rdata[13], rdata[14], rdata[15]);
   3560     }
   3561     rdataP = rdata + mLeftOverBufferSize;
   3562 
   3563     /* read expected  number of bytes */
   3564     rsize =  read(iio_fd, rdataP, nbyte);
   3565     if(rsize < 0) {
   3566         /* IIO buffer might have old data.
   3567            Need to flush it when enabling no sensors, to avoid infinite
   3568            read loop.*/
   3569         LOGE("HAL:input data file descriptor not available - (%s)",
   3570              strerror(errno));
   3571         if (sensors == 0) {
   3572             rsize = read(iio_fd, rdata, MAX_SUSPEND_BATCH_PACKET_SIZE);
   3573         }
   3574         return;
   3575     }
   3576 
   3577     /* reset data and count pointer */
   3578     rdataP = rdata;
   3579     readCounter = rsize + mLeftOverBufferSize;
   3580 
   3581 #ifdef TESTING
   3582     LOGV_IF(INPUT_DATA,
   3583          "HAL:input rdataP:r=%ld, n=%d,"
   3584          "%d, %d, %d, %d,%d, %d, %d, %d,%d, %d, %d, %d,%d, %d, %d, %d\n",
   3585          rsize, nbyte,
   3586          rdataP[0], rdataP[1], rdataP[2], rdataP[3],
   3587          rdataP[4], rdataP[5], rdataP[6], rdataP[7],
   3588          rdataP[8], rdataP[9], rdataP[10], rdataP[11],
   3589          rdataP[12], rdataP[13], rdataP[14], rdataP[15]);
   3590 #endif
   3591 
   3592     LOGV_IF(INPUT_DATA && ENG_VERBOSE,
   3593             "HAL:input rdata= %d nbyte= %d rsize= %ld readCounter= %d",
   3594             *((short *) rdata), nbyte, rsize, readCounter);
   3595     LOGV_IF(INPUT_DATA && ENG_VERBOSE,
   3596             "HAL:input sensors= %d, lp_q_on= %d, 6axis_q_on= %d, "
   3597             "ped_q_on= %d, ped_standalone_on= %d",
   3598             sensors, lp_quaternion_on, sixAxis_quaternion_on,
   3599             ped_quaternion_on, ped_standalone_on);
   3600 
   3601     while (readCounter > 0) {
   3602         mLeftOverBufferSize = 0;
   3603         mask = 0;
   3604         data_format = *((short *)(rdata));
   3605         LOGV_IF(INPUT_DATA && ENG_VERBOSE,
   3606                 "HAL:input data_format=%x", data_format);
   3607 
   3608         if ((data_format & ~DATA_FORMAT_MASK) || (data_format == 0)) {
   3609             LOGE("HAL:input invalid data_format 0x%02X", data_format);
   3610             return;
   3611         }
   3612 
   3613         if (data_format & DATA_FORMAT_STEP) {
   3614             LOGV_IF(ENG_VERBOSE, "STEP DETECTED:0x%x", data_format);
   3615             mPedUpdate = 1;
   3616             mask |= DATA_FORMAT_STEP;
   3617             // cancels step bit
   3618             data_format &= (~DATA_FORMAT_STEP);
   3619         }
   3620 
   3621         if (data_format == DATA_FORMAT_QUAT) {
   3622             mCachedQuaternionData[0] = *((int *) (rdata + 4));
   3623             mCachedQuaternionData[1] = *((int *) (rdata + 8));
   3624             mCachedQuaternionData[2] = *((int *) (rdata + 12));
   3625             rdata += QUAT_ONLY_LAST_PACKET_OFFSET;
   3626             mQuatSensorTimestamp = *((long long*) (rdata));
   3627             mask |= DATA_FORMAT_QUAT;
   3628             readCounter -= BYTES_QUAT_DATA;
   3629         }
   3630         else if (data_format == DATA_FORMAT_6_AXIS) {
   3631             mCached6AxisQuaternionData[0] = *((int *) (rdata + 4));
   3632             mCached6AxisQuaternionData[1] = *((int *) (rdata + 8));
   3633             mCached6AxisQuaternionData[2] = *((int *) (rdata + 12));
   3634             rdata += QUAT_ONLY_LAST_PACKET_OFFSET;
   3635             mQuatSensorTimestamp = *((long long*) (rdata));
   3636             mask |= DATA_FORMAT_6_AXIS;
   3637             readCounter -= BYTES_QUAT_DATA;
   3638         }
   3639         else if (data_format == DATA_FORMAT_PED_QUAT) {
   3640             mCachedPedQuaternionData[0] = *((short *) (rdata + 2));
   3641             mCachedPedQuaternionData[1] = *((short *) (rdata + 4));
   3642             mCachedPedQuaternionData[2] = *((short *) (rdata + 6));
   3643             rdata += BYTES_PER_SENSOR;
   3644             mQuatSensorTimestamp = *((long long*) (rdata));
   3645             mask |= DATA_FORMAT_PED_QUAT;
   3646             readCounter -= BYTES_PER_SENSOR_PACKET;
   3647         }
   3648         else if (data_format == DATA_FORMAT_PED_STANDALONE) {
   3649             LOGV_IF(ENG_VERBOSE, "STEP DETECTED:0x%x", data_format);
   3650             rdata += BYTES_PER_SENSOR;
   3651             mStepSensorTimestamp = *((long long*) (rdata));
   3652             mask |= DATA_FORMAT_PED_STANDALONE;
   3653             readCounter -= BYTES_PER_SENSOR_PACKET;
   3654             mPedUpdate = 1;
   3655         }
   3656         else if (data_format == DATA_FORMAT_GYRO) {
   3657             mCachedGyroData[0] = *((short *) (rdata + 2));
   3658             mCachedGyroData[1] = *((short *) (rdata + 4));
   3659             mCachedGyroData[2] = *((short *) (rdata + 6));
   3660             rdata += BYTES_PER_SENSOR;
   3661             mGyroSensorTimestamp = *((long long*) (rdata));
   3662             mask |= DATA_FORMAT_GYRO;
   3663             readCounter -= BYTES_PER_SENSOR_PACKET;
   3664         }
   3665         else if (data_format == DATA_FORMAT_ACCEL) {
   3666             mCachedAccelData[0] = *((short *) (rdata + 2));
   3667             mCachedAccelData[1] = *((short *) (rdata + 4));
   3668             mCachedAccelData[2] = *((short *) (rdata + 6));
   3669             rdata += BYTES_PER_SENSOR;
   3670             mAccelSensorTimestamp = *((long long*) (rdata));
   3671             mask |= DATA_FORMAT_ACCEL;
   3672             readCounter -= BYTES_PER_SENSOR_PACKET;
   3673         }
   3674         else  if (data_format == DATA_FORMAT_COMPASS) {
   3675             if (mCompassSensor->isIntegrated()) {
   3676                 mCachedCompassData[0] = *((short *) (rdata + 2));
   3677                 mCachedCompassData[1] = *((short *) (rdata + 4));
   3678                 mCachedCompassData[2] = *((short *) (rdata + 6));
   3679                 rdata += BYTES_PER_SENSOR;
   3680                 mCompassTimestamp = *((long long*) (rdata));
   3681                 if (mCachedCompassData[0] != 0 || mCachedCompassData[1] != 0
   3682                                                || mCachedCompassData[2] != 0) {
   3683                     mask |= DATA_FORMAT_COMPASS;
   3684                 }
   3685                 readCounter -= BYTES_PER_SENSOR_PACKET;
   3686             }
   3687         }
   3688         else if (data_format == DATA_FORMAT_PRESSURE) {
   3689             if (mPressureSensor->isIntegrated()) {
   3690                 mCachedPressureData =
   3691                     ((*((short *)(rdata + 4))) << 16) +
   3692                     (*((unsigned short *) (rdata + 6)));
   3693                 rdata += BYTES_PER_SENSOR;
   3694                 mPressureTimestamp = *((long long*) (rdata));
   3695                 if (mCachedPressureData!= 0) {
   3696                     mask |= DATA_FORMAT_PRESSURE;
   3697                 }
   3698                 readCounter -= BYTES_PER_SENSOR_PACKET;
   3699             }
   3700         }
   3701         rdata += BYTES_PER_SENSOR;
   3702 
   3703         /* read ahead and store left over data if any */
   3704         if ((readCounter != 0) && (rsize != (ssize_t)nbyte) && (readCounter <= 24)) {
   3705             int counter = readCounter;
   3706             int currentBufferCounter = 0;
   3707             LOGV_IF(0, "!!! not enough data readCounter=%d, expected nbyte=%d", readCounter, nbyte);
   3708             memcpy(mLeftOverBuffer, rdata, readCounter);
   3709             LOGV_IF(0,
   3710                     "HAL:input store rdata=:%d, %d, %d, %d,%d, %d, %d, %d,%d, "
   3711                     "%d, %d, %d,%d, %d, %d, %d\n",
   3712                     mLeftOverBuffer[0], mLeftOverBuffer[1], mLeftOverBuffer[2], mLeftOverBuffer[3],
   3713                     mLeftOverBuffer[4], mLeftOverBuffer[5], mLeftOverBuffer[6], mLeftOverBuffer[7],
   3714                     mLeftOverBuffer[8], mLeftOverBuffer[9], mLeftOverBuffer[10], mLeftOverBuffer[11],
   3715                     mLeftOverBuffer[12],mLeftOverBuffer[13],mLeftOverBuffer[14], mLeftOverBuffer[15]);
   3716 
   3717             mLeftOverBufferSize = readCounter;
   3718             readCounter = 0;
   3719             LOGV_IF(0, "!!! stored number of bytes:%d", mLeftOverBufferSize);
   3720         }
   3721 
   3722         /* handle data read */
   3723         if (mask & DATA_FORMAT_GYRO) {
   3724             /* batch mode does not batch temperature */
   3725             /* disable temperature read */
   3726             if (!(mFeatureActiveMask & INV_DMP_BATCH_MODE)) {
   3727                 // send down temperature every 0.5 seconds
   3728                 // with timestamp measured in "driver" layer
   3729                 if(mGyroSensorTimestamp - mTempCurrentTime >= 500000000LL) {
   3730                     mTempCurrentTime = mGyroSensorTimestamp;
   3731                     long long temperature[2];
   3732                     if(inv_read_temperature(temperature) == 0) {
   3733                         LOGV_IF(INPUT_DATA,
   3734                         "HAL:input inv_read_temperature = %lld, timestamp= %lld",
   3735                         temperature[0], temperature[1]);
   3736                         inv_build_temp(temperature[0], temperature[1]);
   3737                      }
   3738 #ifdef TESTING
   3739                     long bias[3], temp, temp_slope[3];
   3740                     inv_get_mpl_gyro_bias(bias, &temp);
   3741                     inv_get_gyro_ts(temp_slope);
   3742                     LOGI("T: %.3f "
   3743                      "GB: %+13f %+13f %+13f "
   3744                      "TS: %+13f %+13f %+13f "
   3745                      "\n",
   3746                      (float)temperature[0] / 65536.f,
   3747                      (float)bias[0] / 65536.f / 16.384f,
   3748                      (float)bias[1] / 65536.f / 16.384f,
   3749                      (float)bias[2] / 65536.f / 16.384f,
   3750                      temp_slope[0] / 65536.f,
   3751                      temp_slope[1] / 65536.f,
   3752                      temp_slope[2] / 65536.f);
   3753 #endif
   3754                 }
   3755             }
   3756             mPendingMask |= 1 << Gyro;
   3757             mPendingMask |= 1 << RawGyro;
   3758 
   3759             if (mLocalSensorMask & INV_THREE_AXIS_GYRO) {
   3760                 inv_build_gyro(mCachedGyroData, mGyroSensorTimestamp);
   3761                 LOGV_IF(INPUT_DATA,
   3762                         "HAL:input inv_build_gyro: %+8d %+8d %+8d - %lld",
   3763                         mCachedGyroData[0], mCachedGyroData[1],
   3764                         mCachedGyroData[2], mGyroSensorTimestamp);
   3765            }
   3766            latestTimestamp = mGyroSensorTimestamp;
   3767         }
   3768 
   3769         if (mask & DATA_FORMAT_ACCEL) {
   3770             mPendingMask |= 1 << Accelerometer;
   3771             if (mLocalSensorMask & INV_THREE_AXIS_ACCEL) {
   3772                 inv_build_accel(mCachedAccelData, 0, mAccelSensorTimestamp);
   3773                  LOGV_IF(INPUT_DATA,
   3774                     "HAL:input inv_build_accel: %+8ld %+8ld %+8ld - %lld",
   3775                     mCachedAccelData[0], mCachedAccelData[1],
   3776                     mCachedAccelData[2], mAccelSensorTimestamp);
   3777             }
   3778             latestTimestamp = mAccelSensorTimestamp;
   3779         }
   3780 
   3781         if ((mask & DATA_FORMAT_COMPASS) && mCompassSensor->isIntegrated()) {
   3782             int status = 0;
   3783             if (mCompassSensor->providesCalibration()) {
   3784                 status = mCompassSensor->getAccuracy();
   3785                 status |= INV_CALIBRATED;
   3786             }
   3787             if (mLocalSensorMask & INV_THREE_AXIS_COMPASS) {
   3788             inv_build_compass(mCachedCompassData, status,
   3789                               mCompassTimestamp);
   3790             LOGV_IF(INPUT_DATA,
   3791                     "HAL:input inv_build_compass: %+8ld %+8ld %+8ld - %lld",
   3792                     mCachedCompassData[0], mCachedCompassData[1],
   3793                     mCachedCompassData[2], mCompassTimestamp);
   3794             }
   3795             latestTimestamp = mCompassTimestamp;
   3796         }
   3797 
   3798         if (isLowPowerQuatEnabled() && lp_quaternion_on == 1
   3799                                 && (mask & DATA_FORMAT_QUAT)) {
   3800             /* if bias was applied to DMP bias,
   3801                set status bits to disable gyro bias cal */
   3802             int status = 0;
   3803             if (mGyroBiasApplied == true) {
   3804                 LOGV_IF(INPUT_DATA, "HAL:input mpl bias not used");
   3805                 status |= INV_BIAS_APPLIED;
   3806                 mGyroBiasApplied = false;
   3807             }
   3808             status |= 32 | INV_QUAT_3AXIS; /* default 32 (16/32bits) */
   3809             inv_build_quat(mCachedQuaternionData,
   3810                        status,
   3811                        mQuatSensorTimestamp);
   3812             LOGV_IF(INPUT_DATA,
   3813                     "HAL:input inv_build_quat: %+8ld %+8ld %+8ld - %lld",
   3814                     mCachedQuaternionData[0], mCachedQuaternionData[1],
   3815                     mCachedQuaternionData[2],
   3816                     mQuatSensorTimestamp);
   3817             latestTimestamp = mQuatSensorTimestamp;
   3818         }
   3819 
   3820         if ((mask & DATA_FORMAT_6_AXIS) && check6AxisQuatEnabled()
   3821                                     && (sixAxis_quaternion_on == 1)) {
   3822             /* if bias was applied to DMP bias,
   3823                set status bits to disable gyro bias cal */
   3824             int status = 0;
   3825             if (mGyroBiasApplied == true) {
   3826                 status |= INV_QUAT_6AXIS;
   3827                 mGyroBiasApplied = false;
   3828             }
   3829             status |= 32 | INV_QUAT_3AXIS; /* default 32 (16/32bits) */
   3830             inv_build_quat(mCached6AxisQuaternionData,
   3831                        status,
   3832                        mQuatSensorTimestamp);
   3833             LOGV_IF(INPUT_DATA,
   3834                 "HAL:input 6 axis ped quat: %+8ld %+8ld %+8ld - %lld",
   3835                 mCached6AxisQuaternionData[0], mCached6AxisQuaternionData[1],
   3836                 mCached6AxisQuaternionData[2],
   3837                 mQuatSensorTimestamp);
   3838             latestTimestamp = mQuatSensorTimestamp;
   3839         }
   3840 
   3841         if ((mask & DATA_FORMAT_PED_QUAT) && checkPedQuatEnabled()
   3842                                           && (ped_quaternion_on == 1)) {
   3843             /* if bias was applied to DMP bias,
   3844                set status bits to disable gyro bias cal */
   3845             int status = 0;
   3846             if (mGyroBiasApplied == true) {
   3847                 status |= INV_QUAT_6AXIS;
   3848                 mGyroBiasApplied = false;
   3849             }
   3850             status |= 32 | INV_QUAT_3AXIS; /* default 32 (16/32bits) */
   3851             inv_build_quat(mCachedPedQuaternionData,
   3852                        status,
   3853                        mQuatSensorTimestamp);
   3854 
   3855             LOGV_IF(INPUT_DATA,
   3856             "HAL:input ped quat: %+8ld %+8ld %+8ld - %lld",
   3857             mCachedPedQuaternionData[0], mCachedPedQuaternionData[1],
   3858             mCachedPedQuaternionData[2],
   3859             mQuatSensorTimestamp);
   3860             latestTimestamp = mQuatSensorTimestamp;
   3861         }
   3862 
   3863         if ((mask & DATA_FORMAT_PRESSURE) && mPressureSensor->isIntegrated()) {
   3864             int status = 0;
   3865             if (mLocalSensorMask & INV_ONE_AXIS_PRESSURE) {
   3866 
   3867             LOGV_IF(INPUT_DATA,
   3868                     "HAL:input inv_build_pressure: %+8ld - %lld",
   3869                     mCachedPressureData, mPressureTimestamp);
   3870             }
   3871             latestTimestamp = mPressureTimestamp;
   3872         }
   3873 
   3874         /* take the latest timestamp */
   3875         if (mask & DATA_FORMAT_STEP) {
   3876             mStepSensorTimestamp = latestTimestamp;
   3877         }
   3878    }//while end
   3879 }
   3880 
   3881 /* use for both MPUxxxx and third party compass */
   3882 void MPLSensor::buildCompassEvent(void)
   3883 {
   3884     VHANDLER_LOG;
   3885 
   3886     int done = 0;
   3887 
   3888     // pthread_mutex_lock(&mMplMutex);
   3889     // pthread_mutex_lock(&mHALMutex);
   3890 
   3891     done = mCompassSensor->readSample(mCachedCompassData, &mCompassTimestamp);
   3892     if(mCompassSensor->isYasCompass()) {
   3893         if (mCompassSensor->checkCoilsReset() == 1) {
   3894            //Reset relevant compass settings
   3895            resetCompass();
   3896         }
   3897     }
   3898     if (done > 0) {
   3899         int status = 0;
   3900         if (mCompassSensor->providesCalibration()) {
   3901             status = mCompassSensor->getAccuracy();
   3902             status |= INV_CALIBRATED;
   3903         }
   3904         if (mLocalSensorMask & INV_THREE_AXIS_COMPASS) {
   3905             inv_build_compass(mCachedCompassData, status,
   3906                               mCompassTimestamp);
   3907             LOGV_IF(INPUT_DATA,
   3908                     "HAL:input inv_build_compass: %+8ld %+8ld %+8ld - %lld",
   3909                     mCachedCompassData[0], mCachedCompassData[1],
   3910                     mCachedCompassData[2], mCompassTimestamp);
   3911         }
   3912     }
   3913 
   3914     // pthread_mutex_unlock(&mMplMutex);
   3915     // pthread_mutex_unlock(&mHALMutex);
   3916 }
   3917 
   3918 int MPLSensor::resetCompass(void)
   3919 {
   3920     VFUNC_LOG;
   3921 
   3922     //Reset compass cal if enabled
   3923     if (mMplFeatureActiveMask & INV_COMPASS_CAL) {
   3924        LOGV_IF(EXTRA_VERBOSE, "HAL:Reset compass cal");
   3925        inv_init_vector_compass_cal();
   3926     }
   3927 
   3928     //Reset compass fit if enabled
   3929     if (mMplFeatureActiveMask & INV_COMPASS_FIT) {
   3930        LOGV_IF(EXTRA_VERBOSE, "HAL:Reset compass fit");
   3931        inv_init_compass_fit();
   3932     }
   3933 
   3934     return 0;
   3935 }
   3936 
   3937 int MPLSensor::getFd(void) const
   3938 {
   3939     VFUNC_LOG;
   3940     LOGV_IF(EXTRA_VERBOSE, "MPLSensor::getFd returning %d", iio_fd);
   3941     return iio_fd;
   3942 }
   3943 
   3944 int MPLSensor::getAccelFd(void) const
   3945 {
   3946     VFUNC_LOG;
   3947     LOGV_IF(EXTRA_VERBOSE, "MPLSensor::getAccelFd returning %d", accel_fd);
   3948     return accel_fd;
   3949 }
   3950 
   3951 int MPLSensor::getCompassFd(void) const
   3952 {
   3953     VFUNC_LOG;
   3954     int fd = mCompassSensor->getFd();
   3955     LOGV_IF(EXTRA_VERBOSE, "MPLSensor::getCompassFd returning %d", fd);
   3956     return fd;
   3957 }
   3958 
   3959 int MPLSensor::turnOffAccelFifo(void)
   3960 {
   3961     int i, res = 0, tempFd;
   3962     LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)",
   3963                         0, mpu.accel_fifo_enable, getTimestamp());
   3964     res += write_sysfs_int(mpu.accel_fifo_enable, 0);
   3965     return res;
   3966 }
   3967 
   3968 int MPLSensor::turnOffGyroFifo(void)
   3969 {
   3970     int i, res = 0, tempFd;
   3971     LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)",
   3972                         0, mpu.gyro_fifo_enable, getTimestamp());
   3973     res += write_sysfs_int(mpu.gyro_fifo_enable, 0);
   3974     return res;
   3975 }
   3976 
   3977 int MPLSensor::enableDmpOrientation(int en)
   3978 {
   3979     VFUNC_LOG;
   3980     int res = 0;
   3981     int enabled_sensors = mEnabled;
   3982 
   3983     if (isMpuNonDmp())
   3984         return res;
   3985 
   3986     // reset master enable
   3987     res = masterEnable(0);
   3988     if (res < 0)
   3989         return res;
   3990 
   3991     if (en == 1) {
   3992         //Enable DMP orientation
   3993         LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)",
   3994                 en, mpu.display_orientation_on, getTimestamp());
   3995         if (write_sysfs_int(mpu.display_orientation_on, en) < 0) {
   3996             LOGE("HAL:ERR can't enable Android orientation");
   3997             res = -1;	// indicate an err
   3998             return res;
   3999         }
   4000 
   4001         // enable DMP
   4002         res = onDmp(1);
   4003         if (res < 0)
   4004             return res;
   4005 
   4006         // set rate to 200Hz
   4007         LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)",
   4008                 200, mpu.accel_fifo_rate, getTimestamp());
   4009         if (write_sysfs_int(mpu.accel_fifo_rate, 200) < 0) {
   4010             res = -1;
   4011             LOGE("HAL:ERR can't set rate to 200Hz");
   4012             return res;
   4013         }
   4014 
   4015         // enable accel engine
   4016         res = enableAccel(1);
   4017         if (res < 0)
   4018             return res;
   4019 
   4020         // disable accel FIFO
   4021         if (!(mLocalSensorMask & mMasterSensorMask & INV_THREE_AXIS_ACCEL)) {
   4022             res = turnOffAccelFifo();
   4023             if (res < 0)
   4024                 return res;
   4025         }
   4026 
   4027         if (!mEnabled){
   4028             LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)",
   4029                        1, mpu.dmp_event_int_on, getTimestamp());
   4030             if (write_sysfs_int(mpu.dmp_event_int_on, en) < 0) {
   4031                 res = -1;
   4032                 LOGE("HAL:ERR can't enable DMP event interrupt");
   4033             }
   4034         }
   4035 
   4036         mFeatureActiveMask |= INV_DMP_DISPL_ORIENTATION;
   4037         LOGV_IF(ENG_VERBOSE, "mFeatureActiveMask=%016llx", mFeatureActiveMask);
   4038     } else {
   4039         mFeatureActiveMask &= ~INV_DMP_DISPL_ORIENTATION;
   4040         // disable DMP
   4041         if (mFeatureActiveMask == 0) {
   4042             res = onDmp(0);
   4043             if (res < 0)
   4044                 return res;
   4045 
   4046             // disable accel engine
   4047             if (!(mLocalSensorMask & mMasterSensorMask
   4048                     & INV_THREE_AXIS_ACCEL)) {
   4049                 res = enableAccel(0);
   4050                 if (res < 0)
   4051                     return res;
   4052             }
   4053         }
   4054 
   4055         if (mEnabled){
   4056             LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)",
   4057                        en, mpu.dmp_event_int_on, getTimestamp());
   4058             if (write_sysfs_int(mpu.dmp_event_int_on, en) < 0) {
   4059                 res = -1;
   4060                 LOGE("HAL:ERR can't enable DMP event interrupt");
   4061             }
   4062         }
   4063         LOGV_IF(ENG_VERBOSE, "mFeatureActiveMask=%016llx", mFeatureActiveMask);
   4064     }
   4065 
   4066     if (en || mEnabled || mFeatureActiveMask) {
   4067         res = masterEnable(1);
   4068     }
   4069     return res;
   4070 }
   4071 
   4072 int MPLSensor::openDmpOrientFd(void)
   4073 {
   4074     VFUNC_LOG;
   4075 
   4076     if (!isDmpDisplayOrientationOn() || dmp_orient_fd >= 0) {
   4077         LOGV_IF(PROCESS_VERBOSE,
   4078                 "HAL:DMP display orientation disabled or file desc opened");
   4079         return 0;
   4080     }
   4081 
   4082     dmp_orient_fd = open(mpu.event_display_orientation, O_RDONLY| O_NONBLOCK);
   4083     if (dmp_orient_fd < 0) {
   4084         LOGE("HAL:ERR couldn't open dmpOrient node");
   4085         return -1;
   4086     } else {
   4087         LOGV_IF(PROCESS_VERBOSE,
   4088                 "HAL:dmp_orient_fd opened : %d", dmp_orient_fd);
   4089         return 0;
   4090     }
   4091 }
   4092 
   4093 int MPLSensor::closeDmpOrientFd(void)
   4094 {
   4095     VFUNC_LOG;
   4096     if (dmp_orient_fd >= 0)
   4097         close(dmp_orient_fd);
   4098     return 0;
   4099 }
   4100 
   4101 int MPLSensor::dmpOrientHandler(int orient)
   4102 {
   4103     VFUNC_LOG;
   4104     LOGV_IF(PROCESS_VERBOSE, "HAL:orient %x", orient);
   4105     return 0;
   4106 }
   4107 
   4108 int MPLSensor::readDmpOrientEvents(sensors_event_t* data, int count)
   4109 {
   4110     VFUNC_LOG;
   4111 
   4112     char dummy[4];
   4113     int screen_orientation = 0;
   4114     FILE *fp;
   4115 
   4116     fp = fopen(mpu.event_display_orientation, "r");
   4117     if (fp == NULL) {
   4118         LOGE("HAL:cannot open event_display_orientation");
   4119         return 0;
   4120     }
   4121     fscanf(fp, "%d\n", &screen_orientation);
   4122     fclose(fp);
   4123 
   4124     int numEventReceived = 0;
   4125 
   4126     if (mDmpOrientationEnabled && count > 0) {
   4127         sensors_event_t temp;
   4128 
   4129         temp.version = sizeof(sensors_event_t);
   4130         temp.sensor = ID_SO;
   4131         temp.acceleration.status
   4132             = SENSOR_STATUS_UNRELIABLE;
   4133 #ifdef ENABLE_DMP_SCREEN_AUTO_ROTATION
   4134         temp.type = SENSOR_TYPE_SCREEN_ORIENTATION;
   4135         temp.screen_orientation = screen_orientation;
   4136 #endif
   4137         struct timespec ts;
   4138         clock_gettime(CLOCK_MONOTONIC, &ts);
   4139         temp.timestamp = (int64_t) ts.tv_sec * 1000000000 + ts.tv_nsec;
   4140 
   4141         *data++ = temp;
   4142         count--;
   4143         numEventReceived++;
   4144     }
   4145 
   4146     // read dummy data per driver's request
   4147     dmpOrientHandler(screen_orientation);
   4148     read(dmp_orient_fd, dummy, 4);
   4149 
   4150     return numEventReceived;
   4151 }
   4152 
   4153 int MPLSensor::getDmpOrientFd(void)
   4154 {
   4155     VFUNC_LOG;
   4156 
   4157     LOGV_IF(EXTRA_VERBOSE,
   4158             "MPLSensor::getDmpOrientFd returning %d", dmp_orient_fd);
   4159     return dmp_orient_fd;
   4160 
   4161 }
   4162 
   4163 int MPLSensor::checkDMPOrientation(void)
   4164 {
   4165     VFUNC_LOG;
   4166     return ((mFeatureActiveMask & INV_DMP_DISPL_ORIENTATION) ? 1 : 0);
   4167 }
   4168 
   4169 int MPLSensor::getDmpRate(int64_t *wanted)
   4170 {
   4171     VFUNC_LOG;
   4172 
   4173       // set DMP output rate to FIFO
   4174       if(mDmpOn == 1) {
   4175         LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)",
   4176                 int(1000000000.f / *wanted), mpu.three_axis_q_rate,
   4177                 getTimestamp());
   4178         write_sysfs_int(mpu.three_axis_q_rate, 1000000000.f / *wanted);
   4179         LOGV_IF(PROCESS_VERBOSE,
   4180                 "HAL:DMP three axis rate %.2f Hz", 1000000000.f / *wanted);
   4181 
   4182         LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)",
   4183                 int(1000000000.f / *wanted), mpu.six_axis_q_rate,
   4184                 getTimestamp());
   4185         write_sysfs_int(mpu.six_axis_q_rate, 1000000000.f / *wanted);
   4186         LOGV_IF(PROCESS_VERBOSE,
   4187                 "HAL:DMP six axis rate %.2f Hz", 1000000000.f / *wanted);
   4188 
   4189         LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)",
   4190                 int(1000000000.f / *wanted), mpu.ped_q_rate,
   4191                 getTimestamp());
   4192         write_sysfs_int(mpu.ped_q_rate, 1000000000.f / *wanted);
   4193         LOGV_IF(PROCESS_VERBOSE,
   4194                 "HAL:DMP ped quaternion rate %.2f Hz", 1000000000.f / *wanted);
   4195 
   4196         //DMP running rate must be @ 200Hz
   4197         *wanted= RATE_200HZ;
   4198         LOGV_IF(PROCESS_VERBOSE,
   4199                 "HAL:DMP rate= %.2f Hz", 1000000000.f / *wanted);
   4200     }
   4201     return 0;
   4202 }
   4203 
   4204 int MPLSensor::getPollTime(void)
   4205 {
   4206     VHANDLER_LOG;
   4207     return mPollTime;
   4208 }
   4209 
   4210 int MPLSensor::getStepCountPollTime(void)
   4211 {
   4212     VHANDLER_LOG;
   4213     if (mDmpStepCountEnabled) {
   4214     /* clamped to 1ms?, still rather large */
   4215     LOGV_IF(0/*EXTRA_VERBOSE*/, "Step Count poll time = %lld ms",
   4216             mStepCountPollTime / 1000000LL);
   4217         return (mStepCountPollTime / 1000000LL);
   4218     }
   4219     return -1;
   4220 }
   4221 
   4222 bool MPLSensor::hasStepCountPendingEvents(void)
   4223 {
   4224     VHANDLER_LOG;
   4225     if (mDmpStepCountEnabled) {
   4226         struct timespec t_now;
   4227         int64_t interval = 0;
   4228 
   4229         clock_gettime(CLOCK_MONOTONIC, &t_now);
   4230         interval = ((int64_t(t_now.tv_sec) * 1000000000LL + t_now.tv_nsec) -
   4231                     (int64_t(mt_pre.tv_sec) * 1000000000LL + mt_pre.tv_nsec));
   4232 
   4233         if (interval < mStepCountPollTime) {
   4234             LOGV_IF(0/*ENG_VERBOSE*/,
   4235                     "Step Count interval elapsed: %lld, triggered: %d",
   4236                     interval, mStepCountPollTime);
   4237             return false;
   4238         } else {
   4239             clock_gettime(CLOCK_MONOTONIC, &mt_pre);
   4240             LOGV_IF(0/*ENG_VERBOSE*/, "Step Count previous time: %ld ms",
   4241                     mt_pre.tv_nsec / 1000);
   4242             return true;
   4243         }
   4244     }
   4245     return false;
   4246 }
   4247 
   4248 bool MPLSensor::hasPendingEvents(void) const
   4249 {
   4250     VHANDLER_LOG;
   4251     // if we are using the polling workaround, force the main
   4252     // loop to check for data every time
   4253     return (mPollTime != -1);
   4254 }
   4255 
   4256 /* TODO: support resume suspend when we gain more info about them*/
   4257 void MPLSensor::sleepEvent(void)
   4258 {
   4259     VFUNC_LOG;
   4260 }
   4261 
   4262 void MPLSensor::wakeEvent(void)
   4263 {
   4264     VFUNC_LOG;
   4265 }
   4266 
   4267 int MPLSensor::inv_float_to_q16(float *fdata, long *ldata)
   4268 {
   4269     VHANDLER_LOG;
   4270 
   4271     if (!fdata || !ldata)
   4272         return -1;
   4273     ldata[0] = (long)(fdata[0] * 65536.f);
   4274     ldata[1] = (long)(fdata[1] * 65536.f);
   4275     ldata[2] = (long)(fdata[2] * 65536.f);
   4276     return 0;
   4277 }
   4278 
   4279 int MPLSensor::inv_long_to_q16(long *fdata, long *ldata)
   4280 {
   4281     VHANDLER_LOG;
   4282 
   4283     if (!fdata || !ldata)
   4284         return -1;
   4285     ldata[0] = (fdata[1] * 65536.f);
   4286     ldata[1] = (fdata[2] * 65536.f);
   4287     ldata[2] = (fdata[3] * 65536.f);
   4288     return 0;
   4289 }
   4290 
   4291 int MPLSensor::inv_float_to_round(float *fdata, long *ldata)
   4292 {
   4293     VHANDLER_LOG;
   4294 
   4295     if (!fdata || !ldata)
   4296             return -1;
   4297     ldata[0] = (long)fdata[0];
   4298     ldata[1] = (long)fdata[1];
   4299     ldata[2] = (long)fdata[2];
   4300     return 0;
   4301 }
   4302 
   4303 int MPLSensor::inv_float_to_round2(float *fdata, short *ldata)
   4304 {
   4305     VHANDLER_LOG;
   4306 
   4307     if (!fdata || !ldata)
   4308         return -1;
   4309     ldata[0] = (short)fdata[0];
   4310     ldata[1] = (short)fdata[1];
   4311     ldata[2] = (short)fdata[2];
   4312     return 0;
   4313 }
   4314 
   4315 int MPLSensor::inv_long_to_float(long *ldata, float *fdata)
   4316 {
   4317     VHANDLER_LOG;
   4318 
   4319     if (!ldata || !fdata)
   4320         return -1;
   4321     fdata[0] = (float)ldata[0];
   4322     fdata[1] = (float)ldata[1];
   4323     fdata[2] = (float)ldata[2];
   4324     return 0;
   4325 }
   4326 
   4327 int MPLSensor::inv_read_temperature(long long *data)
   4328 {
   4329     VHANDLER_LOG;
   4330 
   4331     int count = 0;
   4332     char raw_buf[40];
   4333     long raw = 0;
   4334 
   4335     long long timestamp = 0;
   4336 
   4337     memset(raw_buf, 0, sizeof(raw_buf));
   4338     count = read_attribute_sensor(gyro_temperature_fd, raw_buf,
   4339                                   sizeof(raw_buf));
   4340     if(count < 1) {
   4341         LOGE("HAL:error reading gyro temperature");
   4342         return -1;
   4343     }
   4344 
   4345     count = sscanf(raw_buf, "%ld%lld", &raw, &timestamp);
   4346 
   4347     if(count < 0) {
   4348         return -1;
   4349     }
   4350 
   4351     LOGV_IF(ENG_VERBOSE,
   4352             "HAL:temperature raw = %ld, timestamp = %lld, count = %d",
   4353             raw, timestamp, count);
   4354     data[0] = raw;
   4355     data[1] = timestamp;
   4356 
   4357     return 0;
   4358 }
   4359 
   4360 int MPLSensor::inv_read_dmp_state(int fd)
   4361 {
   4362     VFUNC_LOG;
   4363 
   4364     if(fd < 0)
   4365         return -1;
   4366 
   4367     int count = 0;
   4368     char raw_buf[10];
   4369     short raw = 0;
   4370 
   4371     memset(raw_buf, 0, sizeof(raw_buf));
   4372     count = read_attribute_sensor(fd, raw_buf, sizeof(raw_buf));
   4373     if(count < 1) {
   4374         LOGE("HAL:error reading dmp state");
   4375         close(fd);
   4376         return -1;
   4377     }
   4378     count = sscanf(raw_buf, "%hd", &raw);
   4379     if(count < 0) {
   4380         LOGE("HAL:dmp state data is invalid");
   4381         close(fd);
   4382         return -1;
   4383     }
   4384     LOGV_IF(EXTRA_VERBOSE, "HAL:dmp state = %d, count = %d", raw, count);
   4385     close(fd);
   4386     return (int)raw;
   4387 }
   4388 
   4389 int MPLSensor::inv_read_sensor_bias(int fd, long *data)
   4390 {
   4391     VFUNC_LOG;
   4392 
   4393     if(fd == -1) {
   4394         return -1;
   4395     }
   4396 
   4397     char buf[50];
   4398     char x[15], y[15], z[15];
   4399 
   4400     memset(buf, 0, sizeof(buf));
   4401     int count = read_attribute_sensor(fd, buf, sizeof(buf));
   4402     if(count < 1) {
   4403         LOGE("HAL:Error reading gyro bias");
   4404         return -1;
   4405     }
   4406     count = sscanf(buf, "%[^','],%[^','],%[^',']", x, y, z);
   4407     if(count) {
   4408         /* scale appropriately for MPL */
   4409         LOGV_IF(ENG_VERBOSE,
   4410                 "HAL:pre-scaled bias: X:Y:Z (%ld, %ld, %ld)",
   4411                 atol(x), atol(y), atol(z));
   4412 
   4413         data[0] = (long)(atol(x) / 10000 * (1L << 16));
   4414         data[1] = (long)(atol(y) / 10000 * (1L << 16));
   4415         data[2] = (long)(atol(z) / 10000 * (1L << 16));
   4416 
   4417         LOGV_IF(ENG_VERBOSE,
   4418                 "HAL:scaled bias: X:Y:Z (%ld, %ld, %ld)",
   4419                 data[0], data[1], data[2]);
   4420     }
   4421     return 0;
   4422 }
   4423 
   4424 /** fill in the sensor list based on which sensors are configured.
   4425  *  return the number of configured sensors.
   4426  *  parameter list must point to a memory region of at least 7*sizeof(sensor_t)
   4427  *  parameter len gives the length of the buffer pointed to by list
   4428  */
   4429 int MPLSensor::populateSensorList(struct sensor_t *list, int len)
   4430 {
   4431     VFUNC_LOG;
   4432 
   4433     int numsensors;
   4434 
   4435     if(len <
   4436         (int)((sizeof(sSensorList) / sizeof(sensor_t)) * sizeof(sensor_t))) {
   4437         LOGE("HAL:sensor list too small, not populating.");
   4438         return -(sizeof(sSensorList) / sizeof(sensor_t));
   4439     }
   4440 
   4441     /* fill in the base values */
   4442     memcpy(list, sSensorList,
   4443            sizeof (struct sensor_t) * (sizeof(sSensorList) / sizeof(sensor_t)));
   4444 
   4445     /* first add gyro, accel and compass to the list */
   4446 
   4447     /* fill in gyro/accel values */
   4448     if(chip_ID == NULL) {
   4449         LOGE("HAL:Can not get gyro/accel id");
   4450     }
   4451     fillGyro(chip_ID, list);
   4452     fillAccel(chip_ID, list);
   4453 
   4454     // TODO: need fixes for unified HAL and 3rd-party solution
   4455     mCompassSensor->fillList(&list[MagneticField]);
   4456     mCompassSensor->fillList(&list[RawMagneticField]);
   4457 
   4458     if(1) {
   4459         numsensors = (sizeof(sSensorList) / sizeof(sensor_t));
   4460         /* all sensors will be added to the list
   4461            fill in orientation values */
   4462         fillOrientation(list);
   4463         /* fill in rotation vector values */
   4464         fillRV(list);
   4465         /* fill in game rotation vector values */
   4466         fillGRV(list);
   4467         /* fill in gravity values */
   4468         fillGravity(list);
   4469         /* fill in Linear accel values */
   4470         fillLinearAccel(list);
   4471         /* fill in Significant motion values */
   4472         fillSignificantMotion(list);
   4473 #ifdef ENABLE_DMP_SCREEN_AUTO_ROTATION
   4474         /* fill in screen orientation values */
   4475         fillScreenOrientation(list);
   4476 #endif
   4477     } else {
   4478         /* no 9-axis sensors, zero fill that part of the list */
   4479         numsensors = 3;
   4480         memset(list + 3, 0, 4 * sizeof(struct sensor_t));
   4481     }
   4482 
   4483     return numsensors;
   4484 }
   4485 
   4486 void MPLSensor::fillAccel(const char* accel, struct sensor_t *list)
   4487 {
   4488     VFUNC_LOG;
   4489 
   4490     if (accel) {
   4491         if(accel != NULL && strcmp(accel, "BMA250") == 0) {
   4492             list[Accelerometer].maxRange = ACCEL_BMA250_RANGE;
   4493             list[Accelerometer].resolution = ACCEL_BMA250_RESOLUTION;
   4494             list[Accelerometer].power = ACCEL_BMA250_POWER;
   4495             list[Accelerometer].minDelay = ACCEL_BMA250_MINDELAY;
   4496             return;
   4497         } else if (accel != NULL && strcmp(accel, "MPU6050") == 0) {
   4498             list[Accelerometer].maxRange = ACCEL_MPU6050_RANGE;
   4499             list[Accelerometer].resolution = ACCEL_MPU6050_RESOLUTION;
   4500             list[Accelerometer].power = ACCEL_MPU6050_POWER;
   4501             list[Accelerometer].minDelay = ACCEL_MPU6050_MINDELAY;
   4502             return;
   4503         } else if (accel != NULL && strcmp(accel, "MPU6500") == 0) {
   4504             list[Accelerometer].maxRange = ACCEL_MPU6500_RANGE;
   4505             list[Accelerometer].resolution = ACCEL_MPU6500_RESOLUTION;
   4506             list[Accelerometer].power = ACCEL_MPU6500_POWER;
   4507             list[Accelerometer].minDelay = ACCEL_MPU6500_MINDELAY;
   4508             return;
   4509          } else if (accel != NULL && strcmp(accel, "MPU6515") == 0) {
   4510             list[Accelerometer].maxRange = ACCEL_MPU6500_RANGE;
   4511             list[Accelerometer].resolution = ACCEL_MPU6500_RESOLUTION;
   4512             list[Accelerometer].power = ACCEL_MPU6500_POWER;
   4513             list[Accelerometer].minDelay = ACCEL_MPU6500_MINDELAY;
   4514             return;
   4515         } else if (accel != NULL && strcmp(accel, "MPU6500") == 0) {
   4516             list[Accelerometer].maxRange = ACCEL_MPU6500_RANGE;
   4517             list[Accelerometer].resolution = ACCEL_MPU6500_RESOLUTION;
   4518             list[Accelerometer].power = ACCEL_MPU6500_POWER;
   4519             list[Accelerometer].minDelay = ACCEL_MPU6500_MINDELAY;
   4520             return;
   4521         } else if (accel != NULL && strcmp(accel, "MPU6500") == 0) {
   4522             list[Accelerometer].maxRange = ACCEL_MPU6500_RANGE;
   4523             list[Accelerometer].resolution = ACCEL_MPU6500_RESOLUTION;
   4524             list[Accelerometer].power = ACCEL_MPU6500_POWER;
   4525             list[Accelerometer].minDelay = ACCEL_MPU6500_MINDELAY;
   4526             return;
   4527         } else if (accel != NULL && strcmp(accel, "MPU9150") == 0) {
   4528             list[Accelerometer].maxRange = ACCEL_MPU9150_RANGE;
   4529             list[Accelerometer].resolution = ACCEL_MPU9150_RESOLUTION;
   4530             list[Accelerometer].power = ACCEL_MPU9150_POWER;
   4531             list[Accelerometer].minDelay = ACCEL_MPU9150_MINDELAY;
   4532             return;
   4533         } else if (accel != NULL && strcmp(accel, "MPU3050") == 0) {
   4534             list[Accelerometer].maxRange = ACCEL_BMA250_RANGE;
   4535             list[Accelerometer].resolution = ACCEL_BMA250_RESOLUTION;
   4536             list[Accelerometer].power = ACCEL_BMA250_POWER;
   4537             list[Accelerometer].minDelay = ACCEL_BMA250_MINDELAY;
   4538             return;
   4539         }
   4540     }
   4541 
   4542     LOGE("HAL:unknown accel id %s -- "
   4543          "params default to bma250 and might be wrong.",
   4544          accel);
   4545     list[Accelerometer].maxRange = ACCEL_BMA250_RANGE;
   4546     list[Accelerometer].resolution = ACCEL_BMA250_RESOLUTION;
   4547     list[Accelerometer].power = ACCEL_BMA250_POWER;
   4548     list[Accelerometer].minDelay = ACCEL_BMA250_MINDELAY;
   4549 }
   4550 
   4551 void MPLSensor::fillGyro(const char* gyro, struct sensor_t *list)
   4552 {
   4553     VFUNC_LOG;
   4554 
   4555     if ( gyro != NULL && strcmp(gyro, "MPU3050") == 0) {
   4556         list[Gyro].maxRange = GYRO_MPU3050_RANGE;
   4557         list[Gyro].resolution = GYRO_MPU3050_RESOLUTION;
   4558         list[Gyro].power = GYRO_MPU3050_POWER;
   4559         list[Gyro].minDelay = GYRO_MPU3050_MINDELAY;
   4560     } else if( gyro != NULL && strcmp(gyro, "MPU6050") == 0) {
   4561         list[Gyro].maxRange = GYRO_MPU6050_RANGE;
   4562         list[Gyro].resolution = GYRO_MPU6050_RESOLUTION;
   4563         list[Gyro].power = GYRO_MPU6050_POWER;
   4564         list[Gyro].minDelay = GYRO_MPU6050_MINDELAY;
   4565     } else if( gyro != NULL && strcmp(gyro, "MPU6500") == 0) {
   4566         list[Gyro].maxRange = GYRO_MPU6500_RANGE;
   4567         list[Gyro].resolution = GYRO_MPU6500_RESOLUTION;
   4568         list[Gyro].power = GYRO_MPU6500_POWER;
   4569         list[Gyro].minDelay = GYRO_MPU6500_MINDELAY;
   4570      } else if( gyro != NULL && strcmp(gyro, "MPU6515") == 0) {
   4571         list[Gyro].maxRange = GYRO_MPU6500_RANGE;
   4572         list[Gyro].resolution = GYRO_MPU6500_RESOLUTION;
   4573         list[Gyro].power = GYRO_MPU6500_POWER;
   4574         list[Gyro].minDelay = GYRO_MPU6500_MINDELAY;
   4575     } else if( gyro != NULL && strcmp(gyro, "MPU9150") == 0) {
   4576         list[Gyro].maxRange = GYRO_MPU9150_RANGE;
   4577         list[Gyro].resolution = GYRO_MPU9150_RESOLUTION;
   4578         list[Gyro].power = GYRO_MPU9150_POWER;
   4579         list[Gyro].minDelay = GYRO_MPU9150_MINDELAY;
   4580     } else {
   4581         LOGE("HAL:unknown gyro id -- gyro params will be wrong.");
   4582         LOGE("HAL:default to use mpu3050 params");
   4583         list[Gyro].maxRange = GYRO_MPU3050_RANGE;
   4584         list[Gyro].resolution = GYRO_MPU3050_RESOLUTION;
   4585         list[Gyro].power = GYRO_MPU3050_POWER;
   4586         list[Gyro].minDelay = GYRO_MPU3050_MINDELAY;
   4587     }
   4588 
   4589     list[RawGyro].maxRange = list[Gyro].maxRange;
   4590     list[RawGyro].resolution = list[Gyro].resolution;
   4591     list[RawGyro].power = list[Gyro].power;
   4592     list[RawGyro].minDelay = list[Gyro].minDelay;
   4593 
   4594     return;
   4595 }
   4596 
   4597 /* fillRV depends on values of gyro, accel and compass in the list */
   4598 void MPLSensor::fillRV(struct sensor_t *list)
   4599 {
   4600     VFUNC_LOG;
   4601 
   4602     /* compute power on the fly */
   4603     list[RotationVector].power = list[Gyro].power +
   4604                                  list[Accelerometer].power +
   4605                                  list[MagneticField].power;
   4606     list[RotationVector].resolution = .00001;
   4607     list[RotationVector].maxRange = 1.0;
   4608     list[RotationVector].minDelay = 5000;
   4609 
   4610     return;
   4611 }
   4612 
   4613 /* fillGMRV depends on values of accel and mag in the list */
   4614 void MPLSensor::fillGMRV(struct sensor_t *list)
   4615 {
   4616     VFUNC_LOG;
   4617 
   4618     /* compute power on the fly */
   4619     list[GeomagneticRotationVector].power = list[Accelerometer].power +
   4620                                  list[MagneticField].power;
   4621     list[GeomagneticRotationVector].resolution = .00001;
   4622     list[GeomagneticRotationVector].maxRange = 1.0;
   4623     list[GeomagneticRotationVector].minDelay = 5000;
   4624 
   4625     return;
   4626 }
   4627 
   4628 /* fillGRV depends on values of gyro and accel in the list */
   4629 void MPLSensor::fillGRV(struct sensor_t *list)
   4630 {
   4631     VFUNC_LOG;
   4632 
   4633     /* compute power on the fly */
   4634     list[GameRotationVector].power = list[Gyro].power +
   4635                                  list[Accelerometer].power;
   4636     list[GameRotationVector].resolution = .00001;
   4637     list[GameRotationVector].maxRange = 1.0;
   4638     list[GameRotationVector].minDelay = 5000;
   4639 
   4640     return;
   4641 }
   4642 
   4643 void MPLSensor::fillOrientation(struct sensor_t *list)
   4644 {
   4645     VFUNC_LOG;
   4646 
   4647     list[Orientation].power = list[Gyro].power +
   4648                               list[Accelerometer].power +
   4649                               list[MagneticField].power;
   4650     list[Orientation].resolution = .00001;
   4651     list[Orientation].maxRange = 360.0;
   4652     list[Orientation].minDelay = 5000;
   4653 
   4654     return;
   4655 }
   4656 
   4657 void MPLSensor::fillGravity( struct sensor_t *list)
   4658 {
   4659     VFUNC_LOG;
   4660 
   4661     list[Gravity].power = list[Gyro].power +
   4662                           list[Accelerometer].power +
   4663                           list[MagneticField].power;
   4664     list[Gravity].resolution = .00001;
   4665     list[Gravity].maxRange = 9.81;
   4666     list[Gravity].minDelay = 5000;
   4667 
   4668     return;
   4669 }
   4670 
   4671 void MPLSensor::fillLinearAccel(struct sensor_t *list)
   4672 {
   4673     VFUNC_LOG;
   4674 
   4675     list[LinearAccel].power = list[Gyro].power +
   4676                           list[Accelerometer].power +
   4677                           list[MagneticField].power;
   4678     list[LinearAccel].resolution = list[Accelerometer].resolution;
   4679     list[LinearAccel].maxRange = list[Accelerometer].maxRange;
   4680     list[LinearAccel].minDelay = 5000;
   4681 
   4682     return;
   4683 }
   4684 
   4685 void MPLSensor::fillSignificantMotion(struct sensor_t *list)
   4686 {
   4687     VFUNC_LOG;
   4688 
   4689     list[SignificantMotion].power = list[Accelerometer].power;
   4690     list[SignificantMotion].resolution = 1;
   4691     list[SignificantMotion].maxRange = 1;
   4692     list[SignificantMotion].minDelay = -1;
   4693 }
   4694 
   4695 #ifdef ENABLE_DMP_SCREEN_AUTO_ROTATION
   4696 void MPLSensor::fillScreenOrientation(struct sensor_t *list)
   4697 {
   4698     VFUNC_LOG;
   4699 
   4700     list[NumSensors].power = list[Accelerometer].power;
   4701     list[NumSensors].resolution = 1;
   4702     list[NumSensors].maxRange = 3;
   4703     list[NumSensors].minDelay = 0;
   4704 }
   4705 #endif
   4706 
   4707 int MPLSensor::inv_init_sysfs_attributes(void)
   4708 {
   4709     VFUNC_LOG;
   4710 
   4711     unsigned char i = 0;
   4712     char sysfs_path[MAX_SYSFS_NAME_LEN];
   4713     char tbuf[2];
   4714     char *sptr;
   4715     char **dptr;
   4716     int num;
   4717 
   4718     memset(sysfs_path, 0, sizeof(sysfs_path));
   4719 
   4720     sysfs_names_ptr =
   4721             (char*)malloc(sizeof(char[MAX_SYSFS_ATTRB][MAX_SYSFS_NAME_LEN]));
   4722     sptr = sysfs_names_ptr;
   4723     if (sptr != NULL) {
   4724         dptr = (char**)&mpu;
   4725         do {
   4726             *dptr++ = sptr;
   4727             memset(sptr, 0, sizeof(sptr));
   4728             sptr += sizeof(char[MAX_SYSFS_NAME_LEN]);
   4729         } while (++i < MAX_SYSFS_ATTRB);
   4730     } else {
   4731         LOGE("HAL:couldn't alloc mem for sysfs paths");
   4732         return -1;
   4733     }
   4734 
   4735     // get proper (in absolute) IIO path & build MPU's sysfs paths
   4736     inv_get_sysfs_path(sysfs_path);
   4737 
   4738     if (strcmp(sysfs_path, "") == 0)
   4739         return 0;
   4740 
   4741     memcpy(mSysfsPath, sysfs_path, sizeof(sysfs_path));
   4742     sprintf(mpu.key, "%s%s", sysfs_path, "/key");
   4743     sprintf(mpu.chip_enable, "%s%s", sysfs_path, "/buffer/enable");
   4744     sprintf(mpu.buffer_length, "%s%s", sysfs_path, "/buffer/length");
   4745     sprintf(mpu.power_state, "%s%s", sysfs_path, "/power_state");
   4746 
   4747     sprintf(mpu.in_timestamp_en, "%s%s", sysfs_path,
   4748             "/scan_elements/in_timestamp_en");
   4749     sprintf(mpu.in_timestamp_index, "%s%s", sysfs_path,
   4750             "/scan_elements/in_timestamp_index");
   4751     sprintf(mpu.in_timestamp_type, "%s%s", sysfs_path,
   4752             "/scan_elements/in_timestamp_type");
   4753 
   4754     sprintf(mpu.dmp_firmware, "%s%s", sysfs_path, "/dmp_firmware");
   4755     sprintf(mpu.firmware_loaded, "%s%s", sysfs_path, "/firmware_loaded");
   4756     sprintf(mpu.dmp_on, "%s%s", sysfs_path, "/dmp_on");
   4757     sprintf(mpu.dmp_int_on, "%s%s", sysfs_path, "/dmp_int_on");
   4758     sprintf(mpu.dmp_event_int_on, "%s%s", sysfs_path, "/dmp_event_int_on");
   4759     sprintf(mpu.tap_on, "%s%s", sysfs_path, "/tap_on");
   4760 
   4761     sprintf(mpu.self_test, "%s%s", sysfs_path, "/self_test");
   4762 
   4763     sprintf(mpu.temperature, "%s%s", sysfs_path, "/temperature");
   4764     sprintf(mpu.gyro_enable, "%s%s", sysfs_path, "/gyro_enable");
   4765     sprintf(mpu.gyro_fifo_rate, "%s%s", sysfs_path, "/sampling_frequency");
   4766     sprintf(mpu.gyro_orient, "%s%s", sysfs_path, "/gyro_matrix");
   4767     sprintf(mpu.gyro_fifo_enable, "%s%s", sysfs_path, "/gyro_fifo_enable");
   4768     sprintf(mpu.gyro_fsr, "%s%s", sysfs_path, "/in_anglvel_scale");
   4769     sprintf(mpu.gyro_fifo_enable, "%s%s", sysfs_path, "/gyro_fifo_enable");
   4770     sprintf(mpu.gyro_rate, "%s%s", sysfs_path, "/gyro_rate");
   4771 
   4772     sprintf(mpu.accel_enable, "%s%s", sysfs_path, "/accel_enable");
   4773     sprintf(mpu.accel_fifo_rate, "%s%s", sysfs_path, "/sampling_frequency");
   4774     sprintf(mpu.accel_orient, "%s%s", sysfs_path, "/accel_matrix");
   4775     sprintf(mpu.accel_fifo_enable, "%s%s", sysfs_path, "/accel_fifo_enable");
   4776     sprintf(mpu.accel_rate, "%s%s", sysfs_path, "/accel_rate");
   4777 
   4778 #ifndef THIRD_PARTY_ACCEL //MPUxxxx
   4779     sprintf(mpu.accel_fsr, "%s%s", sysfs_path, "/in_accel_scale");
   4780 
   4781     // DMP uses these values
   4782     sprintf(mpu.in_accel_x_dmp_bias, "%s%s", sysfs_path, "/in_accel_x_dmp_bias");
   4783     sprintf(mpu.in_accel_y_dmp_bias, "%s%s", sysfs_path, "/in_accel_y_dmp_bias");
   4784     sprintf(mpu.in_accel_z_dmp_bias, "%s%s", sysfs_path, "/in_accel_z_dmp_bias");
   4785 
   4786     // MPU bias value is not set on purpose -
   4787     // raw accel value with factory cal is not requested
   4788 #endif
   4789 
   4790     // DMP uses these bias values
   4791     sprintf(mpu.in_gyro_x_dmp_bias, "%s%s", sysfs_path, "/in_anglvel_x_dmp_bias");
   4792     sprintf(mpu.in_gyro_y_dmp_bias, "%s%s", sysfs_path, "/in_anglvel_y_dmp_bias");
   4793     sprintf(mpu.in_gyro_z_dmp_bias, "%s%s", sysfs_path, "/in_anglvel_z_dmp_bias");
   4794 
   4795     // MPU uses these bias values
   4796     sprintf(mpu.in_gyro_x_offset, "%s%s", sysfs_path, "/in_anglvel_x_offset");
   4797     sprintf(mpu.in_gyro_y_offset, "%s%s", sysfs_path, "/in_anglvel_y_offset");
   4798     sprintf(mpu.in_gyro_z_offset, "%s%s", sysfs_path, "/in_anglvel_z_offset");
   4799     sprintf(mpu.in_gyro_self_test_scale, "%s%s", sysfs_path, "/in_anglvel_self_test_scale");
   4800 
   4801     sprintf(mpu.three_axis_q_on, "%s%s", sysfs_path, "/three_axes_q_on"); //formerly quaternion_on
   4802     sprintf(mpu.three_axis_q_rate, "%s%s", sysfs_path, "/three_axes_q_rate");
   4803 
   4804     sprintf(mpu.ped_q_on, "%s%s", sysfs_path, "/ped_q_on");
   4805     sprintf(mpu.ped_q_rate, "%s%s", sysfs_path, "/ped_q_rate");
   4806 
   4807     sprintf(mpu.six_axis_q_on, "%s%s", sysfs_path, "/six_axes_q_on");
   4808     sprintf(mpu.six_axis_q_rate, "%s%s", sysfs_path, "/six_axes_q_rate");
   4809 
   4810     sprintf(mpu.step_detector_on, "%s%s", sysfs_path, "/step_detector_on");
   4811     sprintf(mpu.step_indicator_on, "%s%s", sysfs_path, "/step_indicator_on");
   4812 
   4813     sprintf(mpu.display_orientation_on, "%s%s", sysfs_path,
   4814             "/display_orientation_on");
   4815     sprintf(mpu.event_display_orientation, "%s%s", sysfs_path,
   4816             "/event_display_orientation");
   4817 
   4818     sprintf(mpu.event_smd, "%s%s", sysfs_path,
   4819             "/event_smd");
   4820     sprintf(mpu.smd_enable, "%s%s", sysfs_path,
   4821             "/smd_enable");
   4822     sprintf(mpu.smd_delay_threshold, "%s%s", sysfs_path,
   4823             "/smd_delay_threshold");
   4824     sprintf(mpu.smd_delay_threshold2, "%s%s", sysfs_path,
   4825             "/smd_delay_threshold2");
   4826     sprintf(mpu.smd_threshold, "%s%s", sysfs_path,
   4827             "/smd_threshold");
   4828     sprintf(mpu.batchmode_timeout, "%s%s", sysfs_path,
   4829             "/batchmode_timeout");
   4830     sprintf(mpu.batchmode_wake_fifo_full_on, "%s%s", sysfs_path,
   4831             "/batchmode_wake_fifo_full_on");
   4832     sprintf(mpu.pedometer_on, "%s%s", sysfs_path,
   4833             "/pedometer_on");
   4834     sprintf(mpu.pedometer_int_on, "%s%s", sysfs_path,
   4835             "/pedometer_int_on");
   4836     sprintf(mpu.event_pedometer, "%s%s", sysfs_path,
   4837             "/event_pedometer");
   4838     sprintf(mpu.pedometer_steps, "%s%s", sysfs_path,
   4839             "/pedometer_steps");
   4840     return 0;
   4841 }
   4842 
   4843 bool MPLSensor::isMpuNonDmp(void)
   4844 {
   4845     if (!strcmp(chip_ID, "mpu3050") || !strcmp(chip_ID, "MPU3050"))
   4846         return true;
   4847     else
   4848         return false;
   4849 }
   4850 
   4851 int MPLSensor::isLowPowerQuatEnabled(void)
   4852 {
   4853 #ifdef ENABLE_LP_QUAT_FEAT
   4854     return !isMpuNonDmp();
   4855 #else
   4856     return 0;
   4857 #endif
   4858 }
   4859 
   4860 int MPLSensor::isDmpDisplayOrientationOn(void)
   4861 {
   4862 #ifdef ENABLE_DMP_DISPL_ORIENT_FEAT
   4863     if (isMpuNonDmp())
   4864         return 0;
   4865     return 1;
   4866 #else
   4867     return 0;
   4868 #endif
   4869 }
   4870 
   4871 /* these functions can be consolidated
   4872 with inv_convert_to_body_with_scale */
   4873 void MPLSensor::getCompassBias()
   4874 {
   4875     VFUNC_LOG;
   4876 
   4877 
   4878     long bias[3];
   4879     long compassBias[3];
   4880     unsigned short orient;
   4881     signed char orientMtx[9];
   4882     mCompassSensor->getOrientationMatrix(orientMtx);
   4883     orient = inv_orientation_matrix_to_scalar(orientMtx);
   4884     /* Get Values from MPL */
   4885     inv_get_compass_bias(bias);
   4886     //inv_convert_to_body_with_scale(unsigned short orientation, long sensitivity, const long *input, long *output);
   4887     inv_convert_to_body(orient, bias, compassBias);
   4888     LOGV_IF(HANDLER_DATA, "Mpl Compass Bias (HW unit) %ld %ld %ld", bias[0], bias[1], bias[2]);
   4889     LOGV_IF(HANDLER_DATA, "Mpl Compass Bias (HW unit) (body) %ld %ld %ld", compassBias[0], compassBias[1], compassBias[2]);
   4890     long compassSensitivity = inv_get_compass_sensitivity();
   4891     if (compassSensitivity == 0) {
   4892         compassSensitivity = mCompassScale;
   4893     }
   4894     for(int i=0; i<3; i++) {
   4895         /* convert to uT */
   4896         float temp = (float) compassSensitivity / (1L << 30);
   4897         mCompassBias[i] =(float) (compassBias[i] * temp / 65536.f);
   4898     }
   4899 
   4900     return;
   4901 }
   4902 
   4903 void MPLSensor::getFactoryGyroBias()
   4904 {
   4905     VFUNC_LOG;
   4906 
   4907     //TODO: mllite needs to add this function
   4908     //if(inv_factory_bias_available) {
   4909         /* Get Values from MPL */
   4910         inv_get_gyro_bias(mFactoryGyroBias);
   4911         LOGV_IF(ENG_VERBOSE, "Factory Gyro Bias %ld %ld %ld", mFactoryGyroBias[0], mFactoryGyroBias[1], mFactoryGyroBias[2]);
   4912         mFactoryGyroBiasAvailable = true;
   4913     //}
   4914 
   4915     return;
   4916 }
   4917 
   4918 /* set bias from factory cal file to MPU offset
   4919 /* x = values store in cal file --> (v/1000 * 2^16 / (2000/250))
   4920 /* offset = x/2^16 * (Gyro scale / self test scale used) * (-1) / offset scale
   4921 /* i.e. self test default scale = 250
   4922 /*       gyro scale default to = 2000
   4923 /*       offset scale = 4 //as spec by hardware
   4924 /*       offset = x/2^16 * (8) * (-1) / (4)
   4925 */
   4926 
   4927 void MPLSensor::setFactoryGyroBias()
   4928 {
   4929     VFUNC_LOG;
   4930     int scaleRatio = mGyroScale / mGyroSelfTestScale;
   4931     int offsetScale = 4;
   4932     LOGV_IF(PROCESS_VERBOSE, "HAL: scaleRatio used =%d", scaleRatio);
   4933     LOGV_IF(PROCESS_VERBOSE, "HAL: offsetScale used =%d", offsetScale);
   4934 
   4935     /* Write to Driver */
   4936     LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)",
   4937             (((int) (((float) mFactoryGyroBias[0]) / 65536.f * scaleRatio)) * -1 / offsetScale),
   4938             mpu.in_gyro_x_offset, getTimestamp());
   4939     if(write_attribute_sensor_continuous(gyro_x_offset_fd,
   4940         (((int) (((float) mFactoryGyroBias[0]) / 65536.f * scaleRatio)) * -1 / offsetScale)) < 0)
   4941     {
   4942         LOGE("HAL:Error writing to gyro_x_offset");
   4943         return;
   4944     }
   4945     LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)",
   4946             (((int) (((float) mFactoryGyroBias[1]) / 65536.f * scaleRatio)) * -1 / offsetScale),
   4947             mpu.in_gyro_y_offset, getTimestamp());
   4948     if(write_attribute_sensor_continuous(gyro_y_offset_fd,
   4949         (((int) (((float) mFactoryGyroBias[1]) / 65536.f * scaleRatio)) * -1 / offsetScale)) < 0)
   4950     {
   4951         LOGE("HAL:Error writing to gyro_y_offset");
   4952         return;
   4953     }
   4954     LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)",
   4955             (((int) (((float) mFactoryGyroBias[2]) / 65536.f * scaleRatio)) * -1 / offsetScale),
   4956             mpu.in_gyro_z_offset, getTimestamp());
   4957     if(write_attribute_sensor_continuous(gyro_z_offset_fd,
   4958         (((int) (((float) mFactoryGyroBias[2]) / 65536.f * scaleRatio)) * -1 / offsetScale)) < 0)
   4959     {
   4960         LOGE("HAL:Error writing to gyro_z_offset");
   4961         return;
   4962     }
   4963     mFactoryGyroBiasAvailable = false;
   4964     LOGV_IF(EXTRA_VERBOSE, "HAL:Factory Gyro Calibrated Bias Applied");
   4965 
   4966     return;
   4967 }
   4968 
   4969 /* these functions can be consolidated
   4970 with inv_convert_to_body_with_scale */
   4971 void MPLSensor::getGyroBias()
   4972 {
   4973     VFUNC_LOG;
   4974 
   4975     long *temp = NULL;
   4976     long chipBias[3];
   4977     long bias[3];
   4978     unsigned short orient;
   4979 
   4980     /* Get Values from MPL */
   4981     inv_get_mpl_gyro_bias(mGyroChipBias, temp);
   4982     orient = inv_orientation_matrix_to_scalar(mGyroOrientation);
   4983     //void inv_convert_to_body_with_scale(unsigned short orientation, long sensitivity, const long *input, long *output);
   4984     inv_convert_to_body(orient, mGyroChipBias, bias);
   4985     LOGV_IF(ENG_VERBOSE, "Mpl Gyro Bias (HW unit) %ld %ld %ld", mGyroChipBias[0], mGyroChipBias[1], mGyroChipBias[2]);
   4986     LOGV_IF(ENG_VERBOSE, "Mpl Gyro Bias (HW unit) (body) %ld %ld %ld", bias[0], bias[1], bias[2]);
   4987     long gyroSensitivity = inv_get_gyro_sensitivity();
   4988     if(gyroSensitivity == 0) {
   4989         gyroSensitivity = mGyroScale;
   4990     }
   4991 
   4992     /* scale and convert to rad */
   4993     for(int i=0; i<3; i++) {
   4994         float temp = (float) gyroSensitivity / (1L << 30);
   4995         mGyroBias[i] = (float) (bias[i] * temp / (1<<16) / 180 * M_PI);
   4996         if (mGyroBias[i] != 0)
   4997             mGyroBiasAvailable = true;
   4998     }
   4999 
   5000     return;
   5001 }
   5002 
   5003 void MPLSensor::setGyroBias()
   5004 {
   5005     VFUNC_LOG;
   5006 
   5007     if(mGyroBiasAvailable == false)
   5008         return;
   5009 
   5010     long bias[3];
   5011     long gyroSensitivity = inv_get_gyro_sensitivity();
   5012 
   5013     if(gyroSensitivity == 0) {
   5014         gyroSensitivity = mGyroScale;
   5015     }
   5016 
   5017     inv_get_gyro_bias_dmp_units(bias);
   5018 
   5019     /* Write to Driver */
   5020     LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %ld > %s (%lld)",
   5021             bias[0], mpu.in_gyro_x_dmp_bias, getTimestamp());
   5022     if(write_attribute_sensor_continuous(gyro_x_dmp_bias_fd, bias[0]) < 0)
   5023     {
   5024         LOGE("HAL:Error writing to gyro_x_dmp_bias");
   5025         return;
   5026     }
   5027     LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %ld > %s (%lld)",
   5028             bias[1], mpu.in_gyro_y_dmp_bias, getTimestamp());
   5029     if(write_attribute_sensor_continuous(gyro_y_dmp_bias_fd, bias[1]) < 0)
   5030     {
   5031         LOGE("HAL:Error writing to gyro_y_dmp_bias");
   5032         return;
   5033     }
   5034     LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %ld > %s (%lld)",
   5035             bias[2], mpu.in_gyro_z_dmp_bias, getTimestamp());
   5036     if(write_attribute_sensor_continuous(gyro_z_dmp_bias_fd, bias[2]) < 0)
   5037     {
   5038         LOGE("HAL:Error writing to gyro_z_dmp_bias");
   5039         return;
   5040     }
   5041     mGyroBiasApplied = true;
   5042     mGyroBiasAvailable = false;
   5043     LOGV_IF(EXTRA_VERBOSE, "HAL:Gyro DMP Calibrated Bias Applied");
   5044 
   5045     return;
   5046 }
   5047 
   5048 void MPLSensor::getFactoryAccelBias()
   5049 {
   5050     VFUNC_LOG;
   5051 
   5052     long temp;
   5053 
   5054     /* Get Values from MPL */
   5055     inv_get_accel_bias(mAccelBias, &temp);
   5056     LOGV_IF(HANDLER_DATA, "Factory Accel Bias (mg) %ld %ld %ld", mFactoryAccelBias[0], mFactoryAccelBias[1], mFactoryAccelBias[2]);
   5057     mFactoryAccelBiasAvailable = true;
   5058 
   5059     return;
   5060 }
   5061 
   5062 void MPLSensor::setFactoryAccelBias()
   5063 {
   5064     if(mFactoryAccelBiasAvailable == false)
   5065         return;
   5066 
   5067     /* TODO: add scaling here - depends on self test parameters */
   5068 
   5069     /* Write to Driver */
   5070     if(write_attribute_sensor_continuous(accel_x_offset_fd, mFactoryAccelBias[0]) < 0)
   5071     {
   5072         LOGE("HAL:Error writing to accel_x_offset");
   5073         return;
   5074     }
   5075     if(write_attribute_sensor_continuous(accel_y_offset_fd, mFactoryAccelBias[1]) < 0)
   5076     {
   5077         LOGE("HAL:Error writing to accel_y_offset");
   5078         return;
   5079     }
   5080     if(write_attribute_sensor_continuous(accel_z_offset_fd, mFactoryAccelBias[2]) < 0)
   5081     {
   5082         LOGE("HAL:Error writing to accel_z_offset");
   5083         return;
   5084     }
   5085     mFactoryAccelBiasAvailable = false;
   5086     LOGV_IF(EXTRA_VERBOSE, "HAL:Factory Accel Calibrated Bias Applied");
   5087 
   5088     return;
   5089 }
   5090 
   5091 void MPLSensor::getAccelBias()
   5092 {
   5093     VFUNC_LOG;
   5094     long temp;
   5095 
   5096     /* Get Values from MPL */
   5097     inv_get_accel_bias(mAccelBias, &temp);
   5098     LOGV_IF(ENG_VERBOSE, "Accel Bias (mg) %ld %ld %ld", mAccelBias[0], mAccelBias[1], mAccelBias[2]);
   5099     mAccelBiasAvailable = true;
   5100 
   5101     return;
   5102 }
   5103 
   5104 void MPLSensor::setAccelBias()
   5105 {
   5106     VFUNC_LOG;
   5107 
   5108     if(mAccelBiasAvailable == false)
   5109         return;
   5110 
   5111     long bias[3];
   5112     unsigned short orient = inv_orientation_matrix_to_scalar(mAccelOrientation);
   5113     inv_convert_to_body(orient, mAccelBias, bias);
   5114 
   5115     /* Write to Driver */
   5116     LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %ld > %s (%lld)",
   5117            (long) (mAccelBias[0] / 65536.f / 2), mpu.in_accel_x_dmp_bias, getTimestamp());
   5118     if(write_attribute_sensor_continuous(accel_x_dmp_bias_fd, (long)(mAccelBias[0] / 65536.f / 2)) < 0)
   5119     {
   5120         LOGE("HAL:Error writing to accel_x_dmp_bias");
   5121         return;
   5122     }
   5123     LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %ld > %s (%lld)",
   5124             (long)(mAccelBias[1] / 65536.f / 2), mpu.in_accel_y_dmp_bias, getTimestamp());
   5125     if(write_attribute_sensor_continuous(accel_y_dmp_bias_fd, (long)(mAccelBias[1] / 65536.f / 2)) < 0)
   5126     {
   5127         LOGE("HAL:Error writing to accel_y_dmp_bias");
   5128         return;
   5129     }
   5130     LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %ld > %s (%lld)",
   5131             (long)(mAccelBias[2] / 65536 / 2), mpu.in_accel_z_dmp_bias, getTimestamp());
   5132     if(write_attribute_sensor_continuous(accel_z_dmp_bias_fd, (long)(mAccelBias[2] / 65536 / 2)) < 0)
   5133     {
   5134         LOGE("HAL:Error writing to accel_z_dmp_bias");
   5135         return;
   5136     }
   5137     mAccelBiasAvailable = false;
   5138     mAccelBiasApplied = true;
   5139     LOGV_IF(EXTRA_VERBOSE, "HAL:Accel DMP Calibrated Bias Applied");
   5140 
   5141     return;
   5142 }
   5143 
   5144 int MPLSensor::isCompassDisabled(void)
   5145 {
   5146     if(mCompassSensor->getFd() < 0 && !mCompassSensor->isIntegrated()) {
   5147     LOGI_IF(EXTRA_VERBOSE, "HAL: Compass is disabled, Six-axis Sensor Fusion is used.");
   5148         return 1;
   5149     }
   5150     return 0;
   5151 }
   5152 
   5153 /* precondition: framework disallows this case, ie enable continuous sensor, */
   5154 /* and enable batch sensor */
   5155 /* if one sensor is in continuous mode, HAL disallows enabling batch for this sensor */
   5156 /* or any other sensors */
   5157 #define DEBUG_BATCHING  (1)
   5158 int MPLSensor::batch(int handle, int flags, int64_t period_ns, int64_t timeout)
   5159 {
   5160     VFUNC_LOG;
   5161 
   5162     int res = 0;
   5163 
   5164     if (isMpuNonDmp())
   5165         return res;
   5166 
   5167     /* Enables batch mode and sets timeout for the given sensor */
   5168     /* enum SENSORS_BATCH_DRY_RUN, SENSORS_BATCH_WAKE_UPON_FIFO_FULL */
   5169     bool dryRun = false;
   5170     android::String8 sname;
   5171     int what = -1;
   5172     int enabled_sensors = mEnabled;
   5173     int batchMode = timeout > 0 ? 1 : 0;
   5174 
   5175     LOGI_IF(DEBUG_BATCHING || ENG_VERBOSE,
   5176             "HAL:batch called - handle=%d, flags=%d, period=%lld, timeout=%lld",
   5177             handle, flags, period_ns, timeout);
   5178 
   5179     if(flags & (1 << SENSORS_BATCH_DRY_RUN)) {
   5180         dryRun = true;
   5181         LOGI_IF(PROCESS_VERBOSE,
   5182                 "HAL:batch - dry run mode is set (%d)", SENSORS_BATCH_DRY_RUN);
   5183     }
   5184 
   5185     getHandle(handle, what, sname);
   5186     if(uint32_t(what) >= NumSensors) {
   5187         LOGE("HAL:batch sensors %d not found", what);
   5188         return -EINVAL;
   5189     }
   5190 
   5191     int tempBatch = 0;
   5192     if (timeout > 0) {
   5193         tempBatch = mBatchEnabled | (1 << what);
   5194     } else {
   5195         tempBatch = mBatchEnabled & ~(1 << what);
   5196     }
   5197 
   5198     if (!computeBatchSensorMask(mEnabled, tempBatch)) {
   5199         batchMode = 0;
   5200     } else {
   5201         batchMode = 1;
   5202     }
   5203 
   5204     /* Supported sensors: Accel, Gyro, Raw Gyro, Compass, Raw Compass, GRV, Step Detector */
   5205     switch (what) {
   5206     case Orientation:
   5207     case LinearAccel:
   5208     case Gravity:
   5209     case RotationVector:
   5210     case GeomagneticRotationVector:
   5211     case SignificantMotion:
   5212     case ID_SC:
   5213     case ID_SO:
   5214         LOGE("HAL:batch - "
   5215              "sensor (handle %d) is not supported in batch mode", handle);
   5216         return -EINVAL;
   5217     }
   5218 
   5219     /* get maximum possible bytes to batch per sample */
   5220     /* get minimum delay for each requested sensor    */
   5221     ssize_t nBytes = 0;
   5222     int64_t wanted = 1000000000LL, ns = 0;
   5223     int64_t timeoutInMs = 0;
   5224     for (int i = 0; i < NumSensors; i++) {
   5225         if (batchMode == 1) {
   5226             ns = mBatchDelays[i];
   5227             LOGV_IF(DEBUG_BATCHING || EXTRA_VERBOSE,
   5228                     "HAL:batch - requested sensor=0x%01x, batch delay=%lld", mEnabled & (1 << i), ns);
   5229             // take the min delay ==> max rate
   5230             wanted = (ns < wanted) ? ns : wanted;
   5231             if (i <= RawMagneticField) {
   5232                 nBytes += 8;
   5233             }
   5234             if (i == Pressure) {
   5235                 nBytes += 6;
   5236             }
   5237             if ((i == StepDetector) || (i == GameRotationVector)) {
   5238                 nBytes += 16;
   5239             }
   5240         }
   5241     }
   5242 
   5243     /* check if we can support issuing interrupt before FIFO fills-up */
   5244     /* in the given timeout.                                          */
   5245     if ((flags & (1 << SENSORS_BATCH_WAKE_UPON_FIFO_FULL)) &&
   5246             (batchMode == 1)) {
   5247             LOGE("HAL: batch SENSORS_BATCH_WAKE_UPON_FIFO_FULL is not supported");
   5248             return -EINVAL;
   5249         /* provide messge if it exceeds hardware capability
   5250         if (nSamples * nBytes >= 1024) {
   5251             LOGE("HAL:batch - timeout - configuration is not supported, "
   5252                  "cannot provide requested amount of buffering (%lld ms)",
   5253                  timeout / 1000000LL);
   5254         }*/
   5255     }
   5256 
   5257     if(dryRun == true)
   5258         return 0;
   5259 
   5260     /* starting from code below,  we will modify hardware */
   5261     /* first edit global batch mode mask */
   5262 
   5263     if (!timeout) {
   5264         mBatchEnabled &= ~(1 << what);
   5265         mBatchDelays[what] = 1000000000L;
   5266         mBatchTimeouts[what] = 30000000000LL;
   5267         if (mBatchEnabled == 0) {
   5268             mFeatureActiveMask &= ~INV_DMP_BATCH_MODE;
   5269         }
   5270     } else {
   5271         mBatchEnabled |= (1 << what);
   5272         mBatchDelays[what] = period_ns;
   5273         mBatchTimeouts[what] = timeout;
   5274         mFeatureActiveMask |= INV_DMP_BATCH_MODE;
   5275     }
   5276 
   5277     /* For these sensors, switch to different data output */
   5278     /* These steps should be optimized at some point */
   5279     int featureMask = computeBatchDataOutput();
   5280 
   5281     LOGV_IF(ENG_VERBOSE, "batchMode =%d, featureMask=0x%x, mEnabled=%d",
   5282                 batchMode, featureMask, mEnabled);
   5283     if (DEBUG_BATCHING || EXTRA_VERBOSE) {
   5284         LOGV("HAL:batch - sensor=0x%01x", mBatchEnabled);
   5285         for (int d = 0; d < NumSensors; d++) {
   5286             LOGV("HAL:batch - sensor status=0x%01x batch status=0x%01x timeout=%lld delay=%lld",
   5287                             mEnabled & (1 << d), (mBatchEnabled & (1 << d)), mBatchTimeouts[d],
   5288                             mBatchDelays[d]);
   5289         }
   5290     }
   5291 
   5292     /* take the minimum batchmode timeout */
   5293     if (batchMode == 1) {
   5294         int64_t tempTimeout = 30000000000LL;
   5295         for (int i = 0; i < NumSensors; i++) {
   5296             if ((mEnabled & (1 << i) && mBatchEnabled & (1 << i)) ||
   5297                     (((featureMask & INV_DMP_PED_STANDALONE) && (mBatchEnabled & (1 << StepDetector))))) {
   5298                 LOGV_IF(ENG_VERBOSE, "i=%d, timeout=%lld", i, mBatchTimeouts[i]);
   5299                 ns = mBatchTimeouts[i];
   5300                 tempTimeout = (ns < tempTimeout) ? ns : tempTimeout;
   5301             }
   5302         }
   5303         timeout = tempTimeout;
   5304         /* Convert ns to millisecond */
   5305         timeoutInMs = timeout / 1000000;
   5306 
   5307         /* remember last timeout value */
   5308         mBatchTimeoutInMs = timeoutInMs;
   5309 
   5310         /* TODO: Calculate nSamples */
   5311         int nSamples = 0;
   5312         nSamples = (unsigned long)(
   5313             (1000000000.f / wanted) * ((float)timeout / 1000000000.f));
   5314     } else {
   5315         timeoutInMs = 0;
   5316     }
   5317 
   5318     LOGV_IF(DEBUG_BATCHING || EXTRA_VERBOSE,
   5319                 "HAL:batch - timeout - timeout=%lld ns, timeoutInMs=%lld, delay=%lld ns",
   5320                 timeout, timeoutInMs, wanted);
   5321 
   5322     // reset master enable
   5323     res = masterEnable(0);
   5324     if (res < 0) {
   5325         return res;
   5326     }
   5327 
   5328     /* case for Ped standalone */
   5329     if ((batchMode == 1) && (featureMask & INV_DMP_PED_STANDALONE) &&
   5330            (mFeatureActiveMask & INV_DMP_PEDOMETER)) {
   5331         LOGI("ID_P only = 0x%x", mBatchEnabled);
   5332         enablePedQuaternion(0);
   5333         enablePedStandalone(1);
   5334     } else {
   5335         enablePedStandalone(0);
   5336         if (featureMask & INV_DMP_PED_QUATERNION) {
   5337             enableLPQuaternion(0);
   5338             enablePedQuaternion(1);
   5339         }
   5340     }
   5341 
   5342     /* case for Ped Quaternion */
   5343     if ((batchMode == 1) && (featureMask & INV_DMP_PED_QUATERNION) &&
   5344             (mEnabled & (1 << GameRotationVector)) &&
   5345             (mFeatureActiveMask & INV_DMP_PEDOMETER)) {
   5346         LOGI("ID_P and GRV or ALL = 0x%x", mBatchEnabled);
   5347         LOGI("ID_P is enabled for batching, PED quat will be automatically enabled");
   5348         enableLPQuaternion(0);
   5349         enablePedQuaternion(1);
   5350 
   5351         wanted = mBatchDelays[GameRotationVector];
   5352         /* set pedq rate */
   5353         LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)",
   5354                 int(1000000000.f / wanted), mpu.ped_q_rate,
   5355                 getTimestamp());
   5356         write_sysfs_int(mpu.ped_q_rate, 1000000000.f / wanted);
   5357         LOGV_IF(PROCESS_VERBOSE,
   5358                 "HAL:DMP ped quaternion rate %.2f Hz", 1000000000.f / wanted);
   5359     } else if (!(featureMask & INV_DMP_PED_STANDALONE)){
   5360         LOGI("Toggle back to normal 6 axis");
   5361         if (mEnabled & (1 << GameRotationVector)) {
   5362             enableLPQuaternion(1);
   5363         }
   5364         enablePedQuaternion(0);
   5365     }
   5366 
   5367      /* case for Ped indicator */
   5368     if ((batchMode == 1) && ((featureMask & INV_DMP_PED_INDICATOR))) {
   5369         enablePedIndicator(1);
   5370     } else {
   5371         enablePedIndicator(0);
   5372     }
   5373 
   5374     /* case for Six Axis Quaternion */
   5375     if ((batchMode == 1) && (featureMask & INV_DMP_6AXIS_QUATERNION) &&
   5376             (mEnabled & (1 << GameRotationVector))) {
   5377         LOGI("GRV = 0x%x", mBatchEnabled);
   5378         enableLPQuaternion(0);
   5379         enable6AxisQuaternion(1);
   5380 
   5381         wanted = mBatchDelays[GameRotationVector];
   5382         /* set sixaxis rate */
   5383         LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)",
   5384                 int(1000000000.f / wanted), mpu.six_axis_q_rate,
   5385                 getTimestamp());
   5386         write_sysfs_int(mpu.six_axis_q_rate, 1000000000.f / wanted);
   5387         LOGV_IF(PROCESS_VERBOSE,
   5388                 "HAL:DMP three axis rate %.2f Hz", 1000000000.f / wanted);
   5389     } else if (!(featureMask & INV_DMP_PED_QUATERNION)){
   5390         LOGI("Toggle back to normal 6 axis");
   5391         if (mEnabled & (1 << GameRotationVector)) {
   5392             enableLPQuaternion(1);
   5393         }
   5394         enable6AxisQuaternion(0);
   5395     } else {
   5396         enable6AxisQuaternion(0);
   5397     }
   5398 
   5399     /* TODO: This may make a come back some day */
   5400     /* write not to overflow hardware FIFO if flag is set */
   5401     /*if (flags & (1 << SENSORS_BATCH_WAKE_UPON_FIFO_FULL)) {
   5402         LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)",
   5403                 0, mpu.batchmode_wake_fifo_full_on, getTimestamp());
   5404         if (write_sysfs_int(mpu.batchmode_wake_fifo_full_on, 0) < 0) {
   5405             LOGE("HAL:ERR can't write batchmode_wake_fifo_full_on");
   5406         }
   5407     }*/
   5408 
   5409     /* write required timeout to sysfs */
   5410     LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %lld > %s (%lld)",
   5411             timeoutInMs, mpu.batchmode_timeout, getTimestamp());
   5412     if (write_sysfs_int(mpu.batchmode_timeout, timeoutInMs) < 0) {
   5413         LOGE("HAL:ERR can't write batchmode_timeout");
   5414     }
   5415 
   5416     if (batchMode == 1) {
   5417         // enable DMP
   5418         res = onDmp(1);
   5419         if (res < 0) {
   5420             return res;
   5421         }
   5422         // set batch rates
   5423         if (setBatchDataRates() < 0) {
   5424             LOGE("HAL:ERR can't set batch data rates");
   5425         }
   5426         // default fifo rate to 200Hz
   5427         LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)",
   5428                 200, mpu.gyro_fifo_rate, getTimestamp());
   5429         if (write_sysfs_int(mpu.gyro_fifo_rate, 200) < 0) {
   5430             res = -1;
   5431             LOGE("HAL:ERR can't set DMP rate to 200Hz");
   5432             return res;
   5433         }
   5434     } else {
   5435         if ((mFeatureActiveMask == 0) && !(mEnabled & VIRTUAL_SENSOR_ALL_MASK)) {
   5436             // disable DMP
   5437             res = onDmp(0);
   5438             if (res < 0) {
   5439                 return res;
   5440             }
   5441         }
   5442         /* reset sensor rate */
   5443         /*if (resetDataRates() < 0) {
   5444             LOGE("HAL:ERR can't reset output rate back to original setting");
   5445         }*/
   5446     }
   5447     if ((batchMode == 1) || enabled_sensors || mFeatureActiveMask) {
   5448         masterEnable(1);
   5449     }
   5450     return res;
   5451 }
   5452 
   5453 int MPLSensor::computeBatchDataOutput()
   5454 {
   5455     VFUNC_LOG;
   5456 
   5457     int featureMask = 0;
   5458     if (mBatchEnabled == 0)
   5459         return 0;//h
   5460 
   5461     uint32_t hardwareSensorMask = (1<<Gyro) | (1<<RawGyro) | (1<<Accelerometer) | (1<<MagneticField) |
   5462                                         (1<<RawMagneticField) | (1<<Pressure);
   5463     LOGV_IF(ENG_VERBOSE, "hardwareSensorMask = 0x%0x, mBatchEnabled = 0x%0x", hardwareSensorMask, mBatchEnabled);
   5464 
   5465     if (mBatchEnabled & (1 << StepDetector)) {
   5466         if (mBatchEnabled & (1 << GameRotationVector)) {
   5467             if ((mBatchEnabled & hardwareSensorMask)) {
   5468                 featureMask |= INV_DMP_6AXIS_QUATERNION;//a
   5469                 featureMask |= INV_DMP_PED_INDICATOR;
   5470             } else {
   5471                 featureMask |= INV_DMP_PED_QUATERNION; //b
   5472                 featureMask |= INV_DMP_PED_INDICATOR;  //always piggy back a bit
   5473             }
   5474         } else {
   5475             if (mBatchEnabled & hardwareSensorMask) {
   5476                 featureMask |= INV_DMP_PED_INDICATOR; //c
   5477             } else {
   5478                 featureMask |= INV_DMP_PED_STANDALONE; //d
   5479                 featureMask |= INV_DMP_PED_INDICATOR; //required for standalone
   5480             }
   5481         }
   5482     } else if (mBatchEnabled & (1 << GameRotationVector)) {
   5483         featureMask |= INV_DMP_6AXIS_QUATERNION; //e,f
   5484     } else {
   5485         LOGV_IF(ENG_VERBOSE, "HAL:computeBatchDataOutput: featuerMask=0x%x", featureMask);
   5486         return 0; //g
   5487     }
   5488 
   5489     LOGV_IF(ENG_VERBOSE, "HAL:computeBatchDataOutput: featuerMask=0x%x", featureMask);
   5490     return featureMask;
   5491 }
   5492 
   5493 int MPLSensor::getDmpPedometerFd()
   5494 {
   5495     LOGV_IF(EXTRA_VERBOSE, "MPLSensor::getDmpPedometerFd returning %d",
   5496              dmp_pedometer_fd);
   5497     return dmp_pedometer_fd;
   5498 }
   5499 
   5500 /* @param [in] : outputType = 1 --derive from ped_q */
   5501 /* outputType = 0 --derive from IRQ          */
   5502 int MPLSensor::readDmpPedometerEvents(sensors_event_t* data, int count,
   5503                                       int32_t id, int32_t type, int outputType)
   5504 {
   5505     VFUNC_LOG;
   5506 
   5507     int res = 0;
   5508     char dummy[4];
   5509     FILE *fp;
   5510     uint64_t stepCount = 0;
   5511     int numEventReceived = 0;
   5512     int update = 0;
   5513 
   5514     if((mDmpStepCountEnabled || mDmpPedometerEnabled) && count > 0) {
   5515         /* handles return event */
   5516         sensors_event_t temp;
   5517 
   5518         LOGI_IF(EXTRA_VERBOSE, "HAL: Read Pedometer Event ID=%d", id);
   5519         temp.version = sizeof(sensors_event_t);
   5520         temp.sensor = id;
   5521         temp.type = type;
   5522         temp.acceleration.status
   5523             = SENSOR_STATUS_UNRELIABLE;
   5524         /* sensors.h specified to return 1.0 */
   5525         if(id == ID_P) {
   5526              temp.data[0] = 1;
   5527              temp.data[1] = 0.f;
   5528              temp.data[2] = 0.f;
   5529         } else {
   5530             fp = fopen(mpu.pedometer_steps, "r");
   5531             if (fp == NULL) {
   5532                 LOGE("HAL:cannot open pedometer_steps");
   5533             } else{
   5534                 if (fscanf(fp, "%lld\n", &stepCount) < 0 || fclose(fp) < 0) {
   5535                     LOGE("HAL:cannot read pedometer_steps");
   5536                 }
   5537             }
   5538             /* return onChange only*/
   5539             if (stepCount == mLastStepCount) {
   5540                 return 0;
   5541             }
   5542             temp.data[0] = stepCount;
   5543             temp.data[1] = 0.f;
   5544             temp.data[2] = 0.f;
   5545             mLastStepCount = stepCount;
   5546         }
   5547 
   5548         if (!outputType) {
   5549             struct timespec ts;
   5550             clock_gettime(CLOCK_MONOTONIC, &ts) ;
   5551             temp.timestamp = (int64_t)ts.tv_sec * 1000000000 + ts.tv_nsec;
   5552         }
   5553 
   5554         *data++ = temp;
   5555         count--;
   5556         numEventReceived++;
   5557     }
   5558 
   5559     if (!outputType) {
   5560         // read dummy data per driver's request
   5561         // only required if actual irq is issued
   5562         read(dmp_pedometer_fd, dummy, 4);
   5563     } else {
   5564         return 1;
   5565     }
   5566 
   5567     return numEventReceived;
   5568 }
   5569 
   5570 int MPLSensor::getDmpSignificantMotionFd()
   5571 {
   5572     LOGV_IF(EXTRA_VERBOSE,
   5573             "MPLSensor::getDmpSignificantMotionFd returning %d",
   5574             dmp_sign_motion_fd);
   5575     return dmp_sign_motion_fd;
   5576 }
   5577 
   5578 int MPLSensor::readDmpSignificantMotionEvents(sensors_event_t* data, int count) {
   5579     VFUNC_LOG;
   5580 
   5581     int res = 0;
   5582     char dummy[4];
   5583     int significantMotion;
   5584     FILE *fp;
   5585     int sensors = mEnabled;
   5586     int numEventReceived = 0;
   5587     int update = 0;
   5588 
   5589     /* Technically this step is not necessary for now  */
   5590     /* In the future, we may have meaningful values */
   5591     fp = fopen(mpu.event_smd, "r");
   5592     if (fp == NULL) {
   5593         LOGE("HAL:cannot open event_smd");
   5594         return 0;
   5595     }
   5596     fscanf(fp, "%d\n", &significantMotion);
   5597     fclose(fp);
   5598 
   5599     if(mDmpSignificantMotionEnabled && count > 0) {
   5600        /* By implementation, smd is disabled once an event is triggered */
   5601         sensors_event_t temp;
   5602 
   5603         /* Handles return event */
   5604         LOGI("HAL: SMD detected");
   5605         int update = smHandler(&temp);
   5606         if (update && count > 0) {
   5607             *data++ = temp;
   5608             count--;
   5609             numEventReceived++;
   5610             mDmpSignificantMotionEnabled = 0;
   5611             mFeatureActiveMask &= ~INV_DMP_SIGNIFICANT_MOTION;
   5612             if(mFeatureActiveMask == 0) {
   5613                 LOGI("dmp off");
   5614                 // disable DMP
   5615                 masterEnable(0);
   5616                 res = onDmp(0);
   5617                 if (res < 0)
   5618                     return res;
   5619 
   5620                 // disable accel engine
   5621                 if (!(mLocalSensorMask & mMasterSensorMask
   5622                         & INV_THREE_AXIS_ACCEL)) {
   5623                     res = enableAccel(0);
   5624                     if (res < 0)
   5625                         return res;
   5626                 }
   5627             }
   5628             if(sensors != 0) {
   5629                  update_delay();
   5630                  masterEnable(1);
   5631             }
   5632         }
   5633     }
   5634 
   5635     // read dummy data per driver's request
   5636     read(dmp_sign_motion_fd, dummy, 4);
   5637 
   5638     return numEventReceived;
   5639 }
   5640 
   5641 int MPLSensor::enableDmpSignificantMotion(int en)
   5642 {
   5643     int res = 0;
   5644     VFUNC_LOG;
   5645 
   5646     int enabled_sensors = mEnabled;
   5647 
   5648     if (isMpuNonDmp())
   5649         return res;
   5650 
   5651     // reset master enable
   5652     res = masterEnable(0);
   5653     if (res < 0)
   5654         return res;
   5655 
   5656     //Toggle significant montion detection
   5657     if(en) {
   5658         LOGV_IF(PROCESS_VERBOSE, "HAL:Enabling Significant Motion");
   5659         LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)",
   5660                 1, mpu.smd_enable, getTimestamp());
   5661         if (write_sysfs_int(mpu.smd_enable, 1) < 0) {
   5662             LOGE("HAL:ERR can't write DMP smd_enable");
   5663             res = -1;   //Indicate an err
   5664         }
   5665 
   5666         // enable DMP
   5667         res = onDmp(1);
   5668         if (res < 0)
   5669             return res;
   5670 
   5671         // set DMP rate to 200Hz
   5672         LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)",
   5673                 200, mpu.accel_fifo_rate, getTimestamp());
   5674         if (write_sysfs_int(mpu.accel_fifo_rate, 200) < 0) {
   5675             res = -1;
   5676             LOGE("HAL:ERR can't set rate to 200Hz");
   5677             return res;
   5678         }
   5679 
   5680         // enable accel engine
   5681         res = enableAccel(1);
   5682         if (res < 0)
   5683             return res;
   5684 
   5685         // disable accel FIFO
   5686         if (!(mLocalSensorMask & mMasterSensorMask & INV_THREE_AXIS_ACCEL)) {
   5687             res = turnOffAccelFifo();
   5688             if (res < 0)
   5689                 return res;
   5690         }
   5691         mFeatureActiveMask |= INV_DMP_SIGNIFICANT_MOTION;
   5692     }
   5693     else {
   5694         LOGV_IF(PROCESS_VERBOSE, "HAL:Disabling Significant Motion");
   5695         LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)",
   5696                 0, mpu.smd_enable, getTimestamp());
   5697         if (write_sysfs_int(mpu.smd_enable, 0) < 0) {
   5698             LOGE("HAL:ERR write DMP smd_enable");
   5699         }
   5700         mFeatureActiveMask &= ~INV_DMP_SIGNIFICANT_MOTION;
   5701         // disable DMP
   5702         if (mFeatureActiveMask == 0) {
   5703             res = onDmp(0);
   5704 
   5705             if (res < 0)
   5706                 return res;
   5707 
   5708             // disable accel engine
   5709             if (!(mLocalSensorMask & mMasterSensorMask
   5710                     & INV_THREE_AXIS_ACCEL)) {
   5711                 res = enableAccel(0);
   5712                 if (res < 0)
   5713                     return res;
   5714             }
   5715         }
   5716         if(enabled_sensors) {
   5717             LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)",
   5718                 en, mpu.dmp_event_int_on, getTimestamp());
   5719             if (write_sysfs_int(mpu.dmp_event_int_on, en) < 0) {
   5720                 res = -1;
   5721                 LOGE("HAL:ERR can't enable DMP event interrupt");
   5722             }
   5723          }
   5724     }
   5725     if(en || enabled_sensors || mFeatureActiveMask) {
   5726         res = masterEnable(1);
   5727     }
   5728     return res;
   5729 }
   5730 
   5731 int MPLSensor::writeSignificantMotionParams(bool toggleEnable,
   5732                                             uint32_t delayThreshold1,
   5733                                             uint32_t delayThreshold2,
   5734                                             uint32_t motionThreshold)
   5735 {
   5736     int res = 0;
   5737 
   5738     // Turn off enable
   5739     if (toggleEnable) {
   5740         masterEnable(0);
   5741     }
   5742 
   5743     // Write supplied values
   5744     LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)",
   5745             delayThreshold1, mpu.smd_delay_threshold, getTimestamp());
   5746     res = write_sysfs_int(mpu.smd_delay_threshold, delayThreshold1);
   5747     if (res == 0) {
   5748         LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)",
   5749                 delayThreshold2, mpu.smd_delay_threshold2, getTimestamp());
   5750         res = write_sysfs_int(mpu.smd_delay_threshold2, delayThreshold2);
   5751     }
   5752     if (res == 0) {
   5753         LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)",
   5754                 motionThreshold, mpu.smd_threshold, getTimestamp());
   5755         res = write_sysfs_int(mpu.smd_threshold, motionThreshold);
   5756     }
   5757 
   5758     // Turn on enable
   5759     if (toggleEnable) {
   5760         masterEnable(1);
   5761     }
   5762     return res;
   5763 }
   5764 
   5765 /* set batch data rate */
   5766 /* this function should be optimized */
   5767 int MPLSensor::setBatchDataRates()
   5768 {
   5769     VFUNC_LOG;
   5770 
   5771     int res = 0;
   5772     int tempFd = -1;
   5773 
   5774     int64_t gyroRate;
   5775     int64_t accelRate;
   5776     int64_t compassRate;
   5777     int64_t pressureRate;
   5778 
   5779     int mplGyroRate;
   5780     int mplAccelRate;
   5781     int mplCompassRate;
   5782 
   5783 #ifdef ENABLE_MULTI_RATE
   5784     /* take care of case where only one type of gyro sensors or compass sensors is turned on */
   5785     gyroRate = mBatchDelays[Gyro] < mBatchDelays[RawGyro] ? mBatchDelays[Gyro] : mBatchDelays[RawGyro];
   5786     accelRate = mBatchDelays[Accelerometer];
   5787     compassRate = mBatchDelays[MagneticField] < mBatchDelays[RawMagneticField] ? mBatchDelays[MagneticField] : mBatchDelays[RawMagneticField];
   5788     pressureRate = mBatchDelays[Pressure];
   5789 
   5790     mplGyroRate = (int) gyroRate / 1000LL;
   5791     mplAccelRate = (int) accelRate / 1000LL;
   5792     mplCompassRate = (int) compassRate / 1000LL;
   5793 
   5794      /* set rate in MPL */
   5795      /* compass can only do 100Hz max */
   5796     inv_set_gyro_sample_rate(mplGyroRate);
   5797     inv_set_accel_sample_rate(mplAccelRate);
   5798     inv_set_compass_sample_rate(mplCompassRate);
   5799 
   5800     LOGV_IF(PROCESS_VERBOSE,
   5801             "HAL:MPL gyro sample rate: (mpl)=%d us (mpu)=%.2f Hz", mplGyroRate, 1000000000.f / gyroRate);
   5802     LOGV_IF(PROCESS_VERBOSE,
   5803             "HAL:MPL accel sample rate: (mpl)=%d us (mpu)=%.2f Hz", mplAccelRate, 1000000000.f / accelRate);
   5804     LOGV_IF(PROCESS_VERBOSE,
   5805             "HAL:MPL compass sample rate: (mpl)=%d us (mpu)=%.2f Hz", mplCompassRate, 1000000000.f / compassRate);
   5806 
   5807 #else
   5808     /* search the minimum delay requested across all enabled sensors */
   5809     int64_t wanted = 1000000000LL;
   5810     for (int i = 1; i < NumSensors; i++) {
   5811         if (mBatchEnabled & (1 << i)) {
   5812             int64_t ns = mBatchDelays[i];
   5813             wanted = wanted < ns ? wanted : ns;
   5814         }
   5815     }
   5816     gyroRate = wanted;
   5817     accelRate = wanted;
   5818     compassRate = wanted;
   5819     pressureRate = wanted;
   5820 #endif
   5821 
   5822     LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %.0f > %s (%lld)",
   5823             1000000000.f / gyroRate, mpu.gyro_rate,
   5824             getTimestamp());
   5825     tempFd = open(mpu.gyro_rate, O_RDWR);
   5826     res = write_attribute_sensor(tempFd, 1000000000.f / gyroRate);
   5827     if(res < 0) {
   5828         LOGE("HAL:GYRO update delay error");
   5829     }
   5830 
   5831     LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %.0f > %s (%lld)",
   5832             1000000000.f / accelRate, mpu.accel_rate,
   5833             getTimestamp());
   5834     tempFd = open(mpu.accel_rate, O_RDWR);
   5835     res = write_attribute_sensor(tempFd, 1000000000.f / accelRate);
   5836     LOGE_IF(res < 0, "HAL:ACCEL update delay error");
   5837 
   5838     if (compassRate < mCompassSensor->getMinDelay() * 1000LL) {
   5839         compassRate = mCompassSensor->getMinDelay() * 1000LL;
   5840     }
   5841     mCompassSensor->setDelay(ID_M, compassRate);
   5842 
   5843     mPressureSensor->setDelay(ID_PS, pressureRate);
   5844 
   5845     return res;
   5846 }
   5847 
   5848 /* Set sensor rate */
   5849 /* this function should be optimized */
   5850 int MPLSensor::resetDataRates()
   5851 {
   5852     VFUNC_LOG;
   5853 
   5854     int res = 0;
   5855     int tempFd = -1;
   5856     int64_t wanted = 1000000000LL;
   5857 
   5858     int64_t gyroRate;
   5859     int64_t accelRate;
   5860     int64_t compassRate;
   5861     int64_t pressureRate;
   5862 
   5863     /* enable this once driver supports multi-rate in dmp off mode */
   5864 
   5865     /* search the minimum delay requested across all enabled sensors */
   5866     for (int i = 1; i < NumSensors; i++) {
   5867         if (mEnabled & (1 << i)) {
   5868             int64_t ns = mDelays[i];
   5869             wanted = wanted < ns ? wanted : ns;
   5870         }
   5871     }
   5872 
   5873     if (mDmpOn == 1) {
   5874         gyroRate = mDelays[Gyro] < mDelays[RawGyro] ? mDelays[Gyro] : mDelays[RawGyro];
   5875         accelRate = mDelays[Accelerometer];
   5876         compassRate = mDelays[MagneticField] < mDelays[RawMagneticField] ? mDelays[MagneticField] : mDelays[RawMagneticField];
   5877         pressureRate = mDelays[Pressure];
   5878 
   5879 #ifndef ENABLE_MULTI_RATE
   5880         gyroRate = wanted;
   5881         accelRate = wanted;
   5882         compassRate = wanted;
   5883         pressureRate = wanted;
   5884 #endif
   5885 
   5886     } else {
   5887         gyroRate = wanted;
   5888         accelRate = wanted;
   5889         compassRate = wanted;
   5890         pressureRate = wanted;
   5891     }
   5892 
   5893     /* set mpl data rate */
   5894     inv_set_gyro_sample_rate((int)gyroRate/1000LL);
   5895     inv_set_accel_sample_rate((int)accelRate/1000LL);
   5896     inv_set_compass_sample_rate((int)compassRate/1000LL);
   5897 
   5898    LOGV_IF(PROCESS_VERBOSE,
   5899             "HAL:MPL gyro sample rate: (mpl)=%lld us (mpu)=%.2f Hz", gyroRate/1000LL, 1000000000.f / gyroRate);
   5900    LOGV_IF(PROCESS_VERBOSE,
   5901             "HAL:MPL accel sample rate: (mpl)=%lld us (mpu)=%.2f Hz", accelRate/1000LL, 1000000000.f / accelRate);
   5902    LOGV_IF(PROCESS_VERBOSE,
   5903             "HAL:MPL compass sample rate: (mpl)=%lld us (mpu)=%.2f Hz", compassRate/1000LL, 1000000000.f / compassRate);
   5904 
   5905     /* reset dmp rate */
   5906     getDmpRate (&wanted);
   5907 
   5908     LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %.0f > %s (%lld)",
   5909             1000000000.f / wanted, mpu.gyro_fifo_rate,
   5910             getTimestamp());
   5911     tempFd = open(mpu.gyro_fifo_rate, O_RDWR);
   5912     res = write_attribute_sensor(tempFd, 1000000000.f / wanted);
   5913     LOGE_IF(res < 0, "HAL:sampling frequency update delay error");
   5914 
   5915     LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %.0f > %s (%lld)",
   5916             1000000000.f / gyroRate, mpu.gyro_rate,
   5917             getTimestamp());
   5918     tempFd = open(mpu.gyro_rate, O_RDWR);
   5919     res = write_attribute_sensor(tempFd, 1000000000.f / gyroRate);
   5920     if(res < 0) {
   5921         LOGE("HAL:GYRO update delay error");
   5922     }
   5923 
   5924     LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %.0f > %s (%lld)",
   5925             1000000000.f / accelRate, mpu.accel_rate,
   5926             getTimestamp());
   5927     tempFd = open(mpu.accel_rate, O_RDWR);
   5928     res = write_attribute_sensor(tempFd, 1000000000.f / accelRate);
   5929     LOGE_IF(res < 0, "HAL:ACCEL update delay error");
   5930 
   5931     if (compassRate < mCompassSensor->getMinDelay() * 1000LL) {
   5932         compassRate = mCompassSensor->getMinDelay() * 1000LL;
   5933     }
   5934     mCompassSensor->setDelay(ID_M, compassRate);
   5935 
   5936     mPressureSensor->setDelay(ID_PS, pressureRate);
   5937 
   5938     return res;
   5939 }
   5940 
   5941 void MPLSensor::initBias()
   5942 {
   5943     LOGV_IF(ENG_VERBOSE, "HAL:inititalize dmp and device offsets to 0");
   5944 
   5945     if(write_attribute_sensor_continuous(accel_x_dmp_bias_fd, 0) < 0)
   5946     {
   5947         LOGE("HAL:Error writing to accel_x_dmp_bias");
   5948     }
   5949     if(write_attribute_sensor_continuous(accel_y_dmp_bias_fd, 0) < 0)
   5950     {
   5951         LOGE("HAL:Error writing to accel_y_dmp_bias");
   5952     }
   5953     if(write_attribute_sensor_continuous(accel_z_dmp_bias_fd, 0) < 0)
   5954     {
   5955         LOGE("HAL:Error writing to accel_z_dmp_bias");
   5956     }
   5957 
   5958     if(write_attribute_sensor_continuous(gyro_x_dmp_bias_fd, 0) < 0)
   5959     {
   5960         LOGE("HAL:Error writing to gyro_x_dmp_bias");
   5961     }
   5962     if(write_attribute_sensor_continuous(gyro_y_dmp_bias_fd, 0) < 0)
   5963     {
   5964         LOGE("HAL:Error writing to gyro_y_dmp_bias");
   5965     }
   5966      if(write_attribute_sensor_continuous(gyro_z_dmp_bias_fd, 0) < 0)
   5967     {
   5968         LOGE("HAL:Error writing to gyro_z_dmp_bias");
   5969     }
   5970 
   5971     if(write_attribute_sensor_continuous(gyro_x_offset_fd, 0) < 0)
   5972     {
   5973         LOGE("HAL:Error writing to gyro_x_offset");
   5974     }
   5975     if(write_attribute_sensor_continuous(gyro_y_offset_fd, 0) < 0)
   5976     {
   5977         LOGE("HAL:Error writing to gyro_y_offset");
   5978     }
   5979     if(write_attribute_sensor_continuous(gyro_z_offset_fd, 0) < 0)
   5980     {
   5981         LOGE("HAL:Error writing to gyro_z_offset");
   5982     }
   5983     return;
   5984 }
   5985 
   5986 /*TODO: reg_dump in a separate file*/
   5987 void MPLSensor::sys_dump(bool fileMode)
   5988 {
   5989     VFUNC_LOG;
   5990 
   5991     char sysfs_path[MAX_SYSFS_NAME_LEN];
   5992     char scan_element_path[MAX_SYSFS_NAME_LEN];
   5993 
   5994     memset(sysfs_path, 0, sizeof(sysfs_path));
   5995     memset(scan_element_path, 0, sizeof(scan_element_path));
   5996     inv_get_sysfs_path(sysfs_path);
   5997     sprintf(scan_element_path, "%s%s", sysfs_path, "/scan_elements");
   5998 
   5999     read_sysfs_dir(fileMode, sysfs_path);
   6000     read_sysfs_dir(fileMode, scan_element_path);
   6001 
   6002     dump_dmp_img("/data/local/read_img.h");
   6003     return;
   6004 }
   6005