149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow/*
249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow* Copyright (C) 2012 Invensense, Inc.
349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow*
449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow* Licensed under the Apache License, Version 2.0 (the "License");
549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow* you may not use this file except in compliance with the License.
649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow* You may obtain a copy of the License at
749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow*
849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow*      http://www.apache.org/licenses/LICENSE-2.0
949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow*
1049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow* Unless required by applicable law or agreed to in writing, software
1149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow* distributed under the License is distributed on an "AS IS" BASIS,
1249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow* See the License for the specific language governing permissions and
1449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow* limitations under the License.
1549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow*/
1649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
1749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow#define LOG_NDEBUG 0
1849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
1949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow//#define KLP 1 //Key Lime Pie Temporary Test Define
2049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow//see also the EXTRA_VERBOSE define in the MPLSensor.h header file
2149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
2249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow#include <fcntl.h>
2349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow#include <errno.h>
2449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow#include <math.h>
2549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow#include <float.h>
2649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow#include <poll.h>
2749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow#include <unistd.h>
2849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow#include <dirent.h>
2949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow#include <stdlib.h>
3049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow#include <sys/select.h>
3149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow#include <sys/syscall.h>
3249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow#include <dlfcn.h>
3349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow#include <pthread.h>
3449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow#include <cutils/log.h>
3549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow#include <utils/KeyedVector.h>
3649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow#include <utils/String8.h>
3749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow#include <string.h>
3849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow#include <linux/input.h>
3949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow#include <utils/Atomic.h>
4049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
4149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow#include "MPLSensor.h"
4249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow#include "PressureSensor.IIO.secondary.h"
4349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow#include "MPLSupport.h"
4449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow#include "sensor_params.h"
4549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
4649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow#include "invensense.h"
4749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow#include "invensense_adv.h"
4849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow#include "ml_stored_data.h"
4949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow#include "ml_load_dmp.h"
5049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow#include "ml_sysfs_helper.h"
5149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
524a28f9c897c46c42a255823f7e307169a828a025Rosa Chow#define ENABLE_MULTI_RATE
5349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow// #define TESTING
5449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow// #define USE_LPQ_AT_FASTEST
554a28f9c897c46c42a255823f7e307169a828a025Rosa Chow#define ENABLE_PRESSSURE
5649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
5749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow#ifdef THIRD_PARTY_ACCEL
5849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow#pragma message("HAL:build third party accel support")
5949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow#define USE_THIRD_PARTY_ACCEL (1)
6049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow#else
6149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow#define USE_THIRD_PARTY_ACCEL (0)
6249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow#endif
6349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
6449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow#define MAX_SYSFS_ATTRB (sizeof(struct sysfs_attrbs) / sizeof(char*))
6549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
6649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow/******************************************************************************/
6749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow/*  MPL interface misc.                                                       */
6849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow/******************************************************************************/
6949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chowstatic int hertz_request = 200;
7049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
7149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow#define DEFAULT_MPL_GYRO_RATE           (20000L)     //us
7249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow#define DEFAULT_MPL_COMPASS_RATE        (20000L)     //us
7349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
7449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow#define DEFAULT_HW_GYRO_RATE            (100)        //Hz
7549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow#define DEFAULT_HW_ACCEL_RATE           (20)         //ms
7649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow#define DEFAULT_HW_COMPASS_RATE         (20000000L)  //ns
7749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow#define DEFAULT_HW_AKMD_COMPASS_RATE    (200000000L) //ns
7849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
7949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow/* convert ns to hardware units */
8049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow#define HW_GYRO_RATE_NS                 (1000000000LL / rate_request) // to Hz
8149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow#define HW_ACCEL_RATE_NS                (rate_request / (1000000L))   // to ms
8249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow#define HW_COMPASS_RATE_NS              (rate_request)                // to ns
8349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
8449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow/* convert Hz to hardware units */
8549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow#define HW_GYRO_RATE_HZ                 (hertz_request)
8649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow#define HW_ACCEL_RATE_HZ                (1000 / hertz_request)
8749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow#define HW_COMPASS_RATE_HZ              (1000000000LL / hertz_request)
8849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
8949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow#define RATE_200HZ                      5000000LL
9049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow#define RATE_15HZ                       66667000LL
9149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow#define RATE_5HZ                        200000000LL
9249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
9349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow// mask of virtual sensors that require gyro + accel + compass data
9449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow#define VIRTUAL_SENSOR_9AXES_MASK ( \
9549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        (1 << Orientation)          \
9649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        | (1 << RotationVector)     \
9749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        | (1 << LinearAccel)        \
9849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        | (1 << Gravity)            \
9949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow)
10049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow// mask of virtual sensors that require gyro + accel data (but no compass data)
10149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow#define VIRTUAL_SENSOR_GYRO_6AXES_MASK ( \
10249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        (1 << GameRotationVector)   \
10349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow)
10449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow// mask of virtual sensors that require mag + accel data (but no gyro data)
10549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow#define VIRTUAL_SENSOR_MAG_6AXES_MASK (    \
10649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        (1 << GeomagneticRotationVector)   \
10749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow)
10849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow// mask of all virtual sensors
10949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow#define VIRTUAL_SENSOR_ALL_MASK (       \
11049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        VIRTUAL_SENSOR_9AXES_MASK       \
11149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        | VIRTUAL_SENSOR_GYRO_6AXES_MASK     \
11249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        | VIRTUAL_SENSOR_MAG_6AXES_MASK \
11349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow)
11449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
11549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chowstatic struct timespec mt_pre;
11649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chowstatic struct sensor_t sSensorList[] =
11749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow{
11849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    {"MPL Gyroscope", "Invensense", 1,
11949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow     SENSORS_GYROSCOPE_HANDLE,
1209b98ed996e18d6097c9976c9cfe9a0c9397998feMathias Agopian     SENSOR_TYPE_GYROSCOPE, 2000.0f, 1.0f, 0.5f, 10000, 0, 0, {}},
12149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    {"MPL Raw Gyroscope", "Invensense", 1,
12249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow     SENSORS_RAW_GYROSCOPE_HANDLE,
1239b98ed996e18d6097c9976c9cfe9a0c9397998feMathias Agopian     SENSOR_TYPE_GYROSCOPE_UNCALIBRATED, 2000.0f, 1.0f, 0.5f, 10000, 0, 0, {}},
12449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    {"MPL Accelerometer", "Invensense", 1,
12549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow     SENSORS_ACCELERATION_HANDLE,
1269b98ed996e18d6097c9976c9cfe9a0c9397998feMathias Agopian     SENSOR_TYPE_ACCELEROMETER, 10240.0f, 1.0f, 0.5f, 10000, 0, 0, {}},
12749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    {"MPL Magnetic Field", "Invensense", 1,
12849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow     SENSORS_MAGNETIC_FIELD_HANDLE,
1299b98ed996e18d6097c9976c9cfe9a0c9397998feMathias Agopian     SENSOR_TYPE_MAGNETIC_FIELD, 10240.0f, 1.0f, 0.5f, 10000, 0, 0, {}},
13049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow#ifdef ENABLE_PRESSURE
13149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow     {"MPL Pressure", "Invensense", 1,
13249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow     SENSORS_PRESSURE_HANDLE,
1339b98ed996e18d6097c9976c9cfe9a0c9397998feMathias Agopian     SENSOR_TYPE_PRESSURE, 10240.0f, 1.0f, 0.5f, 10000, 0, 0, {}},
13449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow#endif
13549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    {"MPL Raw Magnetic Field", "Invensense", 1,
13649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow     SENSORS_RAW_MAGNETIC_FIELD_HANDLE,
1379b98ed996e18d6097c9976c9cfe9a0c9397998feMathias Agopian     SENSOR_TYPE_MAGNETIC_FIELD_UNCALIBRATED, 10240.0f, 1.0f, 0.5f, 10000, 0, 0, {}},
13849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    {"MPL Orientation", "Invensense", 1,
13949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow     SENSORS_ORIENTATION_HANDLE,
1409b98ed996e18d6097c9976c9cfe9a0c9397998feMathias Agopian     SENSOR_TYPE_ORIENTATION, 360.0f, 1.0f, 9.7f, 10000, 0, 0, {}},
14149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    {"MPL Rotation Vector", "Invensense", 1,
14249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow     SENSORS_ROTATION_VECTOR_HANDLE,
1439b98ed996e18d6097c9976c9cfe9a0c9397998feMathias Agopian     SENSOR_TYPE_ROTATION_VECTOR, 10240.0f, 1.0f, 0.5f, 10000, 0, 0, {}},
14449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    {"MPL Game Rotation Vector", "Invensense", 1,
14549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow     SENSORS_GAME_ROTATION_VECTOR_HANDLE,
1469b98ed996e18d6097c9976c9cfe9a0c9397998feMathias Agopian     SENSOR_TYPE_GAME_ROTATION_VECTOR, 10240.0f, 1.0f, 0.5f, 10000, 0, 0, {}},
14749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    {"MPL Linear Acceleration", "Invensense", 1,
14849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow     SENSORS_LINEAR_ACCEL_HANDLE,
1499b98ed996e18d6097c9976c9cfe9a0c9397998feMathias Agopian     SENSOR_TYPE_LINEAR_ACCELERATION, 10240.0f, 1.0f, 0.5f, 10000, 0, 0, {}},
15049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    {"MPL Gravity", "Invensense", 1,
15149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow     SENSORS_GRAVITY_HANDLE,
1529b98ed996e18d6097c9976c9cfe9a0c9397998feMathias Agopian     SENSOR_TYPE_GRAVITY, 10240.0f, 1.0f, 0.5f, 10000, 0, 0, {}},
15349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    {"MPL Significant Motion", "Invensense", 1,
15449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow     SENSORS_SIGNIFICANT_MOTION_HANDLE,
1559b98ed996e18d6097c9976c9cfe9a0c9397998feMathias Agopian     SENSOR_TYPE_SIGNIFICANT_MOTION, 100.0f, 1.0f, 1.1f, 0, 0, 0, {}},
15649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    {"MPL Step Detector", "Invensense", 1,
15749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow     SENSORS_PEDOMETER_HANDLE,
1589b98ed996e18d6097c9976c9cfe9a0c9397998feMathias Agopian     SENSOR_TYPE_STEP_DETECTOR, 100.0f, 1.0f, 1.1f, 0, 0, 0, {}},
15949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    {"MPL Step Counter", "Invensense", 1,
16049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow     SENSORS_STEP_COUNTER_HANDLE,
1619b98ed996e18d6097c9976c9cfe9a0c9397998feMathias Agopian     SENSOR_TYPE_STEP_COUNTER, 100.0f, 1.0f, 1.1f, 0, 0, 0, {}},
16249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    {"MPL Geomagnetic Rotation Vector", "Invensense", 1,
16349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow     SENSORS_GEOMAGNETIC_ROTATION_VECTOR_HANDLE,
1649b98ed996e18d6097c9976c9cfe9a0c9397998feMathias Agopian     SENSOR_TYPE_GEOMAGNETIC_ROTATION_VECTOR, 10240.0f, 1.0f, 0.5f, 10000, 0, 0, {}},
16549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow#ifdef ENABLE_DMP_SCREEN_AUTO_ROTATION
16649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    {"MPL Screen Orientation", "Invensense ", 1,
16749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow     SENSORS_SCREEN_ORIENTATION_HANDLE,
1689b98ed996e18d6097c9976c9cfe9a0c9397998feMathias Agopian     SENSOR_TYPE_SCREEN_ORIENTATION, 100.0f, 1.0f, 1.1f, 0, 0, 0, {}},
16949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow#endif
17049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow};
17149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
17249ea3e26ca3c6a779e527a0322e49a663333350aRosa ChowMPLSensor *MPLSensor::gMPLSensor = NULL;
17349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
17449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chowextern "C" {
17549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chowvoid procData_cb_wrapper()
17649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow{
17749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    if(MPLSensor::gMPLSensor) {
17849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        MPLSensor::gMPLSensor->cbProcData();
17949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    }
18049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow}
18149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
18249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chowvoid setCallbackObject(MPLSensor* gbpt)
18349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow{
18449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    MPLSensor::gMPLSensor = gbpt;
18549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow}
18649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
18749ea3e26ca3c6a779e527a0322e49a663333350aRosa ChowMPLSensor* getCallbackObject() {
18849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    return MPLSensor::gMPLSensor;
18949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow}
19049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
19149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow} // end of extern C
19249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
1934a28f9c897c46c42a255823f7e307169a828a025Rosa Chow//#define IINV_PLAYBACK_DBG
19449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow#ifdef INV_PLAYBACK_DBG
19549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chowstatic FILE *logfile = NULL;
19649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow#endif
19749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
19849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow/*******************************************************************************
19949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow * MPLSensor class implementation
20049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow ******************************************************************************/
20149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
20249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow// following extended initializer list would only be available with -std=c++11
20349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow//  or -std=gnu+11
20449ea3e26ca3c6a779e527a0322e49a663333350aRosa ChowMPLSensor::MPLSensor(CompassSensor *compass, int (*m_pt2AccelCalLoadFunc)(long *))
20549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                       : SensorBase(NULL, NULL),
20649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                         mNewData(0),
20749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                         mMasterSensorMask(INV_ALL_SENSORS),
20849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                         mLocalSensorMask(0),
20949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                         mPollTime(-1),
21049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                         mStepCountPollTime(-1),
21149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                         mHaveGoodMpuCal(0),
21249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                         mGyroAccuracy(0),
21349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                         mAccelAccuracy(0),
21449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                         mCompassAccuracy(0),
21549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                         mSampleCount(0),
21649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                         dmp_orient_fd(-1),
21749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                         mDmpOrientationEnabled(0),
21849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                         dmp_sign_motion_fd(-1),
21949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                         mDmpSignificantMotionEnabled(0),
22049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                         dmp_pedometer_fd(-1),
22149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                         mDmpPedometerEnabled(0),
22249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                         mDmpStepCountEnabled(0),
22349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                         mEnabled(0),
22449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                         mBatchEnabled(0),
22549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                         mAccelInputReader(4),
22649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                         mGyroInputReader(32),
22749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                         mTempScale(0),
22849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                         mTempOffset(0),
22949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                         mTempCurrentTime(0),
23049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                         mAccelScale(2),
23149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                         mGyroScale(2000),
23249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                         mCompassScale(0),
23349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                         mFactoryGyroBiasAvailable(false),
23449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                         mGyroBiasAvailable(false),
23549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                         mGyroBiasApplied(false),
23649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                         mFactoryAccelBiasAvailable(false),
23749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                         mAccelBiasAvailable(false),
23849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                         mAccelBiasApplied(false),
23949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                         mPendingMask(0),
24049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                         mSensorMask(0),
24149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                         mMplFeatureActiveMask(0),
24249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                         mFeatureActiveMask(0),
24349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                         mDmpOn(0),
24449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                         mPedUpdate(0),
24549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                         mQuatSensorTimestamp(0),
2464a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                         mStepSensorTimestamp(0),
2474a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                         mLastStepCount(0),
2484a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                         mLeftOverBufferSize(0) {
24949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    VFUNC_LOG;
25049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
25149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    inv_error_t rv;
25249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    int i, fd;
25349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    char *port = NULL;
25449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    char *ver_str;
25549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    unsigned long mSensorMask;
25649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    int res;
25749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    FILE *fptr;
25849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
25949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    mCompassSensor = compass;
26049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
26149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    LOGV_IF(EXTRA_VERBOSE,
26249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            "HAL:MPLSensor constructor : NumSensors = %d", NumSensors);
26349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
26449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    pthread_mutex_init(&mMplMutex, NULL);
26549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    pthread_mutex_init(&mHALMutex, NULL);
26649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    memset(mGyroOrientation, 0, sizeof(mGyroOrientation));
26749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    memset(mAccelOrientation, 0, sizeof(mAccelOrientation));
26849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
26949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    /* setup sysfs paths */
27049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    inv_init_sysfs_attributes();
27149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
27249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    /* get chip name */
27349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    if (inv_get_chip_name(chip_ID) != INV_SUCCESS) {
27449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        LOGE("HAL:ERR- Failed to get chip ID\n");
27549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    } else {
27649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        LOGV_IF(PROCESS_VERBOSE, "HAL:Chip ID= %s\n", chip_ID);
27749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    }
27849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
27949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    enable_iio_sysfs();
28049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
28149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    /* instantiate pressure sensor on secondary bus */
28249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    if (strcmp(mSysfsPath, "") != 0) {
28349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        mPressureSensor = new PressureSensor((const char*)mSysfsPath);
28449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    } else {
28549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        LOGE("HAL:ERR - Failed to instantiate pressure sensor class");
28649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    }
28749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
28849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    /* reset driver master enable */
28949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    masterEnable(0);
29049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
29149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    //Always load DMP for KLP
29249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    /* Load DMP image if capable, ie. MPU6xxx/9xxx */
29349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    loadDMP();
29449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
29549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    /* open temperature fd for temp comp */
29649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    LOGV_IF(EXTRA_VERBOSE, "HAL:gyro temperature path: %s", mpu.temperature);
29749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    gyro_temperature_fd = open(mpu.temperature, O_RDONLY);
29849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    if (gyro_temperature_fd == -1) {
29949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        LOGE("HAL:could not open temperature node");
30049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    } else {
30149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        LOGV_IF(EXTRA_VERBOSE,
30249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                "HAL:temperature_fd opened: %s", mpu.temperature);
30349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    }
30449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
30549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    /* read gyro FSR to calculate accel scale later */
30649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    char gyroBuf[5];
30749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    int count = 0;
30849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow         LOGV_IF(SYSFS_VERBOSE,
30949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow             "HAL:sysfs:cat %s (%lld)", mpu.gyro_fsr, getTimestamp());
31049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
31149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    fd = open(mpu.gyro_fsr, O_RDONLY);
31249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    if(fd < 0) {
31349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        LOGE("HAL:Error opening gyro FSR");
31449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    } else {
31549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        memset(gyroBuf, 0, sizeof(gyroBuf));
31649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        count = read_attribute_sensor(fd, gyroBuf, sizeof(gyroBuf));
31749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        if(count < 1) {
31849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            LOGE("HAL:Error reading gyro FSR");
31949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        } else {
32049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            count = sscanf(gyroBuf, "%ld", &mGyroScale);
32149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            if(count)
32249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                LOGV_IF(EXTRA_VERBOSE, "HAL:Gyro FSR used %ld", mGyroScale);
32349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        }
32449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        close(fd);
32549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    }
3264a28f9c897c46c42a255823f7e307169a828a025Rosa Chow
3274a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    /* read gyro self test scale used to calculate factory cal bias later */
3284a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    char gyroScale[5];
3294a28f9c897c46c42a255823f7e307169a828a025Rosa Chow         LOGV_IF(SYSFS_VERBOSE,
3304a28f9c897c46c42a255823f7e307169a828a025Rosa Chow             "HAL:sysfs:cat %s (%lld)", mpu.in_gyro_self_test_scale, getTimestamp());
3314a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    fd = open(mpu.in_gyro_self_test_scale, O_RDONLY);
3324a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    if(fd < 0) {
3334a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        LOGE("HAL:Error opening gyro self test scale");
3344a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    } else {
3354a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        memset(gyroBuf, 0, sizeof(gyroBuf));
3364a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        count = read_attribute_sensor(fd, gyroScale, sizeof(gyroScale));
3374a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        if(count < 1) {
3384a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            LOGE("HAL:Error reading gyro self test scale");
3394a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        } else {
3404a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            count = sscanf(gyroScale, "%ld", &mGyroSelfTestScale);
3414a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            if(count)
3424a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                LOGV_IF(EXTRA_VERBOSE, "HAL:Gyro self test scale used %ld", mGyroSelfTestScale);
3434a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        }
3444a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        close(fd);
3454a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    }
34649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
34749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    /* open Factory Gyro Bias fd */
3484a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    /* mFactoryGyBias contains bias values that will be used for device offset */
34949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    memset(mFactoryGyroBias, 0, sizeof(mFactoryGyroBias));
35049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    LOGV_IF(EXTRA_VERBOSE, "HAL:factory gyro x offset path: %s", mpu.in_gyro_x_offset);
35149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    LOGV_IF(EXTRA_VERBOSE, "HAL:factory gyro y offset path: %s", mpu.in_gyro_y_offset);
3524a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    LOGV_IF(EXTRA_VERBOSE, "HAL:factory gyro z offset path: %s", mpu.in_gyro_z_offset);
35349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    gyro_x_offset_fd = open(mpu.in_gyro_x_offset, O_RDWR);
35449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    gyro_y_offset_fd = open(mpu.in_gyro_y_offset, O_RDWR);
35549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    gyro_z_offset_fd = open(mpu.in_gyro_z_offset, O_RDWR);
35649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    if (gyro_x_offset_fd == -1 ||
35749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow             gyro_y_offset_fd == -1 || gyro_z_offset_fd == -1) {
35849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            LOGE("HAL:could not open factory gyro calibrated bias");
35949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    } else {
36049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        LOGV_IF(EXTRA_VERBOSE,
36149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow             "HAL:gyro_offset opened");
36249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    }
36349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
36449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    /* open Gyro Bias fd */
3654a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    /* mGyroBias contains bias values that will be used for framework */
3664a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    /* mGyroChipBias contains bias values that will be used for dmp */
36749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    memset(mGyroBias, 0, sizeof(mGyroBias));
36849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    memset(mGyroChipBias, 0, sizeof(mGyroChipBias));
36949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    LOGV_IF(EXTRA_VERBOSE, "HAL: gyro x dmp bias path: %s", mpu.in_gyro_x_dmp_bias);
37049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    LOGV_IF(EXTRA_VERBOSE, "HAL: gyro y dmp bias path: %s", mpu.in_gyro_y_dmp_bias);
37149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    LOGV_IF(EXTRA_VERBOSE, "HAL: gyro z dmp bias path: %s", mpu.in_gyro_z_dmp_bias);
37249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    gyro_x_dmp_bias_fd = open(mpu.in_gyro_x_dmp_bias, O_RDWR);
37349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    gyro_y_dmp_bias_fd = open(mpu.in_gyro_y_dmp_bias, O_RDWR);
37449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    gyro_z_dmp_bias_fd = open(mpu.in_gyro_z_dmp_bias, O_RDWR);
37549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    if (gyro_x_dmp_bias_fd == -1 ||
37649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow             gyro_y_dmp_bias_fd == -1 || gyro_z_dmp_bias_fd == -1) {
37749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            LOGE("HAL:could not open gyro DMP calibrated bias");
37849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    } else {
37949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        LOGV_IF(EXTRA_VERBOSE,
38049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow             "HAL:gyro_dmp_bias opened");
38149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    }
38249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
38349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    /* read accel FSR to calcuate accel scale later */
38449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    if (USE_THIRD_PARTY_ACCEL == 0) {
38549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        char buf[3];
38649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        int count = 0;
38749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        LOGV_IF(SYSFS_VERBOSE,
38849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                "HAL:sysfs:cat %s (%lld)", mpu.accel_fsr, getTimestamp());
38949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
39049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        fd = open(mpu.accel_fsr, O_RDONLY);
39149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        if(fd < 0) {
39249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            LOGE("HAL:Error opening accel FSR");
39349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        } else {
39449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow           memset(buf, 0, sizeof(buf));
39549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow           count = read_attribute_sensor(fd, buf, sizeof(buf));
39649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow           if(count < 1) {
39749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow               LOGE("HAL:Error reading accel FSR");
39849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow           } else {
39949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow               count = sscanf(buf, "%d", &mAccelScale);
40049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow               if(count)
40149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                   LOGV_IF(EXTRA_VERBOSE, "HAL:Accel FSR used %d", mAccelScale);
40249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow           }
40349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow           close(fd);
40449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        }
40549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
40649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        /* open Accel Bias fd */
4074a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        /* mAccelBias contains bias that will be used for dmp */
40849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        memset(mAccelBias, 0, sizeof(mAccelBias));
40949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        LOGV_IF(EXTRA_VERBOSE, "HAL:accel x dmp bias path: %s", mpu.in_accel_x_dmp_bias);
41049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        LOGV_IF(EXTRA_VERBOSE, "HAL:accel y dmp bias path: %s", mpu.in_accel_y_dmp_bias);
41149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        LOGV_IF(EXTRA_VERBOSE, "HAL:accel z dmp bias path: %s", mpu.in_accel_z_dmp_bias);
41249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        accel_x_dmp_bias_fd = open(mpu.in_accel_x_dmp_bias, O_RDWR);
41349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        accel_y_dmp_bias_fd = open(mpu.in_accel_y_dmp_bias, O_RDWR);
41449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        accel_z_dmp_bias_fd = open(mpu.in_accel_z_dmp_bias, O_RDWR);
41549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        if (accel_x_dmp_bias_fd == -1 ||
41649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                 accel_y_dmp_bias_fd == -1 || accel_z_dmp_bias_fd == -1) {
41749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            LOGE("HAL:could not open accel DMP calibrated bias");
41849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        } else {
41949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            LOGV_IF(EXTRA_VERBOSE,
42049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                 "HAL:accel_dmp_bias opened");
42149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        }
42249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    }
42349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
42449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    dmp_sign_motion_fd = open(mpu.event_smd, O_RDONLY | O_NONBLOCK);
42549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    if (dmp_sign_motion_fd < 0) {
42649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        LOGE("HAL:ERR couldn't open dmp_sign_motion node");
42749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    } else {
42849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        LOGV_IF(PROCESS_VERBOSE, "HAL:dmp_sign_motion_fd opened : %d", dmp_sign_motion_fd);
42949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    }
43049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
43149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    dmp_pedometer_fd = open(mpu.event_pedometer, O_RDONLY | O_NONBLOCK);
43249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    if (dmp_pedometer_fd < 0) {
43349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        LOGE("HAL:ERR couldn't open dmp_pedometer node");
43449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    } else {
43549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        LOGV_IF(PROCESS_VERBOSE, "HAL:dmp_pedometer_fd opened : %d", dmp_pedometer_fd);
43649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    }
43749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
4384a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    initBias();
4394a28f9c897c46c42a255823f7e307169a828a025Rosa Chow
4404a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    (void)inv_get_version(&ver_str);
4414a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    LOGV_IF(PROCESS_VERBOSE, "%s\n", ver_str);
4424a28f9c897c46c42a255823f7e307169a828a025Rosa Chow
4434a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    /* setup MPL */
4444a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    inv_constructor_init();
4454a28f9c897c46c42a255823f7e307169a828a025Rosa Chow
4464a28f9c897c46c42a255823f7e307169a828a025Rosa Chow#ifdef INV_PLAYBACK_DBG
4474a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    LOGV_IF(PROCESS_VERBOSE, "HAL:inv_turn_on_data_logging");
4484a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    logfile = fopen("/data/playback.bin", "w+");
4494a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    if (logfile)
4504a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        inv_turn_on_data_logging(logfile);
4514a28f9c897c46c42a255823f7e307169a828a025Rosa Chow#endif
4524a28f9c897c46c42a255823f7e307169a828a025Rosa Chow
4534a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    /* setup orientation matrix and scale */
4544a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    inv_set_device_properties();
4554a28f9c897c46c42a255823f7e307169a828a025Rosa Chow
45649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    /* initialize sensor data */
45749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    memset(mPendingEvents, 0, sizeof(mPendingEvents));
45849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
45949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    mPendingEvents[RotationVector].version = sizeof(sensors_event_t);
46049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    mPendingEvents[RotationVector].sensor = ID_RV;
46149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    mPendingEvents[RotationVector].type = SENSOR_TYPE_ROTATION_VECTOR;
46249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    mPendingEvents[RotationVector].acceleration.status
46349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            = SENSOR_STATUS_ACCURACY_HIGH;
46449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
46549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    mPendingEvents[GameRotationVector].version = sizeof(sensors_event_t);
46649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    mPendingEvents[GameRotationVector].sensor = ID_GRV;
46749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    mPendingEvents[GameRotationVector].type = SENSOR_TYPE_GAME_ROTATION_VECTOR;
46849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    mPendingEvents[GameRotationVector].acceleration.status
46949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            = SENSOR_STATUS_ACCURACY_HIGH;
47049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
47149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    mPendingEvents[LinearAccel].version = sizeof(sensors_event_t);
47249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    mPendingEvents[LinearAccel].sensor = ID_LA;
47349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    mPendingEvents[LinearAccel].type = SENSOR_TYPE_LINEAR_ACCELERATION;
47449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    mPendingEvents[LinearAccel].acceleration.status
47549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            = SENSOR_STATUS_ACCURACY_HIGH;
47649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
47749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    mPendingEvents[Gravity].version = sizeof(sensors_event_t);
47849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    mPendingEvents[Gravity].sensor = ID_GR;
47949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    mPendingEvents[Gravity].type = SENSOR_TYPE_GRAVITY;
48049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    mPendingEvents[Gravity].acceleration.status = SENSOR_STATUS_ACCURACY_HIGH;
48149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
48249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    mPendingEvents[Gyro].version = sizeof(sensors_event_t);
48349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    mPendingEvents[Gyro].sensor = ID_GY;
48449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    mPendingEvents[Gyro].type = SENSOR_TYPE_GYROSCOPE;
48549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    mPendingEvents[Gyro].gyro.status = SENSOR_STATUS_ACCURACY_HIGH;
48649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
48749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    mPendingEvents[RawGyro].version = sizeof(sensors_event_t);
48849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    mPendingEvents[RawGyro].sensor = ID_RG;
48949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    mPendingEvents[RawGyro].type = SENSOR_TYPE_GYROSCOPE_UNCALIBRATED;
49049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    mPendingEvents[RawGyro].gyro.status = SENSOR_STATUS_ACCURACY_HIGH;
49149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
49249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    mPendingEvents[Accelerometer].version = sizeof(sensors_event_t);
49349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    mPendingEvents[Accelerometer].sensor = ID_A;
49449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    mPendingEvents[Accelerometer].type = SENSOR_TYPE_ACCELEROMETER;
49549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    mPendingEvents[Accelerometer].acceleration.status
49649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            = SENSOR_STATUS_ACCURACY_HIGH;
49749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
49849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    /* Invensense compass calibration */
49949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    mPendingEvents[MagneticField].version = sizeof(sensors_event_t);
50049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    mPendingEvents[MagneticField].sensor = ID_M;
50149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    mPendingEvents[MagneticField].type = SENSOR_TYPE_MAGNETIC_FIELD;
50249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    mPendingEvents[MagneticField].magnetic.status =
50349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        SENSOR_STATUS_ACCURACY_HIGH;
50449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
50549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    mPendingEvents[RawMagneticField].version = sizeof(sensors_event_t);
50649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    mPendingEvents[RawMagneticField].sensor = ID_RM;
50749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    mPendingEvents[RawMagneticField].type = SENSOR_TYPE_MAGNETIC_FIELD_UNCALIBRATED;
50849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    mPendingEvents[RawMagneticField].magnetic.status =
50949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        SENSOR_STATUS_ACCURACY_HIGH;
51049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
51149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    mPendingEvents[Pressure].version = sizeof(sensors_event_t);
51249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    mPendingEvents[Pressure].sensor = ID_PS;
51349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    mPendingEvents[Pressure].type = SENSOR_TYPE_MAGNETIC_FIELD_UNCALIBRATED;
51449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    mPendingEvents[Pressure].magnetic.status =
51549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        SENSOR_STATUS_ACCURACY_HIGH;
51649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
51749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    mPendingEvents[Orientation].version = sizeof(sensors_event_t);
51849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    mPendingEvents[Orientation].sensor = ID_O;
51949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    mPendingEvents[Orientation].type = SENSOR_TYPE_ORIENTATION;
52049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    mPendingEvents[Orientation].orientation.status
52149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            = SENSOR_STATUS_ACCURACY_HIGH;
52249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
52349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    mPendingEvents[GeomagneticRotationVector].version = sizeof(sensors_event_t);
52449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    mPendingEvents[GeomagneticRotationVector].sensor = ID_GMRV;
52549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    mPendingEvents[GeomagneticRotationVector].type
52649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            = SENSOR_TYPE_GEOMAGNETIC_ROTATION_VECTOR;
52749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    mPendingEvents[GeomagneticRotationVector].acceleration.status
52849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            = SENSOR_STATUS_ACCURACY_HIGH;
52949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
53049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow#ifndef KLP
53149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    mHandlers[RotationVector] = &MPLSensor::rvHandler;
53249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow#else
53349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    mHandlers[RotationVector] = &MPLSensor::grvHandler;
53449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow#endif
53549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    mHandlers[GameRotationVector] = &MPLSensor::grvHandler;
53649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    mHandlers[LinearAccel] = &MPLSensor::laHandler;
53749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    mHandlers[Gravity] = &MPLSensor::gravHandler;
53849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow#ifndef KLP
53949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    mHandlers[Gyro] = &MPLSensor::gyroHandler;
54049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow#else
54149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    mHandlers[Gyro] = &MPLSensor::rawGyroHandler;
54249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow#endif
54349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    mHandlers[RawGyro] = &MPLSensor::rawGyroHandler;
54449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    mHandlers[Accelerometer] = &MPLSensor::accelHandler;
54549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow#ifndef KLP
54649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    mHandlers[MagneticField] = &MPLSensor::compassHandler;
54749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow#else
54849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    mHandlers[MagneticField] = &MPLSensor::rawCompassHandler;
54949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow#endif
55049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    mHandlers[RawMagneticField] = &MPLSensor::rawCompassHandler;
55149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    mHandlers[Orientation] = &MPLSensor::orienHandler;
55249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    mHandlers[GeomagneticRotationVector] = &MPLSensor::gmHandler;
55349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    mHandlers[Pressure] = &MPLSensor::psHandler;
55449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
55549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    for (int i = 0; i < NumSensors; i++) {
55649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        mDelays[i] = 1000000000LL;
55749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        mBatchDelays[i] = 1000000000LL;
5584a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        mBatchTimeouts[i] = 30000000000LL;
55949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    }
56049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
5614a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    /* initialize Compass Bias */
5624a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    memset(mCompassBias, 0, sizeof(mCompassBias));
56349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
5644a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    /* initialize Factory Accel Bias */
5654a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    memset(mFactoryAccelBias, 0, sizeof(mFactoryAccelBias));
56649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
5674a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    /* initialize Gyro Bias */
5684a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    memset(mGyroBias, 0, sizeof(mGyroBias));
5694a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    memset(mGyroChipBias, 0, sizeof(mGyroChipBias));
57049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
57149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    /* load calibration file from /data/inv_cal_data.bin */
5724a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    rv = inv_load_calibration();
57349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    if(rv == INV_SUCCESS) {
5744a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        LOGV_IF(PROCESS_VERBOSE, "HAL:Calibration file successfully loaded");
5754a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        /* Get initial values */
5764a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        getCompassBias();
5774a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        getGyroBias();
5784a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        getAccelBias();
57949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        getFactoryGyroBias();
5804a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        if (mFactoryGyroBiasAvailable) {
5814a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            setFactoryGyroBias();
5824a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        }
5834a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        /* disabled because no request for factory cal accel data yet */
5844a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        //getFactoryAccelBias();
58549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    }
58649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    else
58749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        LOGE("HAL:Could not open or load MPL calibration file (%d)", rv);
58849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
58949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    /* takes external accel calibration load workflow */
59049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    if( m_pt2AccelCalLoadFunc != NULL) {
59149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        long accel_offset[3];
59249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        long tmp_offset[3];
59349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        int result = m_pt2AccelCalLoadFunc(accel_offset);
59449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        if(result)
59549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            LOGW("HAL:Vendor accelerometer calibration file load failed %d\n",
59649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                 result);
59749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        else {
59849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            LOGW("HAL:Vendor accelerometer calibration file successfully "
59949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                 "loaded");
60049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            inv_get_accel_bias(tmp_offset, NULL);
60149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            LOGV_IF(PROCESS_VERBOSE,
60249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                    "HAL:Original accel offset, %ld, %ld, %ld\n",
60349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow               tmp_offset[0], tmp_offset[1], tmp_offset[2]);
60449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            inv_set_accel_bias(accel_offset, mAccelAccuracy);
60549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            inv_get_accel_bias(tmp_offset, NULL);
60649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            LOGV_IF(PROCESS_VERBOSE, "HAL:Set accel offset, %ld, %ld, %ld\n",
60749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow               tmp_offset[0], tmp_offset[1], tmp_offset[2]);
60849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        }
60949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    }
6104a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    /* end of external accel calibration load workflow */
61149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
61249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    /* disable driver master enable the first sensor goes on */
61349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    masterEnable(0);
61449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    enableGyro(0);
61549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    enableAccel(0);
61649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    enableCompass(0,0);
61749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    enablePressure(0);
6184a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    enableBatch(0);
61949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
62049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    if (isLowPowerQuatEnabled()) {
62149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        enableLPQuaternion(0);
62249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    }
62349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
62449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    if (isDmpDisplayOrientationOn()) {
62549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        // open DMP Orient Fd
62649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        openDmpOrientFd();
62749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        enableDmpOrientation(!isDmpScreenAutoRotationEnabled());
62849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    }
62949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow}
63049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
63149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chowvoid MPLSensor::enable_iio_sysfs(void)
63249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow{
63349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    VFUNC_LOG;
63449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
6354a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    char iio_device_node[MAX_CHIP_ID_LEN];
63649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    FILE *tempFp = NULL;
63749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
63849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo 1 > %s (%lld)",
63949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            mpu.in_timestamp_en, getTimestamp());
64049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    // Either fopen()/open() are okay for sysfs access
64149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    // developers could choose what they want
64249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    // with fopen(), the benefit is that fprintf()/fscanf() are available
64349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    tempFp = fopen(mpu.in_timestamp_en, "w");
64449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    if (tempFp == NULL) {
64549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        LOGE("HAL:could not open timestamp enable");
64649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    } else {
64749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        if(fprintf(tempFp, "%d", 1) < 0 || fclose(tempFp) < 0) {
64849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            LOGE("HAL:could not enable timestamp");
64949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        }
65049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    }
65149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
65249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)",
65349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            IIO_BUFFER_LENGTH, mpu.buffer_length, getTimestamp());
65449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    tempFp = fopen(mpu.buffer_length, "w");
65549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    if (tempFp == NULL) {
65649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        LOGE("HAL:could not open buffer length");
65749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    } else {
65849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        if (fprintf(tempFp, "%d", IIO_BUFFER_LENGTH) < 0 || fclose(tempFp) < 0) {
65949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            LOGE("HAL:could not write buffer length");
66049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        }
66149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    }
66249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
66349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    inv_get_iio_device_node(iio_device_node);
66449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    iio_fd = open(iio_device_node, O_RDONLY);
66549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    if (iio_fd < 0) {
66649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        LOGE("HAL:could not open iio device node");
66749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    } else {
66849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        LOGV_IF(PROCESS_VERBOSE, "HAL:iio iio_fd opened : %d", iio_fd);
66949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    }
67049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow}
67149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
67249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chowint MPLSensor::inv_constructor_init(void)
67349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow{
67449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    VFUNC_LOG;
67549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
67649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    inv_error_t result = inv_init_mpl();
67749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    if (result) {
67849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        LOGE("HAL:inv_init_mpl() failed");
67949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        return result;
68049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    }
68149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    result = inv_constructor_default_enable();
68249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    result = inv_start_mpl();
68349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    if (result) {
68449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        LOGE("HAL:inv_start_mpl() failed");
68549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        LOG_RESULT_LOCATION(result);
68649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        return result;
68749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    }
68849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
68949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    return result;
69049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow}
69149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
69249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chowint MPLSensor::inv_constructor_default_enable(void)
69349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow{
69449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    VFUNC_LOG;
69549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
69649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    inv_error_t result;
69749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
69849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow/*******************************************************************************
69949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
70049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow********************************************************************************
70149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
70249ea3e26ca3c6a779e527a0322e49a663333350aRosa ChowThe InvenSense binary file (libmplmpu.so) is subject to Google's standard terms
70349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chowand conditions as accepted in the click-through agreement required to download
70449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chowthis library.
70549ea3e26ca3c6a779e527a0322e49a663333350aRosa ChowThe library includes, but is not limited to the following function calls:
70649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chowinv_enable_quaternion().
70749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
70849ea3e26ca3c6a779e527a0322e49a663333350aRosa ChowANY VIOLATION OF SUCH TERMS AND CONDITIONS WILL BE STRICTLY ENFORCED.
70949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
71049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow********************************************************************************
71149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
71249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow*******************************************************************************/
71349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
71449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    result = inv_enable_quaternion();
71549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    if (result) {
71649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        LOGE("HAL:Cannot enable quaternion\n");
71749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        return result;
71849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    }
71949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
72049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    result = inv_enable_in_use_auto_calibration();
72149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    if (result) {
72249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        return result;
72349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    }
72449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
72549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    result = inv_enable_fast_nomot();
72649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    if (result) {
72749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        return result;
72849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    }
72949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
73049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    result = inv_enable_gyro_tc();
73149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    if (result) {
73249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        return result;
73349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    }
73449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
73549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    result = inv_enable_hal_outputs();
73649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    if (result) {
73749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        return result;
73849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    }
73949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
74049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    if (!mCompassSensor->providesCalibration()) {
74149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        /* Invensense compass calibration */
74249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        LOGV_IF(PROCESS_VERBOSE, "HAL:Invensense vector compass cal enabled");
74349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        result = inv_enable_vector_compass_cal();
74449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        if (result) {
74549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            LOG_RESULT_LOCATION(result);
74649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            return result;
74749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        } else {
74849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            mMplFeatureActiveMask |= INV_COMPASS_CAL;
74949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        }
75049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        // specify MPL's trust weight, used by compass algorithms
75149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        inv_vector_compass_cal_sensitivity(3);
75249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
75349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        /* disabled by default
75449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        result = inv_enable_compass_bias_w_gyro();
75549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        if (result) {
75649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            LOG_RESULT_LOCATION(result);
75749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            return result;
75849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        }
75949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        */
76049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
76149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        result = inv_enable_heading_from_gyro();
76249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        if (result) {
76349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            LOG_RESULT_LOCATION(result);
76449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            return result;
76549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        }
76649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
76749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        result = inv_enable_magnetic_disturbance();
76849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        if (result) {
76949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            LOG_RESULT_LOCATION(result);
77049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            return result;
77149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        }
77249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        //inv_enable_magnetic_disturbance_logging();
77349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    }
77449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
77549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    result = inv_enable_9x_sensor_fusion();
77649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    if (result) {
77749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        LOG_RESULT_LOCATION(result);
77849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        return result;
77949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    } else {
78049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        // 9x sensor fusion enables Compass fit
78149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        mMplFeatureActiveMask |= INV_COMPASS_FIT;
78249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    }
78349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
78449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    result = inv_enable_no_gyro_fusion();
78549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    if (result) {
78649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        LOG_RESULT_LOCATION(result);
78749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        return result;
78849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    }
78949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
79049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    return result;
79149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow}
79249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
79349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow/* TODO: create function pointers to calculate scale */
79449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chowvoid MPLSensor::inv_set_device_properties(void)
79549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow{
79649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    VFUNC_LOG;
79749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
79849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    unsigned short orient;
79949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
80049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    inv_get_sensors_orientation();
80149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
80249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    inv_set_gyro_sample_rate(DEFAULT_MPL_GYRO_RATE);
80349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    inv_set_compass_sample_rate(DEFAULT_MPL_COMPASS_RATE);
80449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
80549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    /* gyro setup */
80649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    orient = inv_orientation_matrix_to_scalar(mGyroOrientation);
80749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    inv_set_gyro_orientation_and_scale(orient, mGyroScale << 15);
80849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    LOGI_IF(EXTRA_VERBOSE, "HAL: Set MPL Gyro Scale %ld", mGyroScale << 15);
80949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
81049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    /* accel setup */
81149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    orient = inv_orientation_matrix_to_scalar(mAccelOrientation);
81249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    /* use for third party accel input subsystem driver
81349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    inv_set_accel_orientation_and_scale(orient, 1LL << 22);
81449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    */
81549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    inv_set_accel_orientation_and_scale(orient, (long)mAccelScale << 15);
81649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    LOGI_IF(EXTRA_VERBOSE,
81749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            "HAL: Set MPL Accel Scale %ld", (long)mAccelScale << 15);
81849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
81949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    /* compass setup */
82049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    signed char orientMtx[9];
82149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    mCompassSensor->getOrientationMatrix(orientMtx);
82249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    orient =
82349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        inv_orientation_matrix_to_scalar(orientMtx);
82449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    long sensitivity;
82549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    sensitivity = mCompassSensor->getSensitivity();
82649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    inv_set_compass_orientation_and_scale(orient, sensitivity);
82749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    mCompassScale = sensitivity;
82849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    LOGI_IF(EXTRA_VERBOSE,
82949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            "HAL: Set MPL Compass Scale %ld", mCompassScale);
83049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow}
83149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
83249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chowvoid MPLSensor::loadDMP(void)
83349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow{
83449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    int res, fd;
83549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    FILE *fptr;
83649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
83749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    if (isMpuNonDmp()) {
83849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        //DMP support only for MPU6xxx/9xxx currently
83949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        return;
84049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    }
84149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
84249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    /* load DMP firmware */
84349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    LOGV_IF(SYSFS_VERBOSE,
84449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            "HAL:sysfs:cat %s (%lld)", mpu.firmware_loaded, getTimestamp());
84549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    fd = open(mpu.firmware_loaded, O_RDONLY);
84649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    if(fd < 0) {
84749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        LOGE("HAL:could not open dmp state");
84849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    } else {
84949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        if(inv_read_dmp_state(fd) == 0) {
85049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            LOGV_IF(EXTRA_VERBOSE, "HAL:load dmp: %s", mpu.dmp_firmware);
85149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            fptr = fopen(mpu.dmp_firmware, "w");
8524a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            if(fptr == NULL) {
85349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                LOGE("HAL:could not write to dmp");
85449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            } else {
8554a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                if (inv_load_dmp(fptr) < 0 || fclose(fptr) < 0) {
85649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                    LOGE("HAL:load DMP failed");
85749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                } else {
8584a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                    fclose(fptr);
85949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                    LOGV_IF(PROCESS_VERBOSE, "HAL:DMP loaded");
8604a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                };
86149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            }
86249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        } else {
86349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            LOGV_IF(PROCESS_VERBOSE, "HAL:DMP is already loaded");
86449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        }
86549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    }
86649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
8674a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    // onDmp(1);    //Can't enable here. See note onDmp()
86849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow}
86949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
87049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chowvoid MPLSensor::inv_get_sensors_orientation(void)
87149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow{
87249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    FILE *fptr;
87349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
87449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    // get gyro orientation
87549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    LOGV_IF(SYSFS_VERBOSE,
87649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            "HAL:sysfs:cat %s (%lld)", mpu.gyro_orient, getTimestamp());
87749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    fptr = fopen(mpu.gyro_orient, "r");
87849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    if (fptr != NULL) {
87949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        int om[9];
88049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        fscanf(fptr, "%d,%d,%d,%d,%d,%d,%d,%d,%d",
88149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow               &om[0], &om[1], &om[2], &om[3], &om[4], &om[5],
88249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow               &om[6], &om[7], &om[8]);
88349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        fclose(fptr);
88449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
88549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        LOGV_IF(EXTRA_VERBOSE,
88649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                "HAL:gyro mounting matrix: "
88749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                "%+d %+d %+d %+d %+d %+d %+d %+d %+d",
88849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                om[0], om[1], om[2], om[3], om[4], om[5], om[6], om[7], om[8]);
88949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
89049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        mGyroOrientation[0] = om[0];
89149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        mGyroOrientation[1] = om[1];
89249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        mGyroOrientation[2] = om[2];
89349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        mGyroOrientation[3] = om[3];
89449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        mGyroOrientation[4] = om[4];
89549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        mGyroOrientation[5] = om[5];
89649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        mGyroOrientation[6] = om[6];
89749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        mGyroOrientation[7] = om[7];
89849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        mGyroOrientation[8] = om[8];
89949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    } else {
90049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        LOGE("HAL:Couldn't read gyro mounting matrix");
90149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    }
90249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
90349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    // get accel orientation
90449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    LOGV_IF(SYSFS_VERBOSE,
90549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            "HAL:sysfs:cat %s (%lld)", mpu.accel_orient, getTimestamp());
90649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    fptr = fopen(mpu.accel_orient, "r");
90749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    if (fptr != NULL) {
90849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        int om[9];
90949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        fscanf(fptr, "%d,%d,%d,%d,%d,%d,%d,%d,%d",
91049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow               &om[0], &om[1], &om[2], &om[3], &om[4], &om[5],
91149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow               &om[6], &om[7], &om[8]);
91249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        fclose(fptr);
91349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
91449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        LOGV_IF(EXTRA_VERBOSE,
91549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                "HAL:accel mounting matrix: "
91649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                "%+d %+d %+d %+d %+d %+d %+d %+d %+d",
91749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                om[0], om[1], om[2], om[3], om[4], om[5], om[6], om[7], om[8]);
91849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
91949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        mAccelOrientation[0] = om[0];
92049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        mAccelOrientation[1] = om[1];
92149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        mAccelOrientation[2] = om[2];
92249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        mAccelOrientation[3] = om[3];
92349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        mAccelOrientation[4] = om[4];
92449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        mAccelOrientation[5] = om[5];
92549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        mAccelOrientation[6] = om[6];
92649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        mAccelOrientation[7] = om[7];
92749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        mAccelOrientation[8] = om[8];
92849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    } else {
92949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        LOGE("HAL:Couldn't read accel mounting matrix");
93049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    }
93149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow}
93249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
93349ea3e26ca3c6a779e527a0322e49a663333350aRosa ChowMPLSensor::~MPLSensor()
93449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow{
93549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    VFUNC_LOG;
93649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
93749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    /* Close open fds */
93849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    if (iio_fd > 0)
93949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        close(iio_fd);
94049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    if( accel_fd > 0 )
94149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        close(accel_fd );
94249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    if (gyro_temperature_fd > 0)
94349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        close(gyro_temperature_fd);
94449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    if (sysfs_names_ptr)
94549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        free(sysfs_names_ptr);
94649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
94749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    closeDmpOrientFd();
94849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
94949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    if (accel_x_dmp_bias_fd > 0) {
95049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        close(accel_x_dmp_bias_fd);
95149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    }
95249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    if (accel_y_dmp_bias_fd > 0) {
95349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        close(accel_y_dmp_bias_fd);
95449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    }
95549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    if (accel_z_dmp_bias_fd > 0) {
95649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        close(accel_z_dmp_bias_fd);
95749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    }
95849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
95949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    if (gyro_x_dmp_bias_fd > 0) {
96049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        close(gyro_x_dmp_bias_fd);
96149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    }
96249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    if (gyro_y_dmp_bias_fd > 0) {
96349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        close(gyro_y_dmp_bias_fd);
96449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    }
96549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    if (gyro_z_dmp_bias_fd > 0) {
96649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        close(gyro_z_dmp_bias_fd);
96749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    }
96849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
96949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    if (gyro_x_offset_fd > 0) {
97049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        close(gyro_x_dmp_bias_fd);
97149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    }
97249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    if (gyro_y_offset_fd > 0) {
97349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        close(gyro_y_offset_fd);
97449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    }
97549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    if (gyro_z_offset_fd > 0) {
97649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        close(accel_z_offset_fd);
97749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    }
97849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
97949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    /* Turn off Gyro master enable          */
98049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    /* A workaround until driver handles it */
98149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    /* TODO: Turn off and close all sensors */
9824a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)",
9834a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            0, mpu.chip_enable, getTimestamp());
98449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    write_sysfs_int(mpu.chip_enable, 0);
98549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
98649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow#ifdef INV_PLAYBACK_DBG
98749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    inv_turn_off_data_logging();
98849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    fclose(logfile);
98949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow#endif
99049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow}
99149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
99249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow#define GY_ENABLED  ((1 << ID_GY) & enabled_sensors)
99349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow#define RGY_ENABLED ((1 << ID_RG) & enabled_sensors)
99449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow#define A_ENABLED   ((1 << ID_A)  & enabled_sensors)
99549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow#define M_ENABLED   ((1 << ID_M) & enabled_sensors)
99649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow#define RM_ENABLED  ((1 << ID_RM) & enabled_sensors)
99749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow#define PS_ENABLED  ((1 << ID_PS) & enabled_sensors)
99849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow#define O_ENABLED   ((1 << ID_O)  & enabled_sensors)
99949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow#define LA_ENABLED  ((1 << ID_LA) & enabled_sensors)
100049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow#define GR_ENABLED  ((1 << ID_GR) & enabled_sensors)
100149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow#define RV_ENABLED  ((1 << ID_RV) & enabled_sensors)
100249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow#define GRV_ENABLED ((1 << ID_GRV) & enabled_sensors)
100349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow#define GMRV_ENABLED ((1 << ID_GMRV) & enabled_sensors)
100449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
100549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow/* TODO: this step is optional, remove?  */
100649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chowint MPLSensor::setGyroInitialState(void)
100749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow{
100849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    VFUNC_LOG;
100949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
101049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    int res = 0;
101149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
101249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)",
10134a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            HW_GYRO_RATE_HZ, mpu.gyro_rate, getTimestamp());
10144a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    int fd = open(mpu.gyro_rate, O_RDWR);
101549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    res = errno;
101649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    if(fd < 0) {
101749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        LOGE("HAL:open of %s failed with '%s' (%d)",
10184a28f9c897c46c42a255823f7e307169a828a025Rosa Chow             mpu.gyro_rate, strerror(res), res);
101949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        return res;
102049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    }
102149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    res = write_attribute_sensor(fd, HW_GYRO_RATE_HZ);
102249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    if(res < 0) {
102349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        LOGE("HAL:write_attribute_sensor : error writing %s with %d",
10244a28f9c897c46c42a255823f7e307169a828a025Rosa Chow             mpu.gyro_rate, HW_GYRO_RATE_HZ);
102549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        return res;
102649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    }
102749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
102849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    // Setting LPF is deprecated
102949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
103049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    return 0;
103149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow}
103249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
103349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow/* this applies to BMA250 Input Subsystem Driver only */
103449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chowint MPLSensor::setAccelInitialState()
103549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow{
103649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    VFUNC_LOG;
103749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
103849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    struct input_absinfo absinfo_x;
103949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    struct input_absinfo absinfo_y;
104049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    struct input_absinfo absinfo_z;
104149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    float value;
104249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    if (!ioctl(accel_fd, EVIOCGABS(EVENT_TYPE_ACCEL_X), &absinfo_x) &&
104349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        !ioctl(accel_fd, EVIOCGABS(EVENT_TYPE_ACCEL_Y), &absinfo_y) &&
104449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        !ioctl(accel_fd, EVIOCGABS(EVENT_TYPE_ACCEL_Z), &absinfo_z)) {
104549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        value = absinfo_x.value;
104649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        mPendingEvents[Accelerometer].data[0] = value * CONVERT_A_X;
104749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        value = absinfo_y.value;
104849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        mPendingEvents[Accelerometer].data[1] = value * CONVERT_A_Y;
104949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        value = absinfo_z.value;
105049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        mPendingEvents[Accelerometer].data[2] = value * CONVERT_A_Z;
105149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        //mHasPendingEvent = true;
105249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    }
105349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    return 0;
105449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow}
105549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
105649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chowint MPLSensor::onDmp(int en)
105749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow{
105849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    VFUNC_LOG;
105949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
106049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    int res = -1;
106149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    int status;
106249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    mDmpOn = en;
106349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
106449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    //Sequence to enable DMP
106549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    //1. Load DMP image if not already loaded
106649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    //2. Either Gyro or Accel must be enabled/configured before next step
106749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    //3. Enable DMP
106849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
106949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:cat %s (%lld)",
107049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            mpu.firmware_loaded, getTimestamp());
107149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    if(read_sysfs_int(mpu.firmware_loaded, &status) < 0){
107249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        LOGE("HAL:ERR can't get firmware_loaded status");
107349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    } else if (status == 1) {
107449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        //Write only if curr DMP state <> request
107549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:cat %s (%lld)",
107649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                mpu.dmp_on, getTimestamp());
107749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        if (read_sysfs_int(mpu.dmp_on, &status) < 0) {
107849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            LOGE("HAL:ERR can't read DMP state");
107949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        } else if (status != en) {
108049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)",
108149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                    en, mpu.dmp_on, getTimestamp());
108249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            if (write_sysfs_int(mpu.dmp_on, en) < 0) {
108349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                LOGE("HAL:ERR can't write dmp_on");
108449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            } else {
108549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                mDmpOn = en;
108649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                res = 0;	//Indicate write successful
108749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                if(!en) {
108849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                    setAccelBias();
108949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                }
109049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            }
109149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            //Enable DMP interrupt
109249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)",
109349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                    en, mpu.dmp_int_on, getTimestamp());
109449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            if (write_sysfs_int(mpu.dmp_int_on, en) < 0) {
109549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                LOGE("HAL:ERR can't en/dis DMP interrupt");
109649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            }
109749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
109849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            // disable DMP event interrupt if needed
109949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            if (!en) {
110049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)",
110149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                        en, mpu.dmp_event_int_on, getTimestamp());
110249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                if (write_sysfs_int(mpu.dmp_event_int_on, en) < 0) {
110349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                    res = -1;
110449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                    LOGE("HAL:ERR can't enable DMP event interrupt");
110549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                }
110649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            }
110749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        } else {
110849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            mDmpOn = en;
110949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            res = 0;  	//DMP already set as requested
111049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            if(!en) {
111149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                setAccelBias();
111249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            }
111349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        }
111449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    } else {
111549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        LOGE("HAL:ERR No DMP image");
111649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    }
111749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    return res;
111849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow}
111949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
11204a28f9c897c46c42a255823f7e307169a828a025Rosa Chow/* called when batch and hw sensor enabled*/
11214a28f9c897c46c42a255823f7e307169a828a025Rosa Chowint MPLSensor::enablePedIndicator(int en)
11224a28f9c897c46c42a255823f7e307169a828a025Rosa Chow{
11234a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    VFUNC_LOG;
11244a28f9c897c46c42a255823f7e307169a828a025Rosa Chow
11254a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    int res = 0;
11264a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    if (en) {
11274a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        if (!(mFeatureActiveMask & INV_DMP_PED_QUATERNION)) {
11284a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            //Disable DMP Pedometer Interrupt
11294a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)",
11304a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                        0, mpu.pedometer_int_on, getTimestamp());
11314a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            if (write_sysfs_int(mpu.pedometer_int_on, 0) < 0) {
11324a28f9c897c46c42a255823f7e307169a828a025Rosa Chow               LOGE("HAL:ERR can't enable Android Pedometer Interrupt");
11334a28f9c897c46c42a255823f7e307169a828a025Rosa Chow               res = -1;   // indicate an err
11344a28f9c897c46c42a255823f7e307169a828a025Rosa Chow               return res;
11354a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            }
11364a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        }
11374a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    }
11384a28f9c897c46c42a255823f7e307169a828a025Rosa Chow
11394a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    LOGV_IF(PROCESS_VERBOSE, "HAL:Toggling step indicator to %d", en);
11404a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)",
11414a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                en, mpu.step_indicator_on, getTimestamp());
11424a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    if (write_sysfs_int(mpu.step_indicator_on, en) < 0) {
11434a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        res = -1;
11444a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        LOGE("HAL:ERR can't write to DMP step_indicator_on");
11454a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    }
11464a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    return res;
11474a28f9c897c46c42a255823f7e307169a828a025Rosa Chow}
11484a28f9c897c46c42a255823f7e307169a828a025Rosa Chow
11494a28f9c897c46c42a255823f7e307169a828a025Rosa Chowint MPLSensor::checkPedStandaloneEnabled(void)
11504a28f9c897c46c42a255823f7e307169a828a025Rosa Chow{
11514a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    return ((mFeatureActiveMask & INV_DMP_PED_STANDALONE)? 1:0);
11524a28f9c897c46c42a255823f7e307169a828a025Rosa Chow
11534a28f9c897c46c42a255823f7e307169a828a025Rosa Chow}
11544a28f9c897c46c42a255823f7e307169a828a025Rosa Chow
11554a28f9c897c46c42a255823f7e307169a828a025Rosa Chow/* This feature is only used in batch mode */
11564a28f9c897c46c42a255823f7e307169a828a025Rosa Chow/* Stand-alone Step Detector */
11574a28f9c897c46c42a255823f7e307169a828a025Rosa Chowint MPLSensor::enablePedStandalone(int en)
11584a28f9c897c46c42a255823f7e307169a828a025Rosa Chow{
11594a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    VFUNC_LOG;
11604a28f9c897c46c42a255823f7e307169a828a025Rosa Chow
11614a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    if (!en) {
11624a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        enablePedStandaloneData(0);
11634a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        mFeatureActiveMask &= ~INV_DMP_PED_STANDALONE;
11644a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        if (mFeatureActiveMask == 0) {
11654a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            onDmp(0);
11664a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        } else if(mFeatureActiveMask & INV_DMP_PEDOMETER) {
11674a28f9c897c46c42a255823f7e307169a828a025Rosa Chow             //Re-enable DMP Pedometer Interrupt
11684a28f9c897c46c42a255823f7e307169a828a025Rosa Chow             LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)",
11694a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                     1, mpu.pedometer_int_on, getTimestamp());
11704a28f9c897c46c42a255823f7e307169a828a025Rosa Chow             if (write_sysfs_int(mpu.pedometer_int_on, 1) < 0) {
11714a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                 LOGE("HAL:ERR can't enable Android Pedometer Interrupt");
11724a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                 return (-1);
11734a28f9c897c46c42a255823f7e307169a828a025Rosa Chow             }
11744a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            //Disable data interrupt if no continuous data
11754a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            if (mEnabled == 0) {
11764a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)",
11774a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                       1, mpu.dmp_event_int_on, getTimestamp());
11784a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                if (write_sysfs_int(mpu.dmp_event_int_on, 1) < 0) {
11794a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                    LOGE("HAL:ERR can't enable DMP event interrupt");
11804a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                    return (-1);
11814a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                }
11824a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            }
11834a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        }
11844a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        LOGV_IF(PROCESS_VERBOSE, "HAL:Ped Standalone disabled");
11854a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    } else {
11864a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        if (enablePedStandaloneData(1) < 0 || onDmp(1) < 0) {
11874a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            LOGE("HAL:ERR can't enable Ped Standalone");
11884a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        } else {
11894a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            mFeatureActiveMask |= INV_DMP_PED_STANDALONE;
11904a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            //Disable DMP Pedometer Interrupt
11914a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)",
11924a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                    0, mpu.pedometer_int_on, getTimestamp());
11934a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            if (write_sysfs_int(mpu.pedometer_int_on, 0) < 0) {
11944a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                LOGE("HAL:ERR can't disable Android Pedometer Interrupt");
11954a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                return (-1);
11964a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            }
11974a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            //Enable Data Interrupt
11984a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)",
11994a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                       0, mpu.dmp_event_int_on, getTimestamp());
12004a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            if (write_sysfs_int(mpu.dmp_event_int_on, 0) < 0) {
12014a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                LOGE("HAL:ERR can't enable DMP event interrupt");
12024a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                return (-1);
12034a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            }
12044a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            LOGV_IF(PROCESS_VERBOSE, "HAL:Ped Standalone enabled");
12054a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        }
12064a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    }
12074a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    return 0;
12084a28f9c897c46c42a255823f7e307169a828a025Rosa Chow}
12094a28f9c897c46c42a255823f7e307169a828a025Rosa Chow
12104a28f9c897c46c42a255823f7e307169a828a025Rosa Chowint MPLSensor:: enablePedStandaloneData(int en)
12114a28f9c897c46c42a255823f7e307169a828a025Rosa Chow{
12124a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    VFUNC_LOG;
12134a28f9c897c46c42a255823f7e307169a828a025Rosa Chow
12144a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    int res = 0;
12154a28f9c897c46c42a255823f7e307169a828a025Rosa Chow
12164a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    // Enable DMP Ped standalone
12174a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)",
12184a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            en, mpu.step_detector_on, getTimestamp());
12194a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    if (write_sysfs_int(mpu.step_detector_on, en) < 0) {
12204a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        LOGE("HAL:ERR can't write DMP step_detector_on");
12214a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        res = -1;   //Indicate an err
12224a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    }
12234a28f9c897c46c42a255823f7e307169a828a025Rosa Chow
12244a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    // Disable DMP Step indicator
12254a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)",
12264a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            en, mpu.step_indicator_on, getTimestamp());
12274a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    if (write_sysfs_int(mpu.step_indicator_on, en) < 0) {
12284a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        LOGE("HAL:ERR can't write DMP step_indicator_on");
12294a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        res = -1;   //Indicate an err
12304a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    }
12314a28f9c897c46c42a255823f7e307169a828a025Rosa Chow
12324a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    if (!en) {
12334a28f9c897c46c42a255823f7e307169a828a025Rosa Chow      LOGV_IF(PROCESS_VERBOSE, "HAL:Disabling ped standalone");
12344a28f9c897c46c42a255823f7e307169a828a025Rosa Chow      //Disable Accel if no sensor needs it
12354a28f9c897c46c42a255823f7e307169a828a025Rosa Chow      if (!(mFeatureActiveMask & DMP_FEATURE_MASK)
12364a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                               && (!(mLocalSensorMask & mMasterSensorMask
12374a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                                                   & INV_THREE_AXIS_ACCEL))) {
12384a28f9c897c46c42a255823f7e307169a828a025Rosa Chow          res = enableAccel(0);
12394a28f9c897c46c42a255823f7e307169a828a025Rosa Chow          if (res < 0)
12404a28f9c897c46c42a255823f7e307169a828a025Rosa Chow              return res;
12414a28f9c897c46c42a255823f7e307169a828a025Rosa Chow      }
12424a28f9c897c46c42a255823f7e307169a828a025Rosa Chow      if (!(mFeatureActiveMask & DMP_FEATURE_MASK)
12434a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                               && (!(mLocalSensorMask & mMasterSensorMask
12444a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                                                   & INV_THREE_AXIS_GYRO))) {
12454a28f9c897c46c42a255823f7e307169a828a025Rosa Chow          res = enableGyro(0);
12464a28f9c897c46c42a255823f7e307169a828a025Rosa Chow          if (res < 0)
12474a28f9c897c46c42a255823f7e307169a828a025Rosa Chow              return res;
12484a28f9c897c46c42a255823f7e307169a828a025Rosa Chow      }
12494a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    } else {
12504a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        LOGV_IF(PROCESS_VERBOSE, "HAL:Enabling ped standalone");
12514a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        // enable accel engine
12524a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        res = enableAccel(1);
12534a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        if (res < 0)
12544a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            return res;
12554a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        LOGV_IF(EXTRA_VERBOSE, "mLocalSensorMask=0x%lx", mLocalSensorMask);
12564a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        // disable accel FIFO
12574a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        if (!((mLocalSensorMask & mMasterSensorMask) & INV_THREE_AXIS_ACCEL)) {
12584a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            res = turnOffAccelFifo();
12594a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            if (res < 0)
12604a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                return res;
12614a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        }
12624a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    }
12634a28f9c897c46c42a255823f7e307169a828a025Rosa Chow
12644a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    return res;
12654a28f9c897c46c42a255823f7e307169a828a025Rosa Chow}
12664a28f9c897c46c42a255823f7e307169a828a025Rosa Chow
126749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chowint MPLSensor::checkPedQuatEnabled(void)
126849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow{
126949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    return ((mFeatureActiveMask & INV_DMP_PED_QUATERNION)? 1:0);
127049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow}
127149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
127249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow/* This feature is only used in batch mode */
127349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow/* Step Detector && Game Rotation Vector */
127449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chowint MPLSensor::enablePedQuaternion(int en)
127549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow{
127649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    VFUNC_LOG;
127749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
127849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    if (!en) {
127949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        enablePedQuaternionData(0);
128049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        mFeatureActiveMask &= ~INV_DMP_PED_QUATERNION;
128149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        if (mFeatureActiveMask == 0) {
128249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            onDmp(0);
128349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        } else if(mFeatureActiveMask & INV_DMP_PEDOMETER) {
128449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow             //Re-enable DMP Pedometer Interrupt
128549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow             LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)",
128649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                     1, mpu.pedometer_int_on, getTimestamp());
128749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow             if (write_sysfs_int(mpu.pedometer_int_on, 1) < 0) {
128849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                 LOGE("HAL:ERR can't enable Android Pedometer Interrupt");
128949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                 return (-1);
129049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow             }
129149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            //Disable data interrupt if no continuous data
129249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            if (mEnabled == 0) {
129349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)",
129449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                       1, mpu.dmp_event_int_on, getTimestamp());
129549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                if (write_sysfs_int(mpu.dmp_event_int_on, en) < 0) {
129649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                    LOGE("HAL:ERR can't enable DMP event interrupt");
129749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                    return (-1);
129849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                }
129949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            }
130049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        }
130149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        LOGV_IF(PROCESS_VERBOSE, "HAL:Ped Quat disabled");
130249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    } else {
130349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        if (enablePedQuaternionData(1) < 0 || onDmp(1) < 0) {
130449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            LOGE("HAL:ERR can't enable Ped Quaternion");
130549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        } else {
130649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            mFeatureActiveMask |= INV_DMP_PED_QUATERNION;
130749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            //Disable DMP Pedometer Interrupt
130849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)",
130949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                    0, mpu.pedometer_int_on, getTimestamp());
131049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            if (write_sysfs_int(mpu.pedometer_int_on, 0) < 0) {
131149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                LOGE("HAL:ERR can't disable Android Pedometer Interrupt");
131249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                return (-1);
131349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            }
131449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            //Enable Data Interrupt
131549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)",
131649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                       0, mpu.dmp_event_int_on, getTimestamp());
131749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            if (write_sysfs_int(mpu.dmp_event_int_on, 0) < 0) {
131849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                LOGE("HAL:ERR can't enable DMP event interrupt");
131949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                return (-1);
132049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            }
132149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            LOGV_IF(PROCESS_VERBOSE, "HAL:Ped Quat enabled");
132249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        }
132349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    }
132449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    return 0;
132549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow}
132649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
132749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chowint MPLSensor::enablePedQuaternionData(int en)
132849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow{
132949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    VFUNC_LOG;
133049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
133149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    int res = 0;
133249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
133349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    // Enable DMP quaternion
133449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)",
133549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            en, mpu.ped_q_on, getTimestamp());
133649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    if (write_sysfs_int(mpu.ped_q_on, en) < 0) {
133749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        LOGE("HAL:ERR can't write DMP ped_q_on");
133849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        res = -1;   //Indicate an err
133949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    }
134049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
13414a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    // toggle DMP step indicator
13424a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    /*LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)",
13434a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            en, mpu.step_indicator_on, getTimestamp());
13444a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    if (write_sysfs_int(mpu.step_indicator_on, en) < 0) {
13454a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        LOGE("HAL:ERR can't write DMP step_indicator_on");
13464a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        res = -1;   //Indicate an err
13474a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    }*/
13484a28f9c897c46c42a255823f7e307169a828a025Rosa Chow
134949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    if (!en) {
13504a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        LOGV_IF(PROCESS_VERBOSE, "HAL:Disabling ped quat");
13514a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        //Disable Accel if no sensor needs it
13524a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        if (!(mFeatureActiveMask & DMP_FEATURE_MASK)
135349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                               && (!(mLocalSensorMask & mMasterSensorMask
135449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                                                   & INV_THREE_AXIS_ACCEL))) {
135549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow          res = enableAccel(0);
135649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow          if (res < 0)
135749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow              return res;
13584a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        }
13594a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        if (!(mFeatureActiveMask & DMP_FEATURE_MASK)
136049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                               && (!(mLocalSensorMask & mMasterSensorMask
136149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                                                   & INV_THREE_AXIS_GYRO))) {
13624a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            res = enableGyro(0);
13634a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            if (res < 0)
13644a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                return res;
13654a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        }
13664a28f9c897c46c42a255823f7e307169a828a025Rosa Chow      if (mFeatureActiveMask & INV_DMP_QUATERNION) {
13674a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            res = write_sysfs_int(mpu.gyro_fifo_enable, 1);
13684a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            res += write_sysfs_int(mpu.accel_fifo_enable, 1);
13694a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            if (res < 0)
13704a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                return res;
137149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow      }
13724a28f9c897c46c42a255823f7e307169a828a025Rosa Chow//LOGV("before mLocalSensorMask=0x%lx", mLocalSensorMask);
13734a28f9c897c46c42a255823f7e307169a828a025Rosa Chow      // reset global mask for buildMpuEvent()
13744a28f9c897c46c42a255823f7e307169a828a025Rosa Chow      if (mEnabled & (1 << GameRotationVector)) {
13754a28f9c897c46c42a255823f7e307169a828a025Rosa Chow          mLocalSensorMask |= INV_THREE_AXIS_GYRO;
13764a28f9c897c46c42a255823f7e307169a828a025Rosa Chow          mLocalSensorMask |= INV_THREE_AXIS_ACCEL;
13774a28f9c897c46c42a255823f7e307169a828a025Rosa Chow      } else if (mEnabled & (1 << Accelerometer)) {
13784a28f9c897c46c42a255823f7e307169a828a025Rosa Chow          mLocalSensorMask |= INV_THREE_AXIS_ACCEL;
13794a28f9c897c46c42a255823f7e307169a828a025Rosa Chow      } else if ((mEnabled & ( 1 << Gyro)) ||
13804a28f9c897c46c42a255823f7e307169a828a025Rosa Chow          (mEnabled & (1 << RawGyro))) {
13814a28f9c897c46c42a255823f7e307169a828a025Rosa Chow          mLocalSensorMask |= INV_THREE_AXIS_GYRO;
13824a28f9c897c46c42a255823f7e307169a828a025Rosa Chow      }
13834a28f9c897c46c42a255823f7e307169a828a025Rosa Chow//LOGV("after mLocalSensorMask=0x%lx", mLocalSensorMask);
138449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    } else {
138549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        LOGV_IF(PROCESS_VERBOSE, "HAL:Enabling ped quat");
138649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        // enable accel engine
138749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        res = enableAccel(1);
138849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        if (res < 0)
138949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            return res;
139049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
139149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        // enable gyro engine
139249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        res = enableGyro(1);
139349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        if (res < 0)
139449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            return res;
13954a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        LOGV_IF(EXTRA_VERBOSE, "mLocalSensorMask=0x%lx", mLocalSensorMask);
139649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        // disable accel FIFO
13974a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        if ((!((mLocalSensorMask & mMasterSensorMask) & INV_THREE_AXIS_ACCEL)) ||
13984a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                !(mBatchEnabled & (1 << Accelerometer))) {
139949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            res = turnOffAccelFifo();
140049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            if (res < 0)
14014a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                return res;
14024a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            mLocalSensorMask &= ~INV_THREE_AXIS_ACCEL;
140349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        }
140449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
140549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        // disable gyro FIFO
14064a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        if ((!((mLocalSensorMask & mMasterSensorMask) & INV_THREE_AXIS_GYRO)) ||
14074a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                !((mBatchEnabled & (1 << Gyro)) || (mBatchEnabled & (1 << RawGyro)))) {
140849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            res = turnOffGyroFifo();
140949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            if (res < 0)
14104a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                return res;
14114a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            mLocalSensorMask &= ~INV_THREE_AXIS_GYRO;
141249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        }
141349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    }
141449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
141549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    return res;
141649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow}
141749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
141849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chowint MPLSensor::check6AxisQuatEnabled(void)
141949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow{
142049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    return ((mFeatureActiveMask & INV_DMP_6AXIS_QUATERNION)? 1:0);
142149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow}
142249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
14234a28f9c897c46c42a255823f7e307169a828a025Rosa Chow/* This is used for batch mode only */
14244a28f9c897c46c42a255823f7e307169a828a025Rosa Chow/* GRV is batched but not along with ped */
142549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chowint MPLSensor::enable6AxisQuaternion(int en)
142649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow{
142749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    VFUNC_LOG;
142849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
142949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    if (!en) {
143049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        enable6AxisQuaternionData(0);
143149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        mFeatureActiveMask &= ~INV_DMP_6AXIS_QUATERNION;
143249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        if (mFeatureActiveMask == 0) {
143349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            onDmp(0);
143449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        }
143549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        LOGV_IF(PROCESS_VERBOSE, "HAL:6 Axis Quat disabled");
143649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    } else {
143749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        if (enable6AxisQuaternionData(1) < 0 || onDmp(1) < 0) {
143849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            LOGE("HAL:ERR can't enable 6 Axis Quaternion");
143949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        } else {
144049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            mFeatureActiveMask |= INV_DMP_6AXIS_QUATERNION;
144149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            LOGV_IF(PROCESS_VERBOSE, "HAL:6 Axis Quat enabled");
144249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        }
144349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    }
144449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    return 0;
144549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow}
144649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
144749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chowint MPLSensor::enable6AxisQuaternionData(int en)
144849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow{
144949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    int res = 0;
145049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    VFUNC_LOG;
145149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
145249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    // Enable DMP quaternion
145349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)",
145449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            en, mpu.six_axis_q_on, getTimestamp());
145549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    if (write_sysfs_int(mpu.six_axis_q_on, en) < 0) {
14564a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        LOGE("HAL:ERR can't write DMP six_axis_q_on");
145749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        res = -1;   //Indicate an err
145849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    }
145949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
146049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    if (!en) {
146149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        LOGV_IF(EXTRA_VERBOSE, "HAL:DMP six axis quaternion data was turned off");
146249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        if (!(mFeatureActiveMask & DMP_FEATURE_MASK)
146349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                                 && (!(mLocalSensorMask & mMasterSensorMask
146449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                                                     & INV_THREE_AXIS_ACCEL))) {
146549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            res = enableAccel(0);
146649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            if (res < 0)
146749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                return res;
146849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        }
146949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        if (!(mFeatureActiveMask & DMP_FEATURE_MASK)
147049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                                 && (!(mLocalSensorMask & mMasterSensorMask
147149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                                                     & INV_THREE_AXIS_GYRO))) {
147249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            res = enableGyro(0);
147349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            if (res < 0)
147449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                return res;
147549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        }
147649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        if (mFeatureActiveMask & INV_DMP_QUATERNION) {
14774a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)",
14784a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                    1, mpu.gyro_fifo_enable, getTimestamp());
147949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            res = write_sysfs_int(mpu.gyro_fifo_enable, 1);
14804a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)",
14814a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                    1, mpu.accel_fifo_enable, getTimestamp());
148249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            res += write_sysfs_int(mpu.accel_fifo_enable, 1);
148349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            if (res < 0)
148449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                return res;
148549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        }
14864a28f9c897c46c42a255823f7e307169a828a025Rosa ChowLOGV("before mLocalSensorMask=0x%lx", mLocalSensorMask);
14874a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        // reset global mask for buildMpuEvent()
14884a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        if (mEnabled & (1 << GameRotationVector)) {
14894a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            if (!(mFeatureActiveMask & INV_DMP_PED_QUATERNION)) {
14904a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                mLocalSensorMask |= INV_THREE_AXIS_GYRO;
14914a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                mLocalSensorMask |= INV_THREE_AXIS_ACCEL;
14924a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            }
14934a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        } else if (mEnabled & (1 << Accelerometer)) {
14944a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            mLocalSensorMask |= INV_THREE_AXIS_ACCEL;
14954a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        } else if ((mEnabled & ( 1 << Gyro)) ||
14964a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                (mEnabled & (1 << RawGyro))) {
14974a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            mLocalSensorMask |= INV_THREE_AXIS_GYRO;
14984a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        }
14994a28f9c897c46c42a255823f7e307169a828a025Rosa ChowLOGV("after mLocalSensorMask=0x%lx", mLocalSensorMask);
150049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    } else {
150149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        LOGV_IF(PROCESS_VERBOSE, "HAL:Enabling six axis quat");
15024a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        if (mEnabled & ( 1 << GameRotationVector)) {
15034a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            // enable accel engine
15044a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            res = enableAccel(1);
150549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            if (res < 0)
150649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                return res;
15074a28f9c897c46c42a255823f7e307169a828a025Rosa Chow
15084a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            // enable gyro engine
15094a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            res = enableGyro(1);
151049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            if (res < 0)
151149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                return res;
15124a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            LOGV_IF(EXTRA_VERBOSE, "before: mLocalSensorMask=0x%lx", mLocalSensorMask);
15134a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            if ((!(mLocalSensorMask & mMasterSensorMask & INV_THREE_AXIS_ACCEL)) ||
15144a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                   (!(mBatchEnabled & (1 << Accelerometer)) ||
15154a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                       (!(mEnabled & (1 << Accelerometer))))) {
15164a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                res = turnOffAccelFifo();
15174a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                if (res < 0)
15184a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                    return res;
15194a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                mLocalSensorMask &= ~INV_THREE_AXIS_ACCEL;
152049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            }
15214a28f9c897c46c42a255823f7e307169a828a025Rosa Chow
15224a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            if ((!(mLocalSensorMask & mMasterSensorMask & INV_THREE_AXIS_GYRO)) ||
15234a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                    (!(mBatchEnabled & (1 << Gyro)) ||
15244a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                       (!(mEnabled & (1 << Gyro))))) {
15254a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                if (!(mBatchEnabled & (1 << RawGyro)) ||
15264a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                        (!(mEnabled & (1 << RawGyro)))) {
15274a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                    res = turnOffGyroFifo();
15284a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                    if (res < 0)
15294a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                        return res;
15304a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                     mLocalSensorMask &= ~INV_THREE_AXIS_GYRO;
15314a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                     }
153249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            }
15334a28f9c897c46c42a255823f7e307169a828a025Rosa ChowLOGV("after: mLocalSensorMask=0x%lx", mLocalSensorMask);
153449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        }
153549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    }
153649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
153749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    return res;
153849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow}
153949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
154049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chowint MPLSensor::checkLPQuaternion(void)
154149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow{
154249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    return ((mFeatureActiveMask & INV_DMP_QUATERNION)? 1:0);
154349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow}
154449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
154549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chowint MPLSensor::enableLPQuaternion(int en)
154649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow{
154749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    VFUNC_LOG;
154849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
154949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    if (!en) {
155049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        enableQuaternionData(0);
155149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        onDmp(0);
155249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        mFeatureActiveMask &= ~INV_DMP_QUATERNION;
155349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        LOGV_IF(PROCESS_VERBOSE, "HAL:LP Quat disabled");
155449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    } else {
155549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        if (enableQuaternionData(1) < 0 || onDmp(1) < 0) {
155649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            LOGE("HAL:ERR can't enable LP Quaternion");
155749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        } else {
155849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            mFeatureActiveMask |= INV_DMP_QUATERNION;
155949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            LOGV_IF(PROCESS_VERBOSE, "HAL:LP Quat enabled");
156049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        }
156149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    }
156249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    return 0;
156349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow}
156449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
156549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chowint MPLSensor::enableQuaternionData(int en)
156649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow{
156749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    int res = 0;
156849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    VFUNC_LOG;
156949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
157049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    // Enable DMP quaternion
157149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)",
157249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            en, mpu.three_axis_q_on, getTimestamp());
157349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    if (write_sysfs_int(mpu.three_axis_q_on, en) < 0) {
157449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        LOGE("HAL:ERR can't write DMP three_axis_q__on");
157549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        res = -1;	//Indicate an err
157649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    }
157749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
157849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    if (!en) {
157949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        LOGV_IF(EXTRA_VERBOSE, "HAL:DMP quaternion data was turned off");
158049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        inv_quaternion_sensor_was_turned_off();
158149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    } else {
158249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        LOGV_IF(PROCESS_VERBOSE, "HAL:Enabling three axis quat");
158349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    }
158449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
158549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    return res;
158649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow}
158749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
158849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chowint MPLSensor::enableDmpPedometer(int en, int interruptMode)
158949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow{
159049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    VFUNC_LOG;
159149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    int res = 0;
159249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    int enabled_sensors = mEnabled;
159349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
159449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    if (isMpuNonDmp())
159549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        return res;
159649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
159749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    // reset master enable
159849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    res = masterEnable(0);
159949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    if (res < 0) {
160049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        return res;
160149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    }
160249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
160349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    if (en == 1) {
160449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        //Enable DMP Pedometer Function
160549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)",
160649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                en, mpu.pedometer_on, getTimestamp());
160749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        if (write_sysfs_int(mpu.pedometer_on, en) < 0) {
160849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            LOGE("HAL:ERR can't enable Android Pedometer");
160949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            res = -1;   // indicate an err
161049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            return res;
161149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        }
161249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
16134a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        if (interruptMode || (mFeatureActiveMask & INV_DMP_PEDOMETER)) {
16144a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            //Enable DMP Pedometer Interrupt
16154a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)",
16164a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                    en, mpu.pedometer_int_on, getTimestamp());
16174a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            if (write_sysfs_int(mpu.pedometer_int_on, en) < 0) {
16184a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                LOGE("HAL:ERR can't enable Android Pedometer Interrupt");
16194a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                res = -1;   // indicate an err
16204a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                return res;
16214a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            }
162249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        }
162349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        // enable DMP
162449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        res = onDmp(1);
162549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        if (res < 0) {
162649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            return res;
16274a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        }
162849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
162949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        // set DMP rate to 200Hz
163049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)",
163149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                200, mpu.accel_fifo_rate, getTimestamp());
163249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        if (write_sysfs_int(mpu.accel_fifo_rate, 200) < 0) {
163349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            res = -1;
16344a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            LOGE("HAL:ERR can't set rate to 200Hz");
163549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            return res;
163649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        }
163749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
163849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        // enable accel engine
163949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        res = enableAccel(1);
164049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        if (res < 0) {
164149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            return res;
164249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        }
164349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
164449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        // disable accel FIFO
164549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        if (!(mLocalSensorMask & mMasterSensorMask & INV_THREE_AXIS_ACCEL)) {
164649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            res = turnOffAccelFifo();
164749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            if (res < 0)
164849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                return res;
164949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        }
165049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
165149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        // disable data interrupt
16524a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        //if (!batchPed && enabled_sensors == 0) {
165349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        if (enabled_sensors == 0) {
165449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)",
165549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                        en, mpu.dmp_event_int_on, getTimestamp());
165649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            if (write_sysfs_int(mpu.dmp_event_int_on, en) < 0) {
165749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                res = -1;
165849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                LOGE("HAL:ERR can't enable DMP event interrupt");
165949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            }
166049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        }
16614a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        if (interruptMode) {
166249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            mFeatureActiveMask |= INV_DMP_PEDOMETER;
16634a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            /*if (batchPed) {
16644a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)",
16654a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                    en, mpu.step_detector_on, getTimestamp());
16664a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                if (write_sysfs_int(mpu.step_detector_on, en) < 0) {
16674a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                    LOGE("HAL:ERR can't write DMP step_detector_on");
16684a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                    res = -1;   //Indicate an err
16694a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                }
16704a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                mFeatureActiveMask |= INV_DMP_PED_STANDALONE;
16714a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            }*/
16724a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        }
16734a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        else {
16744a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            mFeatureActiveMask |= INV_DMP_PEDOMETER_STEP;
16754a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        }
16764a28f9c897c46c42a255823f7e307169a828a025Rosa Chow
167749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        clock_gettime(CLOCK_MONOTONIC, &mt_pre);
16784a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    } else {
16794a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        if (interruptMode) {
16804a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            mFeatureActiveMask &= ~INV_DMP_PEDOMETER;
16814a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        }
16824a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        else {
16834a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            mFeatureActiveMask &= ~INV_DMP_PEDOMETER_STEP;
16844a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        }
16854a28f9c897c46c42a255823f7e307169a828a025Rosa Chow
16864a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        /* if neither step detector or step count is on */
16874a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        if (!(mFeatureActiveMask & (INV_DMP_PEDOMETER | INV_DMP_PEDOMETER_STEP))) {
16884a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            //Disable DMP Pedometer Function
16894a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)",
16904a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                    en, mpu.pedometer_on, getTimestamp());
16914a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            if (write_sysfs_int(mpu.pedometer_on, en) < 0) {
16924a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                LOGE("HAL:ERR can't enable Android Pedometer");
16934a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                res = -1;   // indicate an err
16944a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                return res;
16954a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            }
16964a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        }
169749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
16984a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        if (mFeatureActiveMask == 0 ) {
169949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            // disable DMP
170049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            res = onDmp(0);
170149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            if (res < 0) {
170249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                return res;
170349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            }
17044a28f9c897c46c42a255823f7e307169a828a025Rosa Chow
17054a28f9c897c46c42a255823f7e307169a828a025Rosa Chow             // disable accel engine
170649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow             if (!(mLocalSensorMask & mMasterSensorMask
170749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                        & INV_THREE_AXIS_ACCEL)) {
170849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                res = enableAccel(0);
170949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                if (res < 0) {
171049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                    return res;
171149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                }
171249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            }
171349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        }
17144a28f9c897c46c42a255823f7e307169a828a025Rosa Chow
17154a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        /* if feature is not step detector */
17164a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        if (!(mFeatureActiveMask & INV_DMP_PEDOMETER)) {
17174a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            //Disable DMP Pedometer Interrupt
17184a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)",
17194a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                    en, mpu.pedometer_int_on, getTimestamp());
17204a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            if (write_sysfs_int(mpu.pedometer_int_on, en) < 0) {
17214a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                LOGE("HAL:ERR can't enable Android Pedometer Interrupt");
17224a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                res = -1;   // indicate an err
17234a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                return res;
17244a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            }
17254a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        }
17264a28f9c897c46c42a255823f7e307169a828a025Rosa Chow
172749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        //enable data interrupts if applicable
172849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        if (enabled_sensors) {
172949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)",
173049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                        en, mpu.dmp_event_int_on, getTimestamp());
173149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            if (write_sysfs_int(mpu.dmp_event_int_on, en) < 0) {
173249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                res = -1;
173349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                LOGE("HAL:ERR can't enable DMP event interrupt");
173449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            }
173549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        }
173649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    }
17374a28f9c897c46c42a255823f7e307169a828a025Rosa Chow
173849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    if(en || enabled_sensors || mFeatureActiveMask) {
173949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        res = masterEnable(1);
174049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    }
174149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    return res;
174249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow}
174349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
174449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chowint MPLSensor::masterEnable(int en)
174549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow{
174649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    VFUNC_LOG;
174749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
174849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    int res = 0;
174949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)",
175049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            en, mpu.chip_enable, getTimestamp());
175149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    res = write_sysfs_int(mpu.chip_enable, en);
175249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    return res;
175349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow}
175449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
175549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chowint MPLSensor::enableGyro(int en)
175649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow{
175749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    VFUNC_LOG;
175849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
175949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    int res = 0;
176049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
176149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    /* need to also turn on/off the master enable */
17624a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)",
17634a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            en, mpu.gyro_enable, getTimestamp());
176449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    res = write_sysfs_int(mpu.gyro_enable, en);
17654a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)",
17664a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            en, mpu.gyro_fifo_enable, getTimestamp());
17674a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    res += write_sysfs_int(mpu.gyro_fifo_enable, en);
176849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
176949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    if (!en) {
177049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        LOGV_IF(EXTRA_VERBOSE, "HAL:MPL:inv_gyro_was_turned_off");
177149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        inv_gyro_was_turned_off();
177249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    }
177349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
177449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    return res;
177549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow}
177649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
177749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chowint MPLSensor::enableAccel(int en)
177849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow{
177949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    VFUNC_LOG;
178049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
178149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    int res;
178249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
178349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    /* need to also turn on/off the master enable */
17844a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)",
17854a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            en, mpu.accel_enable, getTimestamp());
178649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    res = write_sysfs_int(mpu.accel_enable, en);
17874a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)",
17884a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            en, mpu.accel_fifo_enable, getTimestamp());
17894a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    res += write_sysfs_int(mpu.accel_fifo_enable, en);
179049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
179149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    if (!en) {
179249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        LOGV_IF(EXTRA_VERBOSE, "HAL:MPL:inv_accel_was_turned_off");
179349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        inv_accel_was_turned_off();
179449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    }
179549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
179649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    return res;
179749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow}
179849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
179949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chowint MPLSensor::enableCompass(int en, int rawSensorRequested)
180049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow{
180149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    VFUNC_LOG;
180249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
180349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    int res = 0;
180449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    /* handle ID_RM if third party compass cal is used */
180549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    if (rawSensorRequested && mCompassSensor->providesCalibration()) {
180649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        res = mCompassSensor->enable(ID_RM, en);
180749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    } else {
180849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        res = mCompassSensor->enable(ID_M, en);
180949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    }
181049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    if (en == 0 || res != 0) {
181149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        LOGV_IF(EXTRA_VERBOSE, "HAL:MPL:inv_compass_was_turned_off %d", res);
181249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        inv_compass_was_turned_off();
181349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    }
181449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
181549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    return res;
181649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow}
181749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
181849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chowint MPLSensor::enablePressure(int en)
181949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow{
182049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    VFUNC_LOG;
182149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
182249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    int res = 0;
18234a28f9c897c46c42a255823f7e307169a828a025Rosa Chow
18242a34df3e7851e7af4095fda80700562af17c4e28Vineeta Srivastava    if (mPressureSensor) {
18258a501706d8a30295a312ccc05fba80097050204fkangsik.shin        res = mPressureSensor->enable(ID_PS, en);
18262a34df3e7851e7af4095fda80700562af17c4e28Vineeta Srivastava    } else {
18272a34df3e7851e7af4095fda80700562af17c4e28Vineeta Srivastava        LOGV_IF(ENG_VERBOSE, "HAL:PRESSURE sensor not detected");
18282a34df3e7851e7af4095fda80700562af17c4e28Vineeta Srivastava    }
182949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
183049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    return res;
183149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow}
183249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
18334a28f9c897c46c42a255823f7e307169a828a025Rosa Chow/* use this function for initialization */
18344a28f9c897c46c42a255823f7e307169a828a025Rosa Chowint MPLSensor::enableBatch(int64_t timeout)
18354a28f9c897c46c42a255823f7e307169a828a025Rosa Chow{
18364a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    VFUNC_LOG;
18374a28f9c897c46c42a255823f7e307169a828a025Rosa Chow
18384a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    int res = 0;
18394a28f9c897c46c42a255823f7e307169a828a025Rosa Chow
18404a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    res = write_sysfs_int(mpu.batchmode_timeout, timeout);
18414a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    if (timeout == 0) {
18424a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        res = write_sysfs_int(mpu.six_axis_q_on, 0);
18434a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        res = write_sysfs_int(mpu.ped_q_on, 0);
18444a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        res = write_sysfs_int(mpu.step_detector_on, 0);
18454a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        res = write_sysfs_int(mpu.step_indicator_on, 0);
18464a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    }
18474a28f9c897c46c42a255823f7e307169a828a025Rosa Chow
18484a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    if (timeout == 0) {
18494a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        LOGV_IF(EXTRA_VERBOSE, "HAL:MPL:batchmode timeout is zero");
18504a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    }
18514a28f9c897c46c42a255823f7e307169a828a025Rosa Chow
18524a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    return res;
18534a28f9c897c46c42a255823f7e307169a828a025Rosa Chow}
18544a28f9c897c46c42a255823f7e307169a828a025Rosa Chow
185549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chowvoid MPLSensor::computeLocalSensorMask(int enabled_sensors)
185649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow{
185749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    VFUNC_LOG;
185849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
185949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    do {
18604a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        /* Invensense Pressure on secondary bus */
18614a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        if (PS_ENABLED) {
18624a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            LOGV_IF(ENG_VERBOSE, "PS ENABLED");
18634a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            mLocalSensorMask |= INV_ONE_AXIS_PRESSURE;
18644a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        } else {
18654a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            LOGV_IF(ENG_VERBOSE, "PS DISABLED");
18664a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            mLocalSensorMask &= ~INV_ONE_AXIS_PRESSURE;
18674a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        }
18684a28f9c897c46c42a255823f7e307169a828a025Rosa Chow
186949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        if (LA_ENABLED || GR_ENABLED || RV_ENABLED || O_ENABLED
187049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                       || (GRV_ENABLED && GMRV_ENABLED)) {
187149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            LOGV_IF(ENG_VERBOSE, "FUSION ENABLED");
187249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            mLocalSensorMask = ALL_MPL_SENSORS_NP;
187349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            break;
187449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        }
187549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
187649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        if (GRV_ENABLED) {
187749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            if (!(mBatchEnabled & (1 << GameRotationVector))) {
187849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                LOGV_IF(ENG_VERBOSE, "6 Axis Fusion ENABLED");
187949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                mLocalSensorMask |= INV_THREE_AXIS_GYRO;
188049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                mLocalSensorMask |= INV_THREE_AXIS_ACCEL;
18814a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            } else {
18824a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                if (GY_ENABLED || RGY_ENABLED) {
18834a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                    LOGV_IF(ENG_VERBOSE, "G ENABLED");
18844a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                    mLocalSensorMask |= INV_THREE_AXIS_GYRO;
18854a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                } else {
18864a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                    LOGV_IF(ENG_VERBOSE, "G DISABLED");
18874a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                    mLocalSensorMask &= ~INV_THREE_AXIS_GYRO;
18884a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                }
18894a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                if (A_ENABLED) {
18904a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                    LOGV_IF(ENG_VERBOSE, "A ENABLED");
18914a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                    mLocalSensorMask |= INV_THREE_AXIS_ACCEL;
18924a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                } else {
18934a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                    LOGV_IF(ENG_VERBOSE, "A DISABLED");
18944a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                    mLocalSensorMask &= ~INV_THREE_AXIS_ACCEL;
18954a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                }
189649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            }
189749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            /* takes care of MAG case */
189849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            if (M_ENABLED || RM_ENABLED) {
189949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                LOGV_IF(1, "M ENABLED");
190049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                mLocalSensorMask |= INV_THREE_AXIS_COMPASS;
190149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            } else {
190249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                LOGV_IF(1, "M DISABLED");
190349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                mLocalSensorMask &= ~INV_THREE_AXIS_COMPASS;
190449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            }
190549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            break;
190649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        }
190749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
190849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        if (GMRV_ENABLED) {
190949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            LOGV_IF(ENG_VERBOSE, "6 Axis Geomagnetic Fusion ENABLED");
191049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            mLocalSensorMask |= INV_THREE_AXIS_ACCEL;
191149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            mLocalSensorMask |= INV_THREE_AXIS_COMPASS;
191249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
191349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            /* takes care of Gyro case */
191449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            if (GY_ENABLED || RGY_ENABLED) {
191549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                LOGV_IF(1, "G ENABLED");
191649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                mLocalSensorMask |= INV_THREE_AXIS_GYRO;
191749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            } else {
191849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                LOGV_IF(1, "G DISABLED");
191949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                mLocalSensorMask &= ~INV_THREE_AXIS_GYRO;
192049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            }
192149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            break;
192249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        }
192349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
192449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        if(!A_ENABLED && !M_ENABLED && !RM_ENABLED &&
192549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow               !GRV_ENABLED && !GMRV_ENABLED && !GY_ENABLED && !RGY_ENABLED &&
192649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow               !PS_ENABLED) {
192749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            /* Invensense compass cal */
192849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            LOGV_IF(ENG_VERBOSE, "ALL DISABLED");
192949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            mLocalSensorMask = 0;
193049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            break;
193149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        }
193249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
193349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        if (GY_ENABLED || RGY_ENABLED) {
193449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            LOGV_IF(ENG_VERBOSE, "G ENABLED");
193549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            mLocalSensorMask |= INV_THREE_AXIS_GYRO;
193649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        } else {
193749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            LOGV_IF(ENG_VERBOSE, "G DISABLED");
193849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            mLocalSensorMask &= ~INV_THREE_AXIS_GYRO;
193949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        }
194049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
194149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        if (A_ENABLED) {
194249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            LOGV_IF(ENG_VERBOSE, "A ENABLED");
194349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            mLocalSensorMask |= INV_THREE_AXIS_ACCEL;
194449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        } else {
194549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            LOGV_IF(ENG_VERBOSE, "A DISABLED");
194649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            mLocalSensorMask &= ~INV_THREE_AXIS_ACCEL;
194749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        }
194849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
194949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        /* Invensense compass calibration */
195049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        if (M_ENABLED || RM_ENABLED) {
195149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            LOGV_IF(ENG_VERBOSE, "M ENABLED");
195249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            mLocalSensorMask |= INV_THREE_AXIS_COMPASS;
195349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        } else {
195449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            LOGV_IF(ENG_VERBOSE, "M DISABLED");
195549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            mLocalSensorMask &= ~INV_THREE_AXIS_COMPASS;
19564a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        }
195749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    } while (0);
195849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow}
195949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
196049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chowint MPLSensor::enableSensors(unsigned long sensors, int en, uint32_t changed)
196149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow{
196249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    VFUNC_LOG;
196349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
196449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    inv_error_t res = -1;
196549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    int on = 1;
196649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    int off = 0;
196749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    int cal_stored = 0;
196849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
196949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    // Sequence to enable or disable a sensor
197049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    // 1. reset master enable (=0)
197149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    // 2. enable or disable a sensor
197249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    // 3. set master enable (=1)
197349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
197449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    if (isLowPowerQuatEnabled() ||
197549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        changed & ((1 << Gyro) | (1 << RawGyro) | (1 << Accelerometer) |
197649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        (mCompassSensor->isIntegrated() << MagneticField) |
197749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        (mCompassSensor->isIntegrated() << RawMagneticField) |
197849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        (mPressureSensor->isIntegrated() << Pressure))) {
197949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
198049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        /* reset master enable */
198149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        res = masterEnable(0);
198249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        if(res < 0) {
198349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            return res;
198449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        }
198549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    }
198649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
198749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    LOGV_IF(PROCESS_VERBOSE, "HAL:enableSensors - sensors: 0x%0x",
198849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            (unsigned int)sensors);
198949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
199049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    if (changed & ((1 << Gyro) | (1 << RawGyro))) {
199149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        LOGV_IF(PROCESS_VERBOSE, "HAL:enableSensors - gyro %s",
199249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            (sensors & INV_THREE_AXIS_GYRO? "enable": "disable"));
199349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        res = enableGyro(!!(sensors & INV_THREE_AXIS_GYRO));
199449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        if(res < 0) {
199549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            return res;
199649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        }
199749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
199849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        if (!cal_stored && (!en && (changed & (1 << Gyro)))) {
199949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            storeCalibration();
200049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            cal_stored = 1;
200149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        }
200249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    }
200349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
200449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    if (changed & (1 << Accelerometer)) {
200549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        LOGV_IF(PROCESS_VERBOSE, "HAL:enableSensors - accel %s",
200649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            (sensors & INV_THREE_AXIS_ACCEL? "enable": "disable"));
200749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        res = enableAccel(!!(sensors & INV_THREE_AXIS_ACCEL));
200849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        if(res < 0) {
200949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            return res;
201049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        }
201149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
201249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        if (!(sensors & INV_THREE_AXIS_ACCEL) && !cal_stored) {
201349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            storeCalibration();
201449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            cal_stored = 1;
201549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        }
201649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    }
201749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
201849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    if (changed & ((1 << MagneticField) | (1 << RawMagneticField))) {
201949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        LOGV_IF(PROCESS_VERBOSE, "HAL:enableSensors - compass %s",
202049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            (sensors & INV_THREE_AXIS_COMPASS? "enable": "disable"));
202149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        res = enableCompass(!!(sensors & INV_THREE_AXIS_COMPASS), changed & (1 << RawMagneticField));
202249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        if(res < 0) {
202349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            return res;
202449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        }
202549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
202649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        if (!cal_stored && (!en && (changed & (1 << MagneticField)))) {
202749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            storeCalibration();
202849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            cal_stored = 1;
202949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        }
203049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    }
203149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
203249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow     if (changed & (1 << Pressure)) {
203349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        LOGV_IF(PROCESS_VERBOSE, "HAL:enableSensors - pressure %s",
203449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            (sensors & INV_ONE_AXIS_PRESSURE? "enable": "disable"));
203549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        res = enablePressure(!!(sensors & INV_ONE_AXIS_PRESSURE));
203649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        if(res < 0) {
203749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            return res;
203849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        }
203949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    }
204049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
204149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    if (isLowPowerQuatEnabled()) {
204249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        // Enable LP Quat
204349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        if ((mEnabled & VIRTUAL_SENSOR_9AXES_MASK)
204449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                      || (mEnabled & VIRTUAL_SENSOR_GYRO_6AXES_MASK)) {
204549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow  LOGI("HAL: 9 axis or game rot enabled");
204649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            if (!(changed & ((1 << Gyro)
204749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                           | (1 << RawGyro)
204849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                           | (1 << Accelerometer)
204949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                           | (mCompassSensor->isIntegrated() << MagneticField)
205049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                           | (mCompassSensor->isIntegrated() << RawMagneticField)))
205149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            ) {
205249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                /* reset master enable */
205349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                res = masterEnable(0);
205449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                if(res < 0) {
205549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                    return res;
205649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                }
205749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            }
205849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            if (!checkLPQuaternion()) {
205949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                enableLPQuaternion(1);
206049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            } else {
206149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                LOGV_IF(PROCESS_VERBOSE, "HAL:LP Quat already enabled");
206249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            }
206349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        } else if (checkLPQuaternion()) {
206449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            enableLPQuaternion(0);
206549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        }
206649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    }
206749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
206849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    /* apply accel/gyro bias to DMP bias                        */
206949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    /* precondition: masterEnable(0), mGyroBiasAvailable=true   */
207049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    /* postcondition: bias is applied upon masterEnable(1)      */
207149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    if(!(sensors & INV_THREE_AXIS_GYRO)) {
207249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        setGyroBias();
207349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    }
207449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    if(!(sensors & INV_THREE_AXIS_ACCEL)) {
207549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        setAccelBias();
207649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    }
207749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
207849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    /* to batch or not to batch */
207949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    int batchMode = computeBatchSensorMask(mEnabled, mBatchEnabled);
20804a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    setBatch(batchMode,0);
208149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
208249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    if (changed & ((1 << Gyro) | (1 << RawGyro) | (1 << Accelerometer) |
208349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            (mCompassSensor->isIntegrated() << MagneticField) |
208449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            (mCompassSensor->isIntegrated() << RawMagneticField) |
208549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            (mPressureSensor->isIntegrated() << Pressure))) {
208649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        LOGV_IF(ENG_VERBOSE, "HAL DEBUG: Gyro, Accel, Compass, Pressure changes");
208749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        if ((checkSmdSupport() == 1) || (checkPedometerSupport() == 1) || (sensors &
208849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            (INV_THREE_AXIS_GYRO
208949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                | INV_THREE_AXIS_ACCEL
209049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                | (INV_THREE_AXIS_COMPASS * mCompassSensor->isIntegrated())
209149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                | (INV_ONE_AXIS_PRESSURE * mPressureSensor->isIntegrated())))) {
209249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            LOGV_IF(ENG_VERBOSE, "SMD or Hardware sensors enabled");
209349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            LOGV_IF(ENG_VERBOSE, "mFeatureActiveMask=%016llx", mFeatureActiveMask);
209449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            if (mFeatureActiveMask & DMP_FEATURE_MASK) {
209549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                LOGV_IF(ENG_VERBOSE, "HAL DEBUG: LPQ, SMD, SO enabled");
209649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                // disable DMP event interrupt only (w/ data interrupt)
209749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)",
209849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                        0, mpu.dmp_event_int_on, getTimestamp());
209949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                if (write_sysfs_int(mpu.dmp_event_int_on, 0) < 0) {
210049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                    res = -1;
210149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                    LOGE("HAL:ERR can't disable DMP event interrupt");
210249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                    return res;
210349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                }
210449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            }
210549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
21064a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            if ((mFeatureActiveMask & DMP_FEATURE_MASK) &&
21074a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                    !((mFeatureActiveMask & 0x240) ||
21084a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                        (mFeatureActiveMask & 0x220) ||
21094a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                        (mFeatureActiveMask & 0x280))) {
211049ea3e26ca3c6a779e527a0322e49a663333350aRosa ChowLOGI("mFeatureActiveMask=%lld", mFeatureActiveMask);
211149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                // enable DMP
211249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                onDmp(1);
211349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                res = enableAccel(on);
211449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                if(res < 0) {
211549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                    return res;
211649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                }
211749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                if ((sensors & INV_THREE_AXIS_ACCEL) == 0) {
211849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                    res = turnOffAccelFifo();
211949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                }
212049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                if(res < 0) {
212149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                    return res;
212249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                }
212349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            }
212449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            res = masterEnable(1);
212549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            if(res < 0) {
212649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                return res;
212749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            }
212849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        } else { // all sensors idle -> reduce power
212949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            LOGV_IF(ENG_VERBOSE, "HAL DEBUG: not SMD or Hardware sensors");
213049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            if (isDmpDisplayOrientationOn()
213149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                    && (mDmpOrientationEnabled
213249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                            || !isDmpScreenAutoRotationEnabled())) {
213349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                enableDmpOrientation(1);
213449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            }
213549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
213649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            if (!cal_stored) {
213749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                storeCalibration();
213849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                cal_stored = 1;
213949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            }
214049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        }
214149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    } else if ((changed &
214249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                    ((!mCompassSensor->isIntegrated()) << MagneticField) ||
214349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                    ((!mCompassSensor->isIntegrated()) << RawMagneticField))
214449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                    &&
214549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow              !(sensors & (INV_THREE_AXIS_GYRO | INV_THREE_AXIS_ACCEL
214649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                | (INV_THREE_AXIS_COMPASS * (!mCompassSensor->isIntegrated()))))
214749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    ) {
214849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        LOGV_IF(ENG_VERBOSE, "HAL DEBUG: Gyro, Accel, Compass no change");
214949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        if (!cal_stored) {
215049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            storeCalibration();
215149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            cal_stored = 1;
215249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        }
215349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    } else {
215449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow      LOGV_IF(ENG_VERBOSE, "HAL DEBUG: mEnabled");
215549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow      if (sensors &
215649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            (INV_THREE_AXIS_GYRO
215749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                | INV_THREE_AXIS_ACCEL
215849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                | (INV_THREE_AXIS_COMPASS * mCompassSensor->isIntegrated()))) {
215949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            res = masterEnable(1);
216049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            if(res < 0)
216149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                return res;
216249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        }
216349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    }
216449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
216549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    return res;
216649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow}
216749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
216849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow/* check if batch mode should be turned on or not */
216949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chowint MPLSensor::computeBatchSensorMask(int enableSensors, int tempBatchSensor)
217049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow{
217149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    VFUNC_LOG;
217249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    int batchMode = 1;
21734a28f9c897c46c42a255823f7e307169a828a025Rosa Chow
21744a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    LOGV("HAL:computeBatchSensorMask: enableSensors=%d tempBatchSensor=%d", enableSensors, tempBatchSensor);
21754a28f9c897c46c42a255823f7e307169a828a025Rosa Chow
217649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    // check for possible continuous data mode
21774a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    for(int i = 0; i <= Pressure; i++) {
217849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        if ((enableSensors & (1 << i)) && !(tempBatchSensor & (1 << i))) {
217949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            LOGV("HAL:computeBatchSensorMask: hardware sensor on continuous mode:%d", i);
218049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            // if any one of the hardware sensor is in continuous data mode
218149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            // turn off batch mode.
218249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            return 0;
218349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        }
218449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        if ((enableSensors & (1 << i)) && (tempBatchSensor & (1 << i))) {
218549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            LOGV("HAL:computeBatchSensorMask: hardware sensor is batch:%d", i);
218649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            // if hardware sensor is batched, check if virtual sensor is batched
218749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            if ((enableSensors & (1 << GameRotationVector))
218849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                            && !(tempBatchSensor & (1 << GameRotationVector))) {
218949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            LOGV("HAL:computeBatchSensorMask: but virtual sensor is not:%d", i);
219049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                return 0;
219149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            }
219249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        }
219349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    }
21944a28f9c897c46c42a255823f7e307169a828a025Rosa Chow
21954a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    for(int i = Orientation; i <= GeomagneticRotationVector; i++) {
21964a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        if ((enableSensors & (1 << i)) && !(tempBatchSensor & (1 << i))) {
21974a28f9c897c46c42a255823f7e307169a828a025Rosa Chow             LOGV("HAL:computeBatchSensorMask: composite sensor on continuous mode:%d", i);
21984a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            // if composite sensors are on but not batched
21994a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            // turn off batch mode.
22004a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            return 0;
22014a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        }
22024a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    }
22034a28f9c897c46c42a255823f7e307169a828a025Rosa Chow
220449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    LOGV_IF(EXTRA_VERBOSE, "HAL:computeBatchSensorMask: batchMode=%d, mBatchEnabled=%0x", batchMode, tempBatchSensor);
220549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    return (batchMode && tempBatchSensor);
220649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow}
220749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
22084a28f9c897c46c42a255823f7e307169a828a025Rosa Chow/* This function is called by enable() */
22094a28f9c897c46c42a255823f7e307169a828a025Rosa Chowint MPLSensor::setBatch(int en, int toggleEnable)
221049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow{
221149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    VFUNC_LOG;
221249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
221349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    int res = 0;
221449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    int64_t wanted = 1000000000LL;
221549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    int64_t timeout = 0;
22164a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    int timeoutInMs = 0;
22174a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    int featureMask = computeBatchDataOutput();
221849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
221949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    // reset master enable
222049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    res = masterEnable(0);
222149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    if (res < 0) {
222249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        return res;
222349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    }
222449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
222549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    if (en) {
22264a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        /* take the minimum batchmode timeout */
22274a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        int64_t timeout = 30000000000LL;
22284a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        int64_t ns;
22294a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        for (int i = 0; i < NumSensors; i++) {
22304a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            LOGV_IF(0, "mFeatureActiveMask=0x%016llx, mEnabled=0x%01x, mBatchEnabled=0x%x",
22314a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                            mFeatureActiveMask, mEnabled, mBatchEnabled);
22324a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            if ((mEnabled & (1 << i)) && (mBatchEnabled & (1 << i)) ||
22334a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                    (((featureMask & INV_DMP_PED_STANDALONE) && (mBatchEnabled & (1 << StepDetector))))) {
22344a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                LOGV_IF(ENG_VERBOSE, "sensor=%d, timeout=%lld", i, mBatchTimeouts[i]);
22354a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                ns = mBatchTimeouts[i];
22364a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                timeout = (ns < timeout) ? ns : timeout;
22374a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            }
22384a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        }
22394a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        /* Convert ns to millisecond */
22404a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        timeoutInMs = timeout / 1000000;
22414a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    } else {
22424a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        timeoutInMs = 0;
22434a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    }
22444a28f9c897c46c42a255823f7e307169a828a025Rosa Chow
22454a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    LOGV_IF(PROCESS_VERBOSE, "HAL: batch timeout set to %dms", timeoutInMs);
22464a28f9c897c46c42a255823f7e307169a828a025Rosa Chow
22474a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    /* step detector is enabled and */
22484a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    /* batch mode is standalone */
22494a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    if (en && (mFeatureActiveMask & INV_DMP_PEDOMETER) &&
22504a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            (featureMask & INV_DMP_PED_STANDALONE)) {
22514a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        LOGI("ID_P only = 0x%x", mBatchEnabled);
22524a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        enablePedStandalone(1);
22534a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    } else {
22544a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        enablePedStandalone(0);
22554a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    }
22564a28f9c897c46c42a255823f7e307169a828a025Rosa Chow
22574a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    /* step detector and GRV are enabled and */
22584a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    /* batch mode is ped q */
22594a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    if (en && (mFeatureActiveMask & INV_DMP_PEDOMETER) &&
22604a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            (mEnabled & (1 << GameRotationVector)) &&
22614a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            (featureMask & INV_DMP_PED_QUATERNION)) {
22624a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        LOGI("ID_P and GRV or ALL = 0x%x", mBatchEnabled);
22634a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        LOGI("ID_P is enabled for batching, PED quat will be automatically enabled");
22644a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        enableLPQuaternion(0);
22654a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        enablePedQuaternion(1);
22664a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    } else if (!(featureMask & INV_DMP_PED_STANDALONE)){
22674a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        enablePedQuaternion(0);
226849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    }
226949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
22704a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    /* step detector and hardware sensors enabled */
22714a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    if (en && (featureMask & INV_DMP_PED_INDICATOR) &&
22724a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            ((mEnabled) ||
22734a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            (mFeatureActiveMask & INV_DMP_PED_STANDALONE))) {
22744a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        enablePedIndicator(1);
22754a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    } else {
22764a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        enablePedIndicator(0);
22774a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    }
22784a28f9c897c46c42a255823f7e307169a828a025Rosa Chow
22794a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    /* GRV is enabled and */
22804a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    /* batch mode is 6axis q */
22814a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    if (en && (mEnabled & (1 << GameRotationVector)) &&
22824a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            (featureMask & INV_DMP_6AXIS_QUATERNION)) {
22834a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        LOGI("GRV = 0x%x", mBatchEnabled);
22844a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        enableLPQuaternion(0);
22854a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        enable6AxisQuaternion(1);
22864a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    } else if (!(featureMask & INV_DMP_PED_QUATERNION)){
22874a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        LOGI("Toggle back to normal 6 axis");
22884a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        if (mEnabled & (1 << GameRotationVector)) {
22894a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            enableLPQuaternion(1);
22904a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        }
22914a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        enable6AxisQuaternion(0);
22924a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    }
22934a28f9c897c46c42a255823f7e307169a828a025Rosa Chow
229449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    /* write required timeout to sysfs */
22954a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)",
22964a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            timeoutInMs, mpu.batchmode_timeout, getTimestamp());
22974a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    if (write_sysfs_int(mpu.batchmode_timeout, timeoutInMs) < 0) {
229849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        LOGE("HAL:ERR can't write batchmode_timeout");
229949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    }
230049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
230149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    if (en) {
230249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        // enable DMP
230349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        res = onDmp(1);
230449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        if (res < 0) {
230549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            return res;
230649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        }
23074a28f9c897c46c42a255823f7e307169a828a025Rosa Chow
23084a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        // set batch rates
23094a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        if (setBatchDataRates() < 0) {
23104a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            LOGE("HAL:ERR can't set batch data rates");
231149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        }
23124a28f9c897c46c42a255823f7e307169a828a025Rosa Chow
231349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        // default fifo rate to 200Hz
231449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)",
231549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                200, mpu.gyro_fifo_rate, getTimestamp());
231649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        if (write_sysfs_int(mpu.gyro_fifo_rate, 200) < 0) {
231749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            res = -1;
23184a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            LOGE("HAL:ERR can't set rate to 200Hz");
231949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            return res;
232049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        }
232149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    } else {
232249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        if (mFeatureActiveMask == 0) {
232349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            // disable DMP
232449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            res = onDmp(0);
232549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            if (res < 0) {
232649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                return res;
232749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            }
232849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        }
23294a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        /* reset sensor rate */
23304a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        /*if (resetDataRates() < 0) {
23314a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            LOGE("HAL:ERR can't reset output rate back to original setting");
23324a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        }*/
23334a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    }
23344a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    if (toggleEnable == 1) {
23354a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        if (mFeatureActiveMask || mEnabled)
233649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            masterEnable(1);
233749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    }
233849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    return res;
233949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow}
234049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
234149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow/* Store calibration file */
234249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chowvoid MPLSensor::storeCalibration(void)
234349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow{
234449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    if(mHaveGoodMpuCal == true
234549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        || mAccelAccuracy >= 2
234649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        || mCompassAccuracy >= 3) {
234749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow       int res = inv_store_calibration();
234849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow       if (res) {
234949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow           LOGE("HAL:Cannot store calibration on file");
235049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow       } else {
235149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow           LOGV_IF(PROCESS_VERBOSE, "HAL:Cal file updated");
235249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow       }
235349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    }
235449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow}
235549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
235649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chowvoid MPLSensor::cbProcData(void)
235749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow{
235849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    mNewData = 1;
235949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    mSampleCount++;
236049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    LOGV_IF(EXTRA_VERBOSE, "HAL:new data");
236149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow}
236249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
236349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow/*  these handlers transform mpl data into one of the Android sensor types */
236449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chowint MPLSensor::gyroHandler(sensors_event_t* s)
236549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow{
236649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    VHANDLER_LOG;
236749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    int update;
236849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    update = inv_get_sensor_type_gyroscope(s->gyro.v, &s->gyro.status,
236949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                                           &s->timestamp);
237049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    LOGV_IF(HANDLER_DATA, "HAL:gyro data : %+f %+f %+f -- %lld - %d",
237149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            s->gyro.v[0], s->gyro.v[1], s->gyro.v[2], s->timestamp, update);
237249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    return update;
237349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow}
237449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
237549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chowint MPLSensor::rawGyroHandler(sensors_event_t* s)
237649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow{
237749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    VHANDLER_LOG;
237849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    int update;
237949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    update = inv_get_sensor_type_gyroscope_raw(s->uncalibrated_gyro.uncalib,
238049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                                               &s->gyro.status, &s->timestamp);
238149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    if(update) {
238249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        memcpy(s->uncalibrated_gyro.bias, mGyroBias, sizeof(mGyroBias));
238349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        LOGV_IF(HANDLER_DATA,"HAL:gyro bias data : %+f %+f %+f -- %lld - %d",
238449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            s->uncalibrated_gyro.bias[0], s->uncalibrated_gyro.bias[1],
238549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            s->uncalibrated_gyro.bias[2], s->timestamp, update);
238649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    }
238749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    s->gyro.status = SENSOR_STATUS_UNRELIABLE;
238849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    LOGV_IF(HANDLER_DATA, "HAL:raw gyro data : %+f %+f %+f -- %lld - %d",
238949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            s->uncalibrated_gyro.uncalib[0], s->uncalibrated_gyro.uncalib[1],
239049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            s->uncalibrated_gyro.uncalib[2], s->timestamp, update);
239149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    return update;
239249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow}
239349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
239449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chowint MPLSensor::accelHandler(sensors_event_t* s)
239549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow{
239649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    VHANDLER_LOG;
239749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    int update;
239849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    update = inv_get_sensor_type_accelerometer(
239949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        s->acceleration.v, &s->acceleration.status, &s->timestamp);
240049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    LOGV_IF(HANDLER_DATA, "HAL:accel data : %+f %+f %+f -- %lld - %d",
240149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            s->acceleration.v[0], s->acceleration.v[1], s->acceleration.v[2],
240249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            s->timestamp, update);
240349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    mAccelAccuracy = s->acceleration.status;
240449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    return update;
240549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow}
240649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
240749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chowint MPLSensor::compassHandler(sensors_event_t* s)
240849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow{
240949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    VHANDLER_LOG;
241049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    int update;
241149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    update = inv_get_sensor_type_magnetic_field(
241249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        s->magnetic.v, &s->magnetic.status, &s->timestamp);
241349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    LOGV_IF(HANDLER_DATA, "HAL:compass data: %+f %+f %+f -- %lld - %d",
241449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            s->magnetic.v[0], s->magnetic.v[1], s->magnetic.v[2],
241549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            s->timestamp, update);
241649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    mCompassAccuracy = s->magnetic.status;
241749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    return update;
241849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow}
241949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
242049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chowint MPLSensor::rawCompassHandler(sensors_event_t* s)
242149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow{
242249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    VHANDLER_LOG;
242349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    int update;
242449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    //TODO:: need to handle uncalib data and bias for 3rd party compass
242549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    if(mCompassSensor->providesCalibration()) {
242649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        update = mCompassSensor->readRawSample(s->uncalibrated_magnetic.uncalib, &s->timestamp);
242749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    }
242849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    else {
242949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        update = inv_get_sensor_type_magnetic_field_raw(s->uncalibrated_magnetic.uncalib,
243049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                     &s->magnetic.status, &s->timestamp);
243149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    }
243249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    if(update) {
243349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        memcpy(s->uncalibrated_magnetic.bias, mCompassBias, sizeof(mCompassBias));
243449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        LOGV_IF(HANDLER_DATA, "HAL:compass bias data: %+f %+f %+f -- %lld - %d",
243549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                s->uncalibrated_magnetic.bias[0], s->uncalibrated_magnetic.bias[1],
243649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                s->uncalibrated_magnetic.bias[2], s->timestamp, update);
243749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    }
243849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    s->magnetic.status = SENSOR_STATUS_UNRELIABLE;
243949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    LOGV_IF(HANDLER_DATA, "HAL:compass raw data: %+f %+f %+f %d -- %lld - %d",
244049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        s->uncalibrated_magnetic.uncalib[0], s->uncalibrated_magnetic.uncalib[1],
244149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                    s->uncalibrated_magnetic.uncalib[2], s->magnetic.status, s->timestamp, update);
244249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    return update;
244349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow}
244449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
244549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow/*
244649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    Rotation Vector handler.
244749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    NOTE: rotation vector does not have an accuracy or status
244849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow*/
244949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chowint MPLSensor::rvHandler(sensors_event_t* s)
245049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow{
245149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    VHANDLER_LOG;
245249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    int8_t status;
245349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    int update;
245449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    update = inv_get_sensor_type_rotation_vector(s->data, &status,
245549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                                                 &s->timestamp);
245649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    update |= isCompassDisabled();
245749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    LOGV_IF(HANDLER_DATA, "HAL:rv data: %+f %+f %+f %+f %+f- %+lld - %d",
245849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            s->data[0], s->data[1], s->data[2], s->data[3], s->data[4], s->timestamp,
245949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            update);
246049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
246149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    return update;
246249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow}
246349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
246449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow/*
246549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    Game Rotation Vector handler.
246649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    NOTE: rotation vector does not have an accuracy or status
246749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow*/
246849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chowint MPLSensor::grvHandler(sensors_event_t* s)
246949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow{
247049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    VHANDLER_LOG;
247149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    int8_t status;
247249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    int update;
247349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    update = inv_get_sensor_type_rotation_vector_6_axis(s->data, &status,
247449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                                                     &s->timestamp);
24754a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    /*hack*/
24764a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    /*s->data[0] =  mCached6AxisQuaternionData[0];
24774a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    s->data[1] =  mCached6AxisQuaternionData[1];
24784a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    s->data[2] =  mCached6AxisQuaternionData[2];
24794a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    update = 1;*/
24804a28f9c897c46c42a255823f7e307169a828a025Rosa Chow
24814a28f9c897c46c42a255823f7e307169a828a025Rosa Chow
248249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    LOGV_IF(HANDLER_DATA, "HAL:grv data: %+f %+f %+f %+f %+f - %+lld - %d",
248349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            s->data[0], s->data[1], s->data[2], s->data[3], s->data[4], s->timestamp,
248449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            update);
248549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    return update;
248649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow}
248749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
248849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chowint MPLSensor::laHandler(sensors_event_t* s)
248949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow{
249049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    VHANDLER_LOG;
249149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    int update;
249249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    update = inv_get_sensor_type_linear_acceleration(
249349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            s->gyro.v, &s->gyro.status, &s->timestamp);
249449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    update |= isCompassDisabled();
249549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    LOGV_IF(HANDLER_DATA, "HAL:la data: %+f %+f %+f - %lld - %d",
249649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            s->gyro.v[0], s->gyro.v[1], s->gyro.v[2], s->timestamp, update);
249749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    return update;
249849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow}
249949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
250049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chowint MPLSensor::gravHandler(sensors_event_t* s)
250149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow{
250249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    VHANDLER_LOG;
250349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    int update;
250449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    update = inv_get_sensor_type_gravity(s->gyro.v, &s->gyro.status,
250549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                                         &s->timestamp);
250649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    update |= isCompassDisabled();
250749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    LOGV_IF(HANDLER_DATA, "HAL:gr data: %+f %+f %+f - %lld - %d",
250849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            s->gyro.v[0], s->gyro.v[1], s->gyro.v[2], s->timestamp, update);
250949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    return update;
251049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow}
251149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
251249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chowint MPLSensor::orienHandler(sensors_event_t* s)
251349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow{
251449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    VHANDLER_LOG;
251549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    int update;
251649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    update = inv_get_sensor_type_orientation(
251749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            s->orientation.v, &s->orientation.status, &s->timestamp);
251849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    update |= isCompassDisabled();
251949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    LOGV_IF(HANDLER_DATA, "HAL:or data: %f %f %f - %lld - %d",
252049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            s->orientation.v[0], s->orientation.v[1], s->orientation.v[2],
252149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            s->timestamp, update);
252249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    return update;
252349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow}
252449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
252549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chowint MPLSensor::smHandler(sensors_event_t* s)
252649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow{
252749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    VHANDLER_LOG;
252849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    int update = 1;
252949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
253049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    /* When event is triggered, set data to 1 */
253149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    s->data[0] = 1.f;
253249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    s->data[1] = 0.f;
253349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    s->data[2] = 0.f;
253449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    s->acceleration.status
253549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            = SENSOR_STATUS_UNRELIABLE;
253649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
253749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    /* Capture timestamp in HAL */
253849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    struct timespec ts;
253949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    clock_gettime(CLOCK_MONOTONIC, &ts);
254049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    s->timestamp = (int64_t) ts.tv_sec * 1000000000 + ts.tv_nsec;
254149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
254249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    /* Identify which sensor this event is for */
254349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    s->version = sizeof(sensors_event_t);
254449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    s->sensor = ID_SM;
254549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    s->type = SENSOR_TYPE_SIGNIFICANT_MOTION;
254649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
254749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    LOGV_IF(HANDLER_DATA, "HAL:sm data: %f - %lld - %d",
254849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            s->data[0], s->timestamp, update);
254949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    return update;
255049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow}
255149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
255249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chowint MPLSensor::scHandler(sensors_event_t* s)
255349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow{
255449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    VHANDLER_LOG;
255549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    int update = 0;
255649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
255749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    //update = readDmpPedometerEvents(s, 1);
255849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    LOGV_IF(HANDLER_DATA, "HAL:sc data: %f - %lld - %d",
255949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            s->data[0], s->timestamp, update);
256049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    return update < 1 ? 0 :1;
256149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow}
256249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
256349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chowint MPLSensor::gmHandler(sensors_event_t* s)
256449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow{
256549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    VHANDLER_LOG;
256649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    int8_t status;
256749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    int update = 0;
256849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    update = inv_get_sensor_type_geomagnetic_rotation_vector(s->data, &status,
256949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                                                             &s->timestamp);
257049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
257149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    LOGV_IF(HANDLER_DATA, "HAL:gm data: %+f %+f %+f %+f %+f- %+lld - %d",
257249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            s->data[0], s->data[1], s->data[2], s->data[3], s->data[4], s->timestamp, update);
257349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    return update < 1 ? 0 :1;
257449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
257549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow}
257649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
257749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chowint MPLSensor::psHandler(sensors_event_t* s)
257849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow{
257949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    VHANDLER_LOG;
258049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    int8_t status;
258149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    int update = 0;
258249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
258349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    s->data[0] = mCachedPressureData / 100; //hpa (millibar)
258449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    s->data[1] = 0;
258549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    s->data[2] = 0;
258649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    s->timestamp = mPressureTimestamp;
258749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    s->magnetic.status = 0;
258849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    update = 1;
258949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
259049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    LOGV_IF(HANDLER_DATA, "HAL:ps data: %+f %+f %+f %+f- %+lld - %d",
259149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            s->data[0], s->data[1], s->data[2], s->data[3], s->timestamp, update);
259249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    return update < 1 ? 0 :1;
259349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
259449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow}
259549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
259649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chowint MPLSensor::enable(int32_t handle, int en)
259749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow{
259849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    VFUNC_LOG;
259949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
260049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    android::String8 sname;
260149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    int what = -1, err = 0;
26024a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    int batchMode = 0;
260349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
260449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    switch (handle) {
260549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    case ID_SC:
260649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow         what = StepCounter;
260749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow         sname = "Step Counter";
260849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow         LOGV_IF(PROCESS_VERBOSE, "HAL:enable - sensor %s (handle %d) %s -> %s",
260949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                sname.string(), handle,
261049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                (mDmpStepCountEnabled? "en": "dis"),
261149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                (en? "en" : "dis"));
261249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        enableDmpPedometer(en, 0);
261349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        mDmpStepCountEnabled = !!en;
261449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        return 0;
261549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    case ID_P:
261649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        sname = "StepDetector";
261749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        LOGV_IF(PROCESS_VERBOSE, "HAL:enable - sensor %s (handle %d) %s -> %s",
261849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                sname.string(), handle,
261949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                (mDmpPedometerEnabled? "en": "dis"),
262049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                (en? "en" : "dis"));
262149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        enableDmpPedometer(en, 1);
262249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        mDmpPedometerEnabled = !!en;
26234a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        batchMode = computeBatchSensorMask(mEnabled, mBatchEnabled);
26244a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        setBatch(batchMode,1);
262549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        return 0;
262649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    case ID_SM:
262749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        sname = "Significant Motion";
262849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        LOGV_IF(PROCESS_VERBOSE, "HAL:enable - sensor %s (handle %d) %s -> %s",
262949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                sname.string(), handle,
263049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                (mDmpSignificantMotionEnabled? "en": "dis"),
263149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                (en? "en" : "dis"));
263249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        enableDmpSignificantMotion(en);
263349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        mDmpSignificantMotionEnabled = !!en;
263449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        return 0;
263549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    case ID_SO:
263649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        sname = "Screen Orientation";
263749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        LOGV_IF(PROCESS_VERBOSE, "HAL:enable - sensor %s (handle %d) %s -> %s",
263849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                sname.string(), handle,
263949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                (mDmpOrientationEnabled? "en": "dis"),
264049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                (en? "en" : "dis"));
264149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        enableDmpOrientation(en && isDmpDisplayOrientationOn());
264249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        mDmpOrientationEnabled = !!en;
264349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        return 0;
264449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    case ID_A:
264549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        what = Accelerometer;
264649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        sname = "Accelerometer";
264749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        break;
264849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    case ID_M:
264949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        what = MagneticField;
265049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        sname = "MagneticField";
265149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        break;
265249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    case ID_RM:
265349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        what = RawMagneticField;
265449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        sname = "MagneticField Uncalibrated";
265549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        break;
265649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    case ID_O:
265749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        what = Orientation;
265849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        sname = "Orientation";
265949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        break;
266049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    case ID_GY:
266149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        what = Gyro;
266249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        sname = "Gyro";
266349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        break;
266449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    case ID_RG:
266549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        what = RawGyro;
266649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        sname = "Gyro Uncalibrated";
266749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        break;
266849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    case ID_GR:
266949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        what = Gravity;
267049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        sname = "Gravity";
267149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        break;
267249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    case ID_RV:
267349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        what = RotationVector;
267449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        sname = "RotationVector";
267549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        break;
267649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    case ID_GRV:
267749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        what = GameRotationVector;
267849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        sname = "GameRotationVector";
267949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        break;
268049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    case ID_LA:
268149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        what = LinearAccel;
268249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        sname = "LinearAccel";
268349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        break;
268449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    case ID_GMRV:
268549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        what = GeomagneticRotationVector;
268649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        sname = "GeomagneticRotationVector";
268749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        break;
268849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    case ID_PS:
268949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        what = Pressure;
269049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        sname = "Pressure";
269149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        break;
269249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    default: //this takes care of all the gestures
269349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        what = handle;
269449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        sname = "Others";
269549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        break;
269649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    }
269749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
269849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    if (uint32_t(what) >= NumSensors)
269949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        return -EINVAL;
270049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
270149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    int newState = en ? 1 : 0;
270249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    unsigned long sen_mask;
270349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
270449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    LOGV_IF(PROCESS_VERBOSE, "HAL:enable - sensor %s (handle %d) %s -> %s",
270549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            sname.string(), handle,
270649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            ((mEnabled & (1 << what)) ? "en" : "dis"),
270749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            ((uint32_t(newState) << what) ? "en" : "dis"));
270849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    LOGV_IF(PROCESS_VERBOSE,
270949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            "HAL:%s sensor state change what=%d", sname.string(), what);
271049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
271149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    // pthread_mutex_lock(&mMplMutex);
271249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    // pthread_mutex_lock(&mHALMutex);
271349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
271449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    if ((uint32_t(newState) << what) != (mEnabled & (1 << what))) {
271549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        uint32_t sensor_type;
271649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        short flags = newState;
271749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        uint32_t lastEnabled = mEnabled, changed = 0;
271849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
271949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        mEnabled &= ~(1 << what);
272049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        mEnabled |= (uint32_t(flags) << what);
272149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
272249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        LOGV_IF(PROCESS_VERBOSE, "HAL:handle = %d", handle);
272349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        LOGV_IF(PROCESS_VERBOSE, "HAL:flags = %d", flags);
272449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        computeLocalSensorMask(mEnabled);
272549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        LOGV_IF(PROCESS_VERBOSE, "HAL:enable : mEnabled = %d", mEnabled);
272649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        LOGV_IF(ENG_VERBOSE, "HAL:last enable : lastEnabled = %d", lastEnabled);
272749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        sen_mask = mLocalSensorMask & mMasterSensorMask;
272849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        mSensorMask = sen_mask;
272949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        LOGV_IF(PROCESS_VERBOSE, "HAL:sen_mask= 0x%0lx", sen_mask);
273049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
273149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        switch (what) {
273249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            case Gyro:
273349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            case RawGyro:
273449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            case Accelerometer:
273549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                if ((!(mEnabled & VIRTUAL_SENSOR_GYRO_6AXES_MASK) &&
273649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                    !(mEnabled & VIRTUAL_SENSOR_9AXES_MASK)) &&
273749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                    ((lastEnabled & (1 << what)) != (mEnabled & (1 << what)))) {
273849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                    changed |= (1 << what);
273949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                }
27404a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                if (mFeatureActiveMask & INV_DMP_6AXIS_QUATERNION) {
27414a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                     changed |= (1 << what);
27424a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                }
274349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                break;
274449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            case MagneticField:
274549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            case RawMagneticField:
274649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                if (!(mEnabled & VIRTUAL_SENSOR_9AXES_MASK) &&
274749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                    ((lastEnabled & (1 << what)) != (mEnabled & (1 << what)))) {
274849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                    changed |= (1 << what);
274949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                }
275049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                break;
275149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            case Pressure:
275249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                if ((lastEnabled & (1 << what)) != (mEnabled & (1 << what))) {
275349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                    changed |= (1 << what);
275449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                }
275549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                break;
275649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            case GameRotationVector:
275749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                if (!en)
275849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                    storeCalibration();
275949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                if ((en && !(lastEnabled & VIRTUAL_SENSOR_ALL_MASK))
276049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                         ||
276149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                    (en && !(lastEnabled & VIRTUAL_SENSOR_9AXES_MASK))
276249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                         ||
276349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                    (!en && !(mEnabled & VIRTUAL_SENSOR_ALL_MASK))
276449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                         ||
276549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                    (!en && (mEnabled & VIRTUAL_SENSOR_MAG_6AXES_MASK))) {
276649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                    for (int i = Gyro; i <= RawMagneticField; i++) {
276749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                        if (!(mEnabled & (1 << i))) {
276849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                            changed |= (1 << i);
276949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                        }
277049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                    }
277149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                }
277249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                break;
277349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
277449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            case Orientation:
277549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            case RotationVector:
277649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            case LinearAccel:
277749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            case Gravity:
277849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                if (!en)
277949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                    storeCalibration();
278049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                if ((en && !(lastEnabled & VIRTUAL_SENSOR_9AXES_MASK))
278149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                         ||
278249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                    (!en && !(mEnabled & VIRTUAL_SENSOR_9AXES_MASK))) {
278349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                    for (int i = Gyro; i <= RawMagneticField; i++) {
278449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                        if (!(mEnabled & (1 << i))) {
278549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                            changed |= (1 << i);
278649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                        }
278749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                    }
278849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                }
278949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                break;
279049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            case GeomagneticRotationVector:
279149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                if (!en)
279249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                    storeCalibration();
279349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                if ((en && !(lastEnabled & VIRTUAL_SENSOR_ALL_MASK))
279449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                        ||
279549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                    (en && !(lastEnabled & VIRTUAL_SENSOR_9AXES_MASK))
279649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                         ||
279749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                   (!en && !(mEnabled & VIRTUAL_SENSOR_ALL_MASK))
279849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                         ||
279949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                   (!en && (mEnabled & VIRTUAL_SENSOR_GYRO_6AXES_MASK))) {
280049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                   for (int i = Accelerometer; i <= RawMagneticField; i++) {
280149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                       if (!(mEnabled & (1<<i))) {
280249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                          changed |= (1 << i);
280349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                       }
280449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                   }
280549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                }
280649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                break;
280749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        }
280849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        LOGV_IF(PROCESS_VERBOSE, "HAL:changed = %d", changed);
280949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        enableSensors(sen_mask, flags, changed);
281049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    }
281149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
281249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    // pthread_mutex_unlock(&mMplMutex);
281349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    // pthread_mutex_unlock(&mHALMutex);
281449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
281549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow#ifdef INV_PLAYBACK_DBG
281649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    /* apparently the logging needs to go through this sequence
281749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow       to properly flush the log file */
281849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    inv_turn_off_data_logging();
281949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    fclose(logfile);
282049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    logfile = fopen("/data/playback.bin", "ab");
282149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    if (logfile)
282249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        inv_turn_on_data_logging(logfile);
282349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow#endif
282449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
282549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    return err;
282649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow}
282749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
282849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chowvoid MPLSensor::getHandle(int32_t handle, int &what, android::String8 &sname)
282949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow{
283049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow   VFUNC_LOG;
283149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
283249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow   what = -1;
283349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
283449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow   switch (handle) {
283549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow   case ID_P:
283649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        what = StepDetector;
283749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        sname = "StepDetector";
283849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        break;
283949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow   case ID_SC:
284049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        what = StepCounter;
284149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        sname = "StepCounter";
284249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        break;
284349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow   case ID_SM:
284449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        what = SignificantMotion;
284549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        sname = "SignificantMotion";
284649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        break;
284749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow   case ID_SO:
284849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        what = handle;
284949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        sname = "ScreenOrienation";
285049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow   case ID_A:
285149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        what = Accelerometer;
285249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        sname = "Accelerometer";
285349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        break;
285449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow   case ID_M:
285549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        what = MagneticField;
285649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        sname = "MagneticField";
285749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        break;
285849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow   case ID_RM:
285949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        what = RawMagneticField;
286049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        sname = "MagneticField Uncalibrated";
286149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        break;
286249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow   case ID_O:
286349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        what = Orientation;
286449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        sname = "Orientation";
286549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        break;
286649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow   case ID_GY:
286749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        what = Gyro;
286849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        sname = "Gyro";
286949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        break;
287049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow   case ID_RG:
287149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        what = RawGyro;
287249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        sname = "Gyro Uncalibrated";
287349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        break;
287449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow   case ID_GR:
287549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        what = Gravity;
287649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        sname = "Gravity";
287749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        break;
287849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow   case ID_RV:
287949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        what = RotationVector;
288049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        sname = "RotationVector";
288149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        break;
288249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow   case ID_GRV:
288349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        what = GameRotationVector;
288449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        sname = "GameRotationVector";
288549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        break;
288649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow   case ID_LA:
288749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        what = LinearAccel;
288849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        sname = "LinearAccel";
288949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        break;
289049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow   case ID_PS:
289149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        what = Pressure;
289249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        sname = "Pressure";
289349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        break;
289449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow   default: // this takes care of all the gestures
289549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        what = handle;
289649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        sname = "Others";
289749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        break;
289849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    }
289949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
290049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    LOGI_IF(EXTRA_VERBOSE, "HAL:getHandle - what=%d, sname=%s", what, sname.string());
290149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    return;
290249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow}
290349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
290449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chowint MPLSensor::setDelay(int32_t handle, int64_t ns)
290549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow{
290649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    VFUNC_LOG;
290749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
290849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    android::String8 sname;
290949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    int what = -1;
291049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
291149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow#if 0
291249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    // skip the 1st call for enalbing sensors called by ICS/JB sensor service
291349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    static int counter_delay = 0;
291449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    if (!(mEnabled & (1 << what))) {
291549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        counter_delay = 0;
291649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    } else {
291749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        if (++counter_delay == 1) {
291849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            return 0;
291949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        }
292049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        else {
292149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            counter_delay = 0;
292249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        }
292349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    }
292449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow#endif
292549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
292649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    getHandle(handle, what, sname);
292749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    if (uint32_t(what) >= NumSensors)
292849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        return -EINVAL;
292949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
293049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    if (ns < 0)
293149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        return -EINVAL;
293249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
293349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    LOGV_IF(PROCESS_VERBOSE,
293449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            "setDelay : %llu ns, (%.2f Hz)", ns, 1000000000.f / ns);
293549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
293649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    // limit all rates to reasonable ones */
293749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    if (ns < 5000000LL) {
293849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        ns = 5000000LL;
293949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    }
294049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
294149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    /* store request rate to mDelays arrary for each sensor */
294249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    mDelays[what] = ns;
294349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
294449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    switch (what) {
294549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        case ID_SC:
294649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            /* set limits of delivery rate of events */
294749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            mStepCountPollTime = ns;
294849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            LOGV_IF(ENG_VERBOSE, "step count rate =%lld ns", ns);
294949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            break;
295049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        case ID_P:
295149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        case SignificantMotion:
295249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        case ID_SO:
295349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            update_delay();
295449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            break;
295549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        case Gyro:
295649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        case RawGyro:
295749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        case Accelerometer:
295849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            for (int i = Gyro;
295949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                    i <= Accelerometer + mCompassSensor->isIntegrated();
296049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                    i++) {
296149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                if (i != what && (mEnabled & (1 << i)) && ns > mDelays[i]) {
296249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                    LOGV_IF(PROCESS_VERBOSE,
296349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                            "HAL:ignore delay set due to sensor %d", i);
296449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                    return 0;
296549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                }
296649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            }
296749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            break;
296849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
296949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        case MagneticField:
297049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        case RawMagneticField:
297149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            if (mCompassSensor->isIntegrated() &&
297249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                    (((mEnabled & (1 << Gyro)) && ns > mDelays[Gyro]) ||
297349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                    ((mEnabled & (1 << RawGyro)) && ns > mDelays[RawGyro]) ||
297449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                    ((mEnabled & (1 << Accelerometer)) &&
297549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                        ns > mDelays[Accelerometer]))) {
297649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                 LOGV_IF(PROCESS_VERBOSE,
297749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                         "HAL:ignore delay set due to gyro/accel");
297849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                 return 0;
297949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            }
298049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            break;
298149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
298249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        case Orientation:
298349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        case RotationVector:
298449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        case GameRotationVector:
298549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        case GeomagneticRotationVector:
298649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        case LinearAccel:
298749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        case Gravity:
298849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            if (isLowPowerQuatEnabled()) {
298949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                LOGV_IF(PROCESS_VERBOSE,
299049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                        "HAL:need to update delay due to LPQ");
299149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                break;
299249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            }
299349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
299449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            for (int i = 0; i < NumSensors; i++) {
299549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                if (i != what && (mEnabled & (1 << i)) && ns > mDelays[i]) {
299649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                    LOGV_IF(PROCESS_VERBOSE,
299749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                            "HAL:ignore delay set due to sensor %d", i);
299849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                    return 0;
299949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                }
300049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            }
300149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            break;
300249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    }
300349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
300449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    // pthread_mutex_lock(&mHALMutex);
300549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    int res = update_delay();
300649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    // pthread_mutex_unlock(&mHALMutex);
300749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    return res;
300849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow}
300949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
301049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chowint MPLSensor::update_delay(void)
301149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow{
301249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    VHANDLER_LOG;
301349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
301449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    int res = 0;
301549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    int64_t got;
301649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
301749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    if (mEnabled) {
301849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        int64_t wanted = 1000000000LL;
301949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        int64_t wanted_3rd_party_sensor = 1000000000LL;
302049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
302149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        // Sequence to change sensor's FIFO rate
302249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        // 1. reset master enable
302349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        // 2. Update delay
302449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        // 3. set master enable
302549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
302649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        // reset master enable
302749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        masterEnable(0);
302849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
30294a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        int64_t gyroRate;
30304a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        int64_t accelRate;
30314a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        int64_t compassRate;
30324a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        int64_t pressureRate;
30334a28f9c897c46c42a255823f7e307169a828a025Rosa Chow
30344a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        int rateInus;
30354a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        int mplGyroRate;
30364a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        int mplAccelRate;
30374a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        int mplCompassRate;
30384a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        int tempRate = wanted;
30394a28f9c897c46c42a255823f7e307169a828a025Rosa Chow
304049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        /* search the minimum delay requested across all enabled sensors */
304149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        for (int i = 0; i < NumSensors; i++) {
304249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            if (mEnabled & (1 << i)) {
304349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                int64_t ns = mDelays[i];
304449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                wanted = wanted < ns ? wanted : ns;
304549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            }
304649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        }
30474a28f9c897c46c42a255823f7e307169a828a025Rosa Chow
30484a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        if (mDmpOn) {
30494a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            gyroRate = mDelays[Gyro] < mDelays[RawGyro] ? mDelays[Gyro] : mDelays[RawGyro];
30504a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            accelRate = mDelays[Accelerometer];
30514a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            compassRate = mDelays[MagneticField] < mDelays[RawMagneticField] ? mDelays[MagneticField] : mDelays[RawMagneticField];
30524a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            pressureRate = mDelays[Pressure];
30534a28f9c897c46c42a255823f7e307169a828a025Rosa Chow
30544a28f9c897c46c42a255823f7e307169a828a025Rosa Chow#ifdef ENABLE_MULTI_RATE
30554a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            gyroRate = wanted;
30564a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            accelRate = wanted;
30574a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            compassRate = wanted;
30584a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            pressureRate = wanted;
30594a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            // same delay for 3rd party Accel or Compass
30604a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            wanted_3rd_party_sensor = wanted;
30614a28f9c897c46c42a255823f7e307169a828a025Rosa Chow#endif
30624a28f9c897c46c42a255823f7e307169a828a025Rosa Chow
30634a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        }
30644a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        else {
30654a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            gyroRate = wanted;
30664a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            accelRate = wanted;
30674a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            compassRate = wanted;
30684a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            pressureRate = wanted;
30694a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            // same delay for 3rd party Accel or Compass
30704a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            wanted_3rd_party_sensor = wanted;
30714a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        }
30724a28f9c897c46c42a255823f7e307169a828a025Rosa Chow
307349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        /* mpl rate in us in future maybe different for
307449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow           gyro vs compass vs accel */
30754a28f9c897c46c42a255823f7e307169a828a025Rosa Chow /*       rateInus = (int)wanted / 1000LL;
30764a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        mplGyroRate = (int)gyroRate / 1000LL;
30774a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        mplAccelRate = (int)accelRate / 1000LL;
30784a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        mplCompassRate = (int)compassRate / 1000LL;
30794a28f9c897c46c42a255823f7e307169a828a025Rosa Chow
308049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        LOGV_IF(PROCESS_VERBOSE, "HAL:wanted rate for all sensors : "
308149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow             "%llu ns, mpl rate: %d us, (%.2f Hz)",
308249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow             wanted, rateInus, 1000000000.f / wanted);
308349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
308449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        /* set rate in MPL */
308549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        /* compass can only do 100Hz max */
30864a28f9c897c46c42a255823f7e307169a828a025Rosa Chow /*       inv_set_gyro_sample_rate(mplGyroRate);
308749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        inv_set_accel_sample_rate(mplAccelRate);
308849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        inv_set_compass_sample_rate(mplCompassRate);
308949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
309049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        LOGV_IF(PROCESS_VERBOSE,
30914a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                "HAL:MPL gyro sample rate: (mpl)=%d us (mpu)=%.2f Hz", mplGyroRate, 1000000000.f / gyroRate);
309249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        LOGV_IF(PROCESS_VERBOSE,
30934a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                "HAL:MPL accel sample rate: (mpl)=%d us (mpu)=%.2f Hz", mplAccelRate, 1000000000.f / accelRate);
309449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        LOGV_IF(PROCESS_VERBOSE,
30954a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                "HAL:MPL compass sample rate: (mpl)=%d us (mpu)=%.2f Hz", mplCompassRate, 1000000000.f / compassRate);
30964a28f9c897c46c42a255823f7e307169a828a025Rosa Chow*/
309749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        int enabled_sensors = mEnabled;
309849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        int tempFd = -1;
30994a28f9c897c46c42a255823f7e307169a828a025Rosa Chow
31004a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        if(mFeatureActiveMask & INV_DMP_BATCH_MODE) {
31014a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            // set batch rates
31024a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            LOGV_IF(ENG_VERBOSE, "HAL: mFeatureActiveMask=%016llx", mFeatureActiveMask);
31034a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            LOGV("HAL: batch mode is set, set batch data rates");
31044a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            if (setBatchDataRates() < 0) {
31054a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                LOGE("HAL:ERR can't set batch data rates");
31064a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            }
31074a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        } else {
310849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        if (LA_ENABLED || GR_ENABLED || RV_ENABLED
310949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                       || GRV_ENABLED || O_ENABLED || GMRV_ENABLED) {
311049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            LOGV_IF(ENG_VERBOSE, "mFeatureActiveMask=%016llx", mFeatureActiveMask);
311149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            //TODO: may be able to combine DMP_FEATURE_MASK, DMP_SENSOR_MASK in the future
311249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            if(mFeatureActiveMask & DMP_FEATURE_MASK) {
311349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                bool setDMPrate= 0;
31144a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                gyroRate = wanted;
31154a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                accelRate = wanted;
31164a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                compassRate = wanted;
31174a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                // same delay for 3rd party Accel or Compass
31184a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                wanted_3rd_party_sensor = wanted;
31194a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                rateInus = (int)wanted / 1000LL;
31204a28f9c897c46c42a255823f7e307169a828a025Rosa Chow
31214a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                 /* set rate in MPL */
31224a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                 /* compass can only do 100Hz max */
31234a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                 inv_set_gyro_sample_rate(rateInus);
31244a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                 inv_set_accel_sample_rate(rateInus);
31254a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                 inv_set_compass_sample_rate(rateInus);
31264a28f9c897c46c42a255823f7e307169a828a025Rosa Chow
31274a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                 LOGV_IF(PROCESS_VERBOSE,
31284a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                "HAL:MPL gyro sample rate: (mpl)=%d us (mpu)=%.2f Hz", rateInus, 1000000000.f / gyroRate);
31294a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                 LOGV_IF(PROCESS_VERBOSE,
31304a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                "HAL:MPL accel sample rate: (mpl)=%d us (mpu)=%.2f Hz", rateInus, 1000000000.f / accelRate);
31314a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                 LOGV_IF(PROCESS_VERBOSE,
31324a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                "HAL:MPL compass sample rate: (mpl)=%d us (mpu)=%.2f Hz", rateInus, 1000000000.f / compassRate);
31334a28f9c897c46c42a255823f7e307169a828a025Rosa Chow
313449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                // Set LP Quaternion sample rate if enabled
313549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                if (checkLPQuaternion()) {
313649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                    if (wanted <= RATE_200HZ) {
31374a28f9c897c46c42a255823f7e307169a828a025Rosa Chow#ifndef USE_LPQ_AT_FASTEST
313849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                        enableLPQuaternion(0);
313949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow#endif
314049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                    } else {
314149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                        inv_set_quat_sample_rate(rateInus);
314249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                        setDMPrate= 1;
314349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                    }
314449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                }
31454a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                //if((mFeatureActiveMask & DMP_SENSOR_MASK) || setDMPrate==1) {
31464a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                //    getDmpRate(&wanted);
31474a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                //}
314849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            }
314949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
315049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            LOGV_IF(EXTRA_VERBOSE, "HAL:setDelay - Fusion");
315149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            //nsToHz
315249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %.0f > %s (%lld)",
31534a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                    1000000000.f / gyroRate, mpu.gyro_rate,
315449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                    getTimestamp());
31554a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            tempFd = open(mpu.gyro_rate, O_RDWR);
31564a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            res = write_attribute_sensor(tempFd, 1000000000.f / gyroRate);
315749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            if(res < 0) {
315849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                LOGE("HAL:GYRO update delay error");
315949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            }
316049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
316149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            if(USE_THIRD_PARTY_ACCEL == 1) {
31624a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            // 3rd party accelerometer - if applicable
31634a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            // nsToHz (BMA250)
316449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                LOGV_IF(SYSFS_VERBOSE, "echo %lld > %s (%lld)",
31654a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                        wanted_3rd_party_sensor / 1000000L, mpu.accel_rate,
316649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                        getTimestamp());
31674a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                tempFd = open(mpu.accel_rate, O_RDWR);
316849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                res = write_attribute_sensor(tempFd,
316949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                        wanted_3rd_party_sensor / 1000000L);
317049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                LOGE_IF(res < 0, "HAL:ACCEL update delay error");
31714a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            } else {
31724a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            // mpu accel
31734a28f9c897c46c42a255823f7e307169a828a025Rosa Chow               LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %.0f > %s (%lld)",
31744a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                        1000000000.f / accelRate, mpu.accel_rate,
31754a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                        getTimestamp());
31764a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                tempFd = open(mpu.accel_rate, O_RDWR);
31774a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                res = write_attribute_sensor(tempFd, 1000000000.f / accelRate);
31784a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                LOGE_IF(res < 0, "HAL:ACCEL update delay error");
317949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            }
318049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
318149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            if (!mCompassSensor->isIntegrated()) {
31824a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            // stand-alone compass - if applicable
318349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                LOGV_IF(PROCESS_VERBOSE,
318449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                        "HAL:Ext compass delay %lld", wanted_3rd_party_sensor);
318549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                LOGV_IF(PROCESS_VERBOSE, "HAL:Ext compass rate %.2f Hz",
318649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                        1000000000.f / wanted_3rd_party_sensor);
318749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                if (wanted_3rd_party_sensor <
318849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                        mCompassSensor->getMinDelay() * 1000LL) {
318949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                    wanted_3rd_party_sensor =
319049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                        mCompassSensor->getMinDelay() * 1000LL;
319149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                }
319249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                LOGV_IF(PROCESS_VERBOSE,
319349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                        "HAL:Ext compass delay %lld", wanted_3rd_party_sensor);
319449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                LOGV_IF(PROCESS_VERBOSE, "HAL:Ext compass rate %.2f Hz",
319549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                        1000000000.f / wanted_3rd_party_sensor);
319649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                mCompassSensor->setDelay(ID_M, wanted_3rd_party_sensor);
319749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                got = mCompassSensor->getDelay(ID_M);
319849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                inv_set_compass_sample_rate(got / 1000);
31994a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            } else {
32004a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            // compass on secondary bus
32014a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                if (compassRate < mCompassSensor->getMinDelay() * 1000LL) {
32024a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                    compassRate = mCompassSensor->getMinDelay() * 1000LL;
32034a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                }
32044a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                mCompassSensor->setDelay(ID_M, compassRate);
320549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            }
320649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
320749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            /*
320849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            //nsTons - nothing to be done
320949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            strcpy(&compass_sensor_sysfs_path[compass_sensor_sysfs_path_len],
321049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                   COMPASS_SENSOR_DELAY);
321149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            tempFd = open(compass_sensor_sysfs_path, O_RDWR);
321249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            LOGV_IF(PROCESS_VERBOSE,
321349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                    "setDelay - open path: %s", compass_sensor_sysfs_path);
321449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            wanted = 20000000LLU;
321549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            res = write_attribute_sensor(tempFd, wanted);
321649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            if(res < 0) {
321749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                LOGE("Compass update delay error");
321849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            }
321949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            */
322049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
322149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        } else {
322249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
322349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            if (GY_ENABLED || RGY_ENABLED) {
322449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                wanted = (mDelays[Gyro] <= mDelays[RawGyro]?
322549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                    (mEnabled & (1 << Gyro)? mDelays[Gyro]: mDelays[RawGyro]):
322649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                    (mEnabled & (1 << RawGyro)? mDelays[RawGyro]: mDelays[Gyro]));
322749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                LOGV_IF(ENG_VERBOSE, "mFeatureActiveMask=%016llx", mFeatureActiveMask);
322849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                if (mFeatureActiveMask & DMP_FEATURE_MASK) {
32294a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                    //int64_t tempWanted;
32304a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                    //getDmpRate(&tempWanted);
323149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                }
323249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
32334a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                inv_set_gyro_sample_rate((int)wanted/1000LL);
32344a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                LOGV_IF(PROCESS_VERBOSE,
32354a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                    "HAL:MPL gyro sample rate: (mpl)=%d us", int(wanted/1000LL));
323649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %.0f > %s (%lld)",
32374a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                        1000000000.f / wanted, mpu.gyro_rate, getTimestamp());
32384a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                tempFd = open(mpu.gyro_rate, O_RDWR);
323949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                res = write_attribute_sensor(tempFd, 1000000000.f / wanted);
324049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                LOGE_IF(res < 0, "HAL:GYRO update delay error");
324149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            }
324249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
324349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            if (A_ENABLED) { /* there is only 1 fifo rate for MPUxxxx */
32444a28f9c897c46c42a255823f7e307169a828a025Rosa Chow
32454a28f9c897c46c42a255823f7e307169a828a025Rosa Chow#if (0)
32464a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                wanted = mDelays[Accelerometer];
32474a28f9c897c46c42a255823f7e307169a828a025Rosa Chow#else
324849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                if (GY_ENABLED && mDelays[Gyro] < mDelays[Accelerometer]) {
324949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                    wanted = mDelays[Gyro];
325049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                } else if (RGY_ENABLED && mDelays[RawGyro]
325149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                            < mDelays[Accelerometer]) {
325249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                    wanted = mDelays[RawGyro];
325349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                } else {
325449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                    wanted = mDelays[Accelerometer];
325549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                }
32564a28f9c897c46c42a255823f7e307169a828a025Rosa Chow#endif
325749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                LOGV_IF(ENG_VERBOSE, "mFeatureActiveMask=%016llx", mFeatureActiveMask);
325849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                if (mFeatureActiveMask & DMP_FEATURE_MASK) {
32594a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                    //int64_t tempWanted;
32604a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                    //getDmpRate(&tempWanted);
326149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                }
326249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
32634a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                inv_set_accel_sample_rate((int)wanted/1000LL);
32644a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                LOGV_IF(PROCESS_VERBOSE,
32654a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                    "HAL:MPL accel sample rate: (mpl)=%d us", int(wanted/1000LL));
326649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                /* TODO: use function pointers to calculate delay value specific
326749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                   to vendor */
326849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %.0f > %s (%lld)",
32694a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                        1000000000.f / wanted, mpu.accel_rate,
327049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                        getTimestamp());
32714a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                tempFd = open(mpu.accel_rate, O_RDWR);
327249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                if(USE_THIRD_PARTY_ACCEL == 1) {
327349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                    //BMA250 in ms
327449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                    res = write_attribute_sensor(tempFd, wanted / 1000000L);
327549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                }
327649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                else {
327749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                    //MPUxxxx in hz
327849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                    res = write_attribute_sensor(tempFd, 1000000000.f/wanted);
327949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                }
328049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                LOGE_IF(res < 0, "HAL:ACCEL update delay error");
328149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            }
328249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
328349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            /* Invensense compass calibration */
328449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            if (M_ENABLED || RM_ENABLED) {
328549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                int64_t compassWanted = (mDelays[MagneticField] <= mDelays[RawMagneticField]?
328649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                    (mEnabled & (1 << MagneticField)? mDelays[MagneticField]: mDelays[RawMagneticField]):
328749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                    (mEnabled & (1 << RawMagneticField)? mDelays[RawMagneticField]: mDelays[MagneticField]));
328849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                if (!mCompassSensor->isIntegrated()) {
328949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                    wanted = compassWanted;
329049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                } else {
32914a28f9c897c46c42a255823f7e307169a828a025Rosa Chow#if (0)
32924a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                    wanted = compassWanted;
32934a28f9c897c46c42a255823f7e307169a828a025Rosa Chow#else
329449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                    if (GY_ENABLED
329549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                        && (mDelays[Gyro] < compassWanted)) {
329649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                        wanted = mDelays[Gyro];
329749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                    } else if (RGY_ENABLED
329849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                               && mDelays[RawGyro] < compassWanted) {
329949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                        wanted = mDelays[RawGyro];
330049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                    } else if (A_ENABLED && mDelays[Accelerometer]
330149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                                < compassWanted) {
330249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                        wanted = mDelays[Accelerometer];
330349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                    } else {
330449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                        wanted = compassWanted;
330549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                    }
33064a28f9c897c46c42a255823f7e307169a828a025Rosa Chow#endif
330749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                    LOGV_IF(ENG_VERBOSE, "mFeatureActiveMask=%016llx", mFeatureActiveMask);
330849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                    if (mFeatureActiveMask & DMP_FEATURE_MASK) {
33094a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                        //int64_t tempWanted;
33104a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                        //getDmpRate(&tempWanted);
331149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                    }
331249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                }
331349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
331449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                mCompassSensor->setDelay(ID_M, wanted);
331549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                got = mCompassSensor->getDelay(ID_M);
331649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                inv_set_compass_sample_rate(got / 1000);
33174a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                LOGV_IF(PROCESS_VERBOSE,
33184a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                    "HAL:MPL compass sample rate: (mpl)=%d us", int(got/1000LL));
331949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            }
332049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
332149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            if (PS_ENABLED) {
33224a28f9c897c46c42a255823f7e307169a828a025Rosa Chow#if (0)
33234a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                wanted = mDelays[Pressure];
33244a28f9c897c46c42a255823f7e307169a828a025Rosa Chow#else
33254a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                wanted = mDelays[Pressure];
33264a28f9c897c46c42a255823f7e307169a828a025Rosa Chow#endif
332749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                LOGV_IF(ENG_VERBOSE, "mFeatureActiveMask=%016llx", mFeatureActiveMask);
332849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                if (mFeatureActiveMask & DMP_FEATURE_MASK) {
33294a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                    //int64_t tempWanted;
33304a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                    //getDmpRate(&tempWanted);
333149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                }
333249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
33332a34df3e7851e7af4095fda80700562af17c4e28Vineeta Srivastava                if (mPressureSensor) {
33342a34df3e7851e7af4095fda80700562af17c4e28Vineeta Srivastava                    mPressureSensor->setDelay(ID_PS, wanted);
33352a34df3e7851e7af4095fda80700562af17c4e28Vineeta Srivastava                } else {
33362a34df3e7851e7af4095fda80700562af17c4e28Vineeta Srivastava                    LOGV_IF(ENG_VERBOSE, "HAL:PRESSURE sensor not detected");
33372a34df3e7851e7af4095fda80700562af17c4e28Vineeta Srivastava                }
333849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                LOGE_IF(res < 0, "HAL:PRESSURE update delay error");
333949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            }
334049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        }
334149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
33424a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        /* set master sampling frequency */
33434a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        /* only use for non multi rate */
33444a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        int64_t tempWanted = wanted;
33454a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        getDmpRate(&tempWanted);
33464a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        /* driver only looks at sampling frequency if DMP is off */
33474a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %.0f > %s (%lld)",
33484a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                1000000000.f / tempWanted, mpu.gyro_fifo_rate, getTimestamp());
33494a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        tempFd = open(mpu.gyro_fifo_rate, O_RDWR);
33504a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        res = write_attribute_sensor(tempFd, 1000000000.f / tempWanted);
33514a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            LOGE_IF(res < 0, "HAL:sampling frequency update delay error");
33524a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        } //end of non batch mode
33534a28f9c897c46c42a255823f7e307169a828a025Rosa Chow
335449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        unsigned long sensors = mLocalSensorMask & mMasterSensorMask;
335549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        if (sensors &
335649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            (INV_THREE_AXIS_GYRO
335749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                | INV_THREE_AXIS_ACCEL
335849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                | (INV_THREE_AXIS_COMPASS * mCompassSensor->isIntegrated()
335949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                | (INV_ONE_AXIS_PRESSURE * mPressureSensor->isIntegrated())))) {
33604a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            LOGV_IF(ENG_VERBOSE, "sensors=%lu", sensors);
336149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            res = masterEnable(1);
336249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            if(res < 0)
336349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                return res;
336449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        } else { // all sensors idle -> reduce power, unless DMP is needed
336549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            LOGV_IF(ENG_VERBOSE, "mFeatureActiveMask=%016llx", mFeatureActiveMask);
336649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            if(mFeatureActiveMask & DMP_FEATURE_MASK) {
336749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                res = masterEnable(1);
336849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                if(res < 0)
336949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                    return res;
337049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            }
337149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        }
337249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    }
337349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
337449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    return res;
337549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow}
337649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
337749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow/* For Third Party Accel Input Subsystem Drivers only */
337849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chowint MPLSensor::readAccelEvents(sensors_event_t* data, int count)
337949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow{
338049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    VHANDLER_LOG;
338149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
338249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    if (count < 1)
338349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        return -EINVAL;
338449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
338549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    ssize_t n = mAccelInputReader.fill(accel_fd);
338649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    if (n < 0) {
338749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        LOGE("HAL:missed accel events, exit");
338849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        return n;
338949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    }
339049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
339149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    int numEventReceived = 0;
339249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    input_event const* event;
339349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    int nb, done = 0;
339449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
339549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    while (done == 0 && count && mAccelInputReader.readEvent(&event)) {
339649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        int type = event->type;
339749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        if (type == EV_ABS) {
339849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            if (event->code == EVENT_TYPE_ACCEL_X) {
339949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                mPendingMask |= 1 << Accelerometer;
340049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                mCachedAccelData[0] = event->value;
340149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            } else if (event->code == EVENT_TYPE_ACCEL_Y) {
340249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                mPendingMask |= 1 << Accelerometer;
340349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                mCachedAccelData[1] = event->value;
340449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            } else if (event->code == EVENT_TYPE_ACCEL_Z) {
340549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                mPendingMask |= 1 << Accelerometer;
340649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                mCachedAccelData[2] =event-> value;
340749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            }
340849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        } else if (type == EV_SYN) {
340949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            done = 1;
341049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            if (mLocalSensorMask & INV_THREE_AXIS_ACCEL) {
341149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                inv_build_accel(mCachedAccelData, 0, getTimestamp());
341249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            }
341349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        } else {
341449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            LOGE("HAL:AccelSensor: unknown event (type=%d, code=%d)",
341549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                    type, event->code);
341649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        }
341749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        mAccelInputReader.next();
341849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    }
341949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
342049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    return numEventReceived;
342149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow}
342249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
342349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow/**
342449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow *  Should be called after reading at least one of gyro
342549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow *  compass or accel data. (Also okay for handling all of them).
342649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow *  @returns 0, if successful, error number if not.
342749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow */
342849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chowint MPLSensor::readEvents(sensors_event_t* data, int count)
342949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow{
343049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    //VFUNC_LOG;
343149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
343249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    inv_execute_on_data();
343349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
343449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    int numEventReceived = 0;
343549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
343649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    long msg;
343749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    msg = inv_get_message_level_0(1);
343849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    if (msg) {
343949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        if (msg & INV_MSG_MOTION_EVENT) {
344049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            LOGV_IF(PROCESS_VERBOSE, "HAL:**** Motion ****\n");
344149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        }
344249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        if (msg & INV_MSG_NO_MOTION_EVENT) {
344349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            LOGV_IF(PROCESS_VERBOSE, "HAL:***** No Motion *****\n");
344449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            /* after the first no motion, the gyro should be
344549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow               calibrated well */
344649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            mGyroAccuracy = SENSOR_STATUS_ACCURACY_HIGH;
344749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            /* if gyros are on and we got a no motion, set a flag
344849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow               indicating that the cal file can be written. */
344949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            mHaveGoodMpuCal = true;
345049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        }
345149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        if(msg & INV_MSG_NEW_AB_EVENT) {
345249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            getAccelBias();
345349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            mAccelAccuracy = inv_get_accel_accuracy();
345449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        }
345549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        if(msg & INV_MSG_NEW_GB_EVENT) {
345649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            getGyroBias();
345749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        }
345849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        if(msg & INV_MSG_NEW_FGB_EVENT) {
345949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            getFactoryGyroBias();
346049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        }
346149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        if(msg & INV_MSG_NEW_CB_EVENT) {
346249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            getCompassBias();
346349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            mCompassAccuracy = inv_get_mag_accuracy();
346449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        }
346549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    }
346649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
346749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    for (int i = 0; i < NumSensors; i++) {
346849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        int update = 0;
346949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        // handle step detector when ped_q is enabled
347049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        if ((i == StepDetector) && (mPedUpdate == 1)) {
347149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            mPedUpdate = 0;
347249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            update = readDmpPedometerEvents(data, count, ID_P, SENSOR_TYPE_STEP_DETECTOR, 1);
347349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            if(update == 1 && count > 0) {
34744a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                data->timestamp = mStepSensorTimestamp;
347549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                //LOGI("sensor=%d type=%d data=%d", data->sensor, data->type, data->data[0]);
347649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                count--;
347749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                numEventReceived++;
347849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                continue;
347949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            }
348049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        }
348149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
348249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        // load up virtual sensors
348349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        if (mEnabled & (1 << i)) {
348449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            update = CALL_MEMBER_FN(this, mHandlers[i])(mPendingEvents + i);
348549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            mPendingMask |= (1 << i);
348649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
348749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            if (update && (count > 0)) {
348849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                *data++ = mPendingEvents[i];
348949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                count--;
349049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                numEventReceived++;
349149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            }
349249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        }
349349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    }
349449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
349549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    return numEventReceived;
349649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow}
349749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
349849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow// collect data for MPL (but NOT sensor service currently), from driver layer
349949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chowvoid MPLSensor::buildMpuEvent(void)
350049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow{
35014a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    int64_t mGyroSensorTimestamp=0, mAccelSensorTimestamp=0, latestTimestamp=0;
350249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    int lp_quaternion_on = 0, sixAxis_quaternion_on = 0,
35034a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        ped_quaternion_on = 0, ped_standalone_on = 0;
350449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    size_t nbyte;
350549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    unsigned short data_format = 0;
350649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    int i, nb, mask = 0,
350749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        sensors = ((mLocalSensorMask & INV_THREE_AXIS_GYRO)? 1 : 0) +
350849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            ((mLocalSensorMask & INV_THREE_AXIS_ACCEL)? 1 : 0) +
350949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            (((mLocalSensorMask & INV_THREE_AXIS_COMPASS)
351049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                && mCompassSensor->isIntegrated())? 1 : 0) +
351149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            ((mLocalSensorMask & INV_ONE_AXIS_PRESSURE)? 1 : 0);
35124a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    //LOGV("mLocalSensorMask=0x%lx", mLocalSensorMask);
351349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    char *rdata = mIIOBuffer;
35144a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    ssize_t rsize = 0;
35154a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    size_t readCounter = 0;
35164a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    char *rdataP = NULL;
351749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
351849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    /* 2 Bytes header + 6 Bytes x,y,z data | 8 bytes timestamp */
351949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    nbyte= (BYTES_PER_SENSOR + 8) * sensors * 1;
352049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
352149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    /* special case for 6 Axis or LPQ */
352249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    /* 2 Bytes header + 4 Bytes x data + 2 Bytes n/a */
352349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    /* 4 Bytes y data | 4 Bytes z data */
352449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    /* 8 Bytes timestamp */
352549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    if (isLowPowerQuatEnabled()) {
352649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        lp_quaternion_on = checkLPQuaternion();
352749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        if (lp_quaternion_on == 1) {
352849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            nbyte += BYTES_QUAT_DATA;
352949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        }
353049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    }
353149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
353249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    if ((sixAxis_quaternion_on = check6AxisQuatEnabled())) {
353349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        // sixAxis is mutually exclusive to LPQ
353449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        // and it is also never enabled when continuous data is enabled
353549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        // mLocalSensorMask does not need to be accounted for here
353649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        // because accel/gyro are turned off anyway
35374a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        nbyte += BYTES_QUAT_DATA;
353849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    }
353949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
354049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    if ((ped_quaternion_on = checkPedQuatEnabled())) {
354149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        nbyte += BYTES_PER_SENSOR_PACKET;
354249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    }
354349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
35444a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    if ((ped_standalone_on = checkPedStandaloneEnabled())) {
35454a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        nbyte += BYTES_PER_SENSOR_PACKET;
35464a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    }
35474a28f9c897c46c42a255823f7e307169a828a025Rosa Chow
35484a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    /* check previous copied buffer */
35494a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    /* append with just read data */
35504a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    if (mLeftOverBufferSize > 0) {
35514a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        LOGV_IF(0, "append old buffer size=%d", mLeftOverBufferSize);
35524a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        memcpy(rdata, mLeftOverBuffer, mLeftOverBufferSize);
35534a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            LOGV_IF(0,
35544a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            "HAL:input retrieve rdata=:%d, %d, %d, %d,%d, %d, %d, %d,%d, %d, "
35554a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            "%d, %d,%d, %d, %d, %d\n",
35564a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            rdata[0], rdata[1], rdata[2], rdata[3],
35574a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            rdata[4], rdata[5], rdata[6], rdata[7],
35584a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            rdata[8], rdata[9], rdata[10], rdata[11],
35594a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            rdata[12], rdata[13], rdata[14], rdata[15]);
35604a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    }
35614a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    rdataP = rdata + mLeftOverBufferSize;
35624a28f9c897c46c42a255823f7e307169a828a025Rosa Chow
35634a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    /* read expected  number of bytes */
35644a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    rsize =  read(iio_fd, rdataP, nbyte);
356549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    if(rsize < 0) {
35664a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        /* IIO buffer might have old data.
35674a28f9c897c46c42a255823f7e307169a828a025Rosa Chow           Need to flush it when enabling no sensors, to avoid infinite
35684a28f9c897c46c42a255823f7e307169a828a025Rosa Chow           read loop.*/
35694a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        LOGE("HAL:input data file descriptor not available - (%s)",
35704a28f9c897c46c42a255823f7e307169a828a025Rosa Chow             strerror(errno));
35714a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        if (sensors == 0) {
35724a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            rsize = read(iio_fd, rdata, MAX_SUSPEND_BATCH_PACKET_SIZE);
35734a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        }
357449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        return;
357549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    }
357649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
35774a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    /* reset data and count pointer */
35784a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    rdataP = rdata;
35794a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    readCounter = rsize + mLeftOverBufferSize;
35804a28f9c897c46c42a255823f7e307169a828a025Rosa Chow
358149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow#ifdef TESTING
35824a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    LOGV_IF(INPUT_DATA,
35834a28f9c897c46c42a255823f7e307169a828a025Rosa Chow         "HAL:input rdataP:r=%ld, n=%d,"
358449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow         "%d, %d, %d, %d,%d, %d, %d, %d,%d, %d, %d, %d,%d, %d, %d, %d\n",
358549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow         rsize, nbyte,
35864a28f9c897c46c42a255823f7e307169a828a025Rosa Chow         rdataP[0], rdataP[1], rdataP[2], rdataP[3],
35874a28f9c897c46c42a255823f7e307169a828a025Rosa Chow         rdataP[4], rdataP[5], rdataP[6], rdataP[7],
35884a28f9c897c46c42a255823f7e307169a828a025Rosa Chow         rdataP[8], rdataP[9], rdataP[10], rdataP[11],
35894a28f9c897c46c42a255823f7e307169a828a025Rosa Chow         rdataP[12], rdataP[13], rdataP[14], rdataP[15]);
359049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow#endif
359149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
35924a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    LOGV_IF(INPUT_DATA && ENG_VERBOSE,
35934a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            "HAL:input rdata= %d nbyte= %d rsize= %ld readCounter= %d",
35944a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            *((short *) rdata), nbyte, rsize, readCounter);
35954a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    LOGV_IF(INPUT_DATA && ENG_VERBOSE,
35964a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            "HAL:input sensors= %d, lp_q_on= %d, 6axis_q_on= %d, "
35974a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            "ped_q_on= %d, ped_standalone_on= %d",
35984a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            sensors, lp_quaternion_on, sixAxis_quaternion_on,
35994a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            ped_quaternion_on, ped_standalone_on);
36004a28f9c897c46c42a255823f7e307169a828a025Rosa Chow
36014a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    while (readCounter > 0) {
36024a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        mLeftOverBufferSize = 0;
36034a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        mask = 0;
360449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        data_format = *((short *)(rdata));
36054a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        LOGV_IF(INPUT_DATA && ENG_VERBOSE,
36064a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                "HAL:input data_format=%x", data_format);
360749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
360849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        if ((data_format & ~DATA_FORMAT_MASK) || (data_format == 0)) {
36094a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            LOGE("HAL:input invalid data_format 0x%02X", data_format);
361049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            return;
361149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        }
36124a28f9c897c46c42a255823f7e307169a828a025Rosa Chow
36134a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        if (data_format & DATA_FORMAT_STEP) {
36144a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            LOGV_IF(ENG_VERBOSE, "STEP DETECTED:0x%x", data_format);
36154a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            mPedUpdate = 1;
36164a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            mask |= DATA_FORMAT_STEP;
36174a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            // cancels step bit
36184a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            data_format &= (~DATA_FORMAT_STEP);
36194a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        }
36204a28f9c897c46c42a255823f7e307169a828a025Rosa Chow
362149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        if (data_format == DATA_FORMAT_QUAT) {
362249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            mCachedQuaternionData[0] = *((int *) (rdata + 4));
362349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            mCachedQuaternionData[1] = *((int *) (rdata + 8));
36244a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            mCachedQuaternionData[2] = *((int *) (rdata + 12));
362549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            rdata += QUAT_ONLY_LAST_PACKET_OFFSET;
362649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            mQuatSensorTimestamp = *((long long*) (rdata));
362749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            mask |= DATA_FORMAT_QUAT;
362849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            readCounter -= BYTES_QUAT_DATA;
362949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        }
363049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        else if (data_format == DATA_FORMAT_6_AXIS) {
363149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            mCached6AxisQuaternionData[0] = *((int *) (rdata + 4));
363249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            mCached6AxisQuaternionData[1] = *((int *) (rdata + 8));
363349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            mCached6AxisQuaternionData[2] = *((int *) (rdata + 12));
363449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            rdata += QUAT_ONLY_LAST_PACKET_OFFSET;
363549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            mQuatSensorTimestamp = *((long long*) (rdata));
363649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            mask |= DATA_FORMAT_6_AXIS;
363749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            readCounter -= BYTES_QUAT_DATA;
363849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        }
363949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        else if (data_format == DATA_FORMAT_PED_QUAT) {
364049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            mCachedPedQuaternionData[0] = *((short *) (rdata + 2));
364149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            mCachedPedQuaternionData[1] = *((short *) (rdata + 4));
364249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            mCachedPedQuaternionData[2] = *((short *) (rdata + 6));
364349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            rdata += BYTES_PER_SENSOR;
364449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            mQuatSensorTimestamp = *((long long*) (rdata));
364549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            mask |= DATA_FORMAT_PED_QUAT;
364649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            readCounter -= BYTES_PER_SENSOR_PACKET;
364749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        }
36484a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        else if (data_format == DATA_FORMAT_PED_STANDALONE) {
36494a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            LOGV_IF(ENG_VERBOSE, "STEP DETECTED:0x%x", data_format);
365049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            rdata += BYTES_PER_SENSOR;
36514a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            mStepSensorTimestamp = *((long long*) (rdata));
36524a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            mask |= DATA_FORMAT_PED_STANDALONE;
365349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            readCounter -= BYTES_PER_SENSOR_PACKET;
365449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            mPedUpdate = 1;
365549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        }
365649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        else if (data_format == DATA_FORMAT_GYRO) {
365749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            mCachedGyroData[0] = *((short *) (rdata + 2));
365849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            mCachedGyroData[1] = *((short *) (rdata + 4));
365949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            mCachedGyroData[2] = *((short *) (rdata + 6));
366049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            rdata += BYTES_PER_SENSOR;
366149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            mGyroSensorTimestamp = *((long long*) (rdata));
366249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            mask |= DATA_FORMAT_GYRO;
366349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            readCounter -= BYTES_PER_SENSOR_PACKET;
366449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        }
366549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        else if (data_format == DATA_FORMAT_ACCEL) {
366649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            mCachedAccelData[0] = *((short *) (rdata + 2));
366749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            mCachedAccelData[1] = *((short *) (rdata + 4));
366849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            mCachedAccelData[2] = *((short *) (rdata + 6));
366949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            rdata += BYTES_PER_SENSOR;
367049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            mAccelSensorTimestamp = *((long long*) (rdata));
367149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            mask |= DATA_FORMAT_ACCEL;
367249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            readCounter -= BYTES_PER_SENSOR_PACKET;
367349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        }
36744a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        else  if (data_format == DATA_FORMAT_COMPASS) {
367549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            if (mCompassSensor->isIntegrated()) {
367649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                mCachedCompassData[0] = *((short *) (rdata + 2));
367749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                mCachedCompassData[1] = *((short *) (rdata + 4));
367849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                mCachedCompassData[2] = *((short *) (rdata + 6));
367949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                rdata += BYTES_PER_SENSOR;
368049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                mCompassTimestamp = *((long long*) (rdata));
368149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                if (mCachedCompassData[0] != 0 || mCachedCompassData[1] != 0
368249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                                               || mCachedCompassData[2] != 0) {
368349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                    mask |= DATA_FORMAT_COMPASS;
368449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                }
368549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                readCounter -= BYTES_PER_SENSOR_PACKET;
368649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            }
368749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        }
368849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        else if (data_format == DATA_FORMAT_PRESSURE) {
368949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            if (mPressureSensor->isIntegrated()) {
36904a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                mCachedPressureData =
36914a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                    ((*((short *)(rdata + 4))) << 16) +
36924a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                    (*((unsigned short *) (rdata + 6)));
369349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                rdata += BYTES_PER_SENSOR;
369449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                mPressureTimestamp = *((long long*) (rdata));
369549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                if (mCachedPressureData!= 0) {
369649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                    mask |= DATA_FORMAT_PRESSURE;
369749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                }
36984a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                readCounter -= BYTES_PER_SENSOR_PACKET;
369949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            }
370049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        }
370149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        rdata += BYTES_PER_SENSOR;
370249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
37034a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        /* read ahead and store left over data if any */
37044a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        if ((readCounter != 0) && (rsize != (ssize_t)nbyte) && (readCounter <= 24)) {
37054a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            int counter = readCounter;
37064a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            int currentBufferCounter = 0;
37074a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            LOGV_IF(0, "!!! not enough data readCounter=%d, expected nbyte=%d", readCounter, nbyte);
37084a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            memcpy(mLeftOverBuffer, rdata, readCounter);
37094a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            LOGV_IF(0,
37104a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                    "HAL:input store rdata=:%d, %d, %d, %d,%d, %d, %d, %d,%d, "
37114a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                    "%d, %d, %d,%d, %d, %d, %d\n",
37124a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                    mLeftOverBuffer[0], mLeftOverBuffer[1], mLeftOverBuffer[2], mLeftOverBuffer[3],
37134a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                    mLeftOverBuffer[4], mLeftOverBuffer[5], mLeftOverBuffer[6], mLeftOverBuffer[7],
37144a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                    mLeftOverBuffer[8], mLeftOverBuffer[9], mLeftOverBuffer[10], mLeftOverBuffer[11],
37154a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                    mLeftOverBuffer[12],mLeftOverBuffer[13],mLeftOverBuffer[14], mLeftOverBuffer[15]);
37164a28f9c897c46c42a255823f7e307169a828a025Rosa Chow
37174a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            mLeftOverBufferSize = readCounter;
37184a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            readCounter = 0;
37194a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            LOGV_IF(0, "!!! stored number of bytes:%d", mLeftOverBufferSize);
37204a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        }
37214a28f9c897c46c42a255823f7e307169a828a025Rosa Chow
37224a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        /* handle data read */
37234a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        if (mask & DATA_FORMAT_GYRO) {
37244a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            /* batch mode does not batch temperature */
37254a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            /* disable temperature read */
37264a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            if (!(mFeatureActiveMask & INV_DMP_BATCH_MODE)) {
37274a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                // send down temperature every 0.5 seconds
37284a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                // with timestamp measured in "driver" layer
37294a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                if(mGyroSensorTimestamp - mTempCurrentTime >= 500000000LL) {
37304a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                    mTempCurrentTime = mGyroSensorTimestamp;
37314a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                    long long temperature[2];
37324a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                    if(inv_read_temperature(temperature) == 0) {
37334a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                        LOGV_IF(INPUT_DATA,
37344a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                        "HAL:input inv_read_temperature = %lld, timestamp= %lld",
373549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                        temperature[0], temperature[1]);
37364a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                        inv_build_temp(temperature[0], temperature[1]);
37374a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                     }
373849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow#ifdef TESTING
37394a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                    long bias[3], temp, temp_slope[3];
37404a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                    inv_get_mpl_gyro_bias(bias, &temp);
37414a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                    inv_get_gyro_ts(temp_slope);
37424a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                    LOGI("T: %.3f "
37434a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                     "GB: %+13f %+13f %+13f "
37444a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                     "TS: %+13f %+13f %+13f "
37454a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                     "\n",
37464a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                     (float)temperature[0] / 65536.f,
37474a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                     (float)bias[0] / 65536.f / 16.384f,
37484a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                     (float)bias[1] / 65536.f / 16.384f,
37494a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                     (float)bias[2] / 65536.f / 16.384f,
37504a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                     temp_slope[0] / 65536.f,
37514a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                     temp_slope[1] / 65536.f,
37524a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                     temp_slope[2] / 65536.f);
375349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow#endif
37544a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                }
37554a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            }
37564a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            mPendingMask |= 1 << Gyro;
37574a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            mPendingMask |= 1 << RawGyro;
37584a28f9c897c46c42a255823f7e307169a828a025Rosa Chow
37594a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            if (mLocalSensorMask & INV_THREE_AXIS_GYRO) {
37604a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                inv_build_gyro(mCachedGyroData, mGyroSensorTimestamp);
37614a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                LOGV_IF(INPUT_DATA,
37624a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                        "HAL:input inv_build_gyro: %+8d %+8d %+8d - %lld",
37634a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                        mCachedGyroData[0], mCachedGyroData[1],
37644a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                        mCachedGyroData[2], mGyroSensorTimestamp);
37654a28f9c897c46c42a255823f7e307169a828a025Rosa Chow           }
37664a28f9c897c46c42a255823f7e307169a828a025Rosa Chow           latestTimestamp = mGyroSensorTimestamp;
376749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        }
376849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
37694a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        if (mask & DATA_FORMAT_ACCEL) {
37704a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            mPendingMask |= 1 << Accelerometer;
37714a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            if (mLocalSensorMask & INV_THREE_AXIS_ACCEL) {
37724a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                inv_build_accel(mCachedAccelData, 0, mAccelSensorTimestamp);
37734a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                 LOGV_IF(INPUT_DATA,
37744a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                    "HAL:input inv_build_accel: %+8ld %+8ld %+8ld - %lld",
377549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                    mCachedAccelData[0], mCachedAccelData[1],
377649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                    mCachedAccelData[2], mAccelSensorTimestamp);
37774a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            }
37784a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            latestTimestamp = mAccelSensorTimestamp;
377949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        }
378049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
37814a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        if ((mask & DATA_FORMAT_COMPASS) && mCompassSensor->isIntegrated()) {
37824a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            int status = 0;
37834a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            if (mCompassSensor->providesCalibration()) {
37844a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                status = mCompassSensor->getAccuracy();
37854a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                status |= INV_CALIBRATED;
37864a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            }
37874a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            if (mLocalSensorMask & INV_THREE_AXIS_COMPASS) {
378849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            inv_build_compass(mCachedCompassData, status,
378949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                              mCompassTimestamp);
379049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            LOGV_IF(INPUT_DATA,
37914a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                    "HAL:input inv_build_compass: %+8ld %+8ld %+8ld - %lld",
379249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                    mCachedCompassData[0], mCachedCompassData[1],
379349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                    mCachedCompassData[2], mCompassTimestamp);
37944a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            }
37954a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            latestTimestamp = mCompassTimestamp;
379649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        }
379749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
37984a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        if (isLowPowerQuatEnabled() && lp_quaternion_on == 1
379949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                                && (mask & DATA_FORMAT_QUAT)) {
38004a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            /* if bias was applied to DMP bias,
38014a28f9c897c46c42a255823f7e307169a828a025Rosa Chow               set status bits to disable gyro bias cal */
38024a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            int status = 0;
38034a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            if (mGyroBiasApplied == true) {
38044a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                LOGV_IF(INPUT_DATA, "HAL:input mpl bias not used");
38054a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                status |= INV_BIAS_APPLIED;
38064a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                mGyroBiasApplied = false;
38074a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            }
38084a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            status |= 32 | INV_QUAT_3AXIS; /* default 32 (16/32bits) */
38094a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            inv_build_quat(mCachedQuaternionData,
381049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                       status,
381149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                       mQuatSensorTimestamp);
38124a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            LOGV_IF(INPUT_DATA,
38134a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                    "HAL:input inv_build_quat: %+8ld %+8ld %+8ld - %lld",
38144a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                    mCachedQuaternionData[0], mCachedQuaternionData[1],
38154a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                    mCachedQuaternionData[2],
38164a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                    mQuatSensorTimestamp);
38174a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            latestTimestamp = mQuatSensorTimestamp;
38184a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        }
381949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
38204a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        if ((mask & DATA_FORMAT_6_AXIS) && check6AxisQuatEnabled()
382149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                                    && (sixAxis_quaternion_on == 1)) {
38224a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            /* if bias was applied to DMP bias,
38234a28f9c897c46c42a255823f7e307169a828a025Rosa Chow               set status bits to disable gyro bias cal */
38244a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            int status = 0;
38254a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            if (mGyroBiasApplied == true) {
38264a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                status |= INV_QUAT_6AXIS;
38274a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                mGyroBiasApplied = false;
38284a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            }
38294a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            status |= 32 | INV_QUAT_3AXIS; /* default 32 (16/32bits) */
38304a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            inv_build_quat(mCached6AxisQuaternionData,
383149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                       status,
383249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                       mQuatSensorTimestamp);
38334a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            LOGV_IF(INPUT_DATA,
38344a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                "HAL:input 6 axis ped quat: %+8ld %+8ld %+8ld - %lld",
383549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                mCached6AxisQuaternionData[0], mCached6AxisQuaternionData[1],
383649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                mCached6AxisQuaternionData[2],
383749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                mQuatSensorTimestamp);
38384a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            latestTimestamp = mQuatSensorTimestamp;
383949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        }
38404a28f9c897c46c42a255823f7e307169a828a025Rosa Chow
38414a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        if ((mask & DATA_FORMAT_PED_QUAT) && checkPedQuatEnabled()
38424a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                                          && (ped_quaternion_on == 1)) {
38434a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            /* if bias was applied to DMP bias,
38444a28f9c897c46c42a255823f7e307169a828a025Rosa Chow               set status bits to disable gyro bias cal */
38454a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            int status = 0;
38464a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            if (mGyroBiasApplied == true) {
38474a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                status |= INV_QUAT_6AXIS;
38484a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                mGyroBiasApplied = false;
38494a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            }
38504a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            status |= 32 | INV_QUAT_3AXIS; /* default 32 (16/32bits) */
38514a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            inv_build_quat(mCachedPedQuaternionData,
385249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                       status,
385349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                       mQuatSensorTimestamp);
38544a28f9c897c46c42a255823f7e307169a828a025Rosa Chow
385549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            LOGV_IF(INPUT_DATA,
38564a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            "HAL:input ped quat: %+8ld %+8ld %+8ld - %lld",
38574a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            mCachedPedQuaternionData[0], mCachedPedQuaternionData[1],
38584a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            mCachedPedQuaternionData[2],
38594a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            mQuatSensorTimestamp);
38604a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            latestTimestamp = mQuatSensorTimestamp;
386149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        }
386249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
38634a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        if ((mask & DATA_FORMAT_PRESSURE) && mPressureSensor->isIntegrated()) {
38644a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            int status = 0;
38654a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            if (mLocalSensorMask & INV_ONE_AXIS_PRESSURE) {
38664a28f9c897c46c42a255823f7e307169a828a025Rosa Chow
386749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            LOGV_IF(INPUT_DATA,
38684a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                    "HAL:input inv_build_pressure: %+8ld - %lld",
386949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                    mCachedPressureData, mPressureTimestamp);
38704a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            }
38714a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            latestTimestamp = mPressureTimestamp;
387249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        }
38734a28f9c897c46c42a255823f7e307169a828a025Rosa Chow
38744a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        /* take the latest timestamp */
38754a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        if (mask & DATA_FORMAT_STEP) {
38764a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            mStepSensorTimestamp = latestTimestamp;
38774a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        }
38784a28f9c897c46c42a255823f7e307169a828a025Rosa Chow   }//while end
387949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow}
388049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
388149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow/* use for both MPUxxxx and third party compass */
388249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chowvoid MPLSensor::buildCompassEvent(void)
388349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow{
388449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    VHANDLER_LOG;
388549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
388649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    int done = 0;
388749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
388849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    // pthread_mutex_lock(&mMplMutex);
388949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    // pthread_mutex_lock(&mHALMutex);
389049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
389149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    done = mCompassSensor->readSample(mCachedCompassData, &mCompassTimestamp);
389249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    if(mCompassSensor->isYasCompass()) {
389349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        if (mCompassSensor->checkCoilsReset() == 1) {
389449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow           //Reset relevant compass settings
389549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow           resetCompass();
389649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        }
389749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    }
389849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    if (done > 0) {
389949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        int status = 0;
390049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        if (mCompassSensor->providesCalibration()) {
390149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            status = mCompassSensor->getAccuracy();
390249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            status |= INV_CALIBRATED;
390349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        }
390449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        if (mLocalSensorMask & INV_THREE_AXIS_COMPASS) {
390549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            inv_build_compass(mCachedCompassData, status,
390649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                              mCompassTimestamp);
390749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            LOGV_IF(INPUT_DATA,
39084a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                    "HAL:input inv_build_compass: %+8ld %+8ld %+8ld - %lld",
390949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                    mCachedCompassData[0], mCachedCompassData[1],
391049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                    mCachedCompassData[2], mCompassTimestamp);
391149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        }
391249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    }
391349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
391449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    // pthread_mutex_unlock(&mMplMutex);
391549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    // pthread_mutex_unlock(&mHALMutex);
391649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow}
391749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
391849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chowint MPLSensor::resetCompass(void)
391949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow{
392049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    VFUNC_LOG;
392149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
392249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    //Reset compass cal if enabled
392349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    if (mMplFeatureActiveMask & INV_COMPASS_CAL) {
392449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow       LOGV_IF(EXTRA_VERBOSE, "HAL:Reset compass cal");
392549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow       inv_init_vector_compass_cal();
392649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    }
392749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
392849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    //Reset compass fit if enabled
392949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    if (mMplFeatureActiveMask & INV_COMPASS_FIT) {
393049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow       LOGV_IF(EXTRA_VERBOSE, "HAL:Reset compass fit");
393149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow       inv_init_compass_fit();
393249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    }
393349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
393449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    return 0;
393549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow}
393649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
393749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chowint MPLSensor::getFd(void) const
393849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow{
393949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    VFUNC_LOG;
394049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    LOGV_IF(EXTRA_VERBOSE, "MPLSensor::getFd returning %d", iio_fd);
394149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    return iio_fd;
394249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow}
394349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
394449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chowint MPLSensor::getAccelFd(void) const
394549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow{
394649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    VFUNC_LOG;
394749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    LOGV_IF(EXTRA_VERBOSE, "MPLSensor::getAccelFd returning %d", accel_fd);
394849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    return accel_fd;
394949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow}
395049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
395149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chowint MPLSensor::getCompassFd(void) const
395249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow{
395349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    VFUNC_LOG;
395449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    int fd = mCompassSensor->getFd();
395549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    LOGV_IF(EXTRA_VERBOSE, "MPLSensor::getCompassFd returning %d", fd);
395649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    return fd;
395749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow}
395849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
395949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chowint MPLSensor::turnOffAccelFifo(void)
396049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow{
396149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    int i, res = 0, tempFd;
396249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)",
396349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                        0, mpu.accel_fifo_enable, getTimestamp());
396449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    res += write_sysfs_int(mpu.accel_fifo_enable, 0);
396549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    return res;
396649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow}
396749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
396849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chowint MPLSensor::turnOffGyroFifo(void)
396949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow{
397049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    int i, res = 0, tempFd;
397149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)",
397249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                        0, mpu.gyro_fifo_enable, getTimestamp());
397349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    res += write_sysfs_int(mpu.gyro_fifo_enable, 0);
397449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    return res;
397549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow}
397649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
397749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chowint MPLSensor::enableDmpOrientation(int en)
397849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow{
397949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    VFUNC_LOG;
398049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    int res = 0;
398149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    int enabled_sensors = mEnabled;
398249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
398349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    if (isMpuNonDmp())
398449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        return res;
398549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
398649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    // reset master enable
398749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    res = masterEnable(0);
398849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    if (res < 0)
398949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        return res;
399049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
399149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    if (en == 1) {
399249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        //Enable DMP orientation
399349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)",
399449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                en, mpu.display_orientation_on, getTimestamp());
399549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        if (write_sysfs_int(mpu.display_orientation_on, en) < 0) {
399649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            LOGE("HAL:ERR can't enable Android orientation");
399749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            res = -1;	// indicate an err
399849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            return res;
399949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        }
400049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
400149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        // enable DMP
400249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        res = onDmp(1);
400349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        if (res < 0)
400449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            return res;
400549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
40064a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        // set rate to 200Hz
400749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)",
400849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                200, mpu.accel_fifo_rate, getTimestamp());
400949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        if (write_sysfs_int(mpu.accel_fifo_rate, 200) < 0) {
401049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            res = -1;
40114a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            LOGE("HAL:ERR can't set rate to 200Hz");
401249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            return res;
401349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        }
401449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
401549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        // enable accel engine
401649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        res = enableAccel(1);
401749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        if (res < 0)
401849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            return res;
401949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
402049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        // disable accel FIFO
402149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        if (!(mLocalSensorMask & mMasterSensorMask & INV_THREE_AXIS_ACCEL)) {
402249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            res = turnOffAccelFifo();
402349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            if (res < 0)
402449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                return res;
402549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        }
402649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
402749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        if (!mEnabled){
402849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)",
402949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                       1, mpu.dmp_event_int_on, getTimestamp());
403049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            if (write_sysfs_int(mpu.dmp_event_int_on, en) < 0) {
403149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                res = -1;
403249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                LOGE("HAL:ERR can't enable DMP event interrupt");
403349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            }
403449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        }
403549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
403649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        mFeatureActiveMask |= INV_DMP_DISPL_ORIENTATION;
403749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        LOGV_IF(ENG_VERBOSE, "mFeatureActiveMask=%016llx", mFeatureActiveMask);
403849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    } else {
403949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        mFeatureActiveMask &= ~INV_DMP_DISPL_ORIENTATION;
404049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        // disable DMP
404149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        if (mFeatureActiveMask == 0) {
404249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            res = onDmp(0);
404349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            if (res < 0)
404449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                return res;
404549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
404649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            // disable accel engine
404749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            if (!(mLocalSensorMask & mMasterSensorMask
404849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                    & INV_THREE_AXIS_ACCEL)) {
404949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                res = enableAccel(0);
405049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                if (res < 0)
405149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                    return res;
405249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            }
405349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        }
405449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
405549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        if (mEnabled){
405649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)",
405749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                       en, mpu.dmp_event_int_on, getTimestamp());
405849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            if (write_sysfs_int(mpu.dmp_event_int_on, en) < 0) {
405949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                res = -1;
406049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                LOGE("HAL:ERR can't enable DMP event interrupt");
406149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            }
406249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        }
406349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        LOGV_IF(ENG_VERBOSE, "mFeatureActiveMask=%016llx", mFeatureActiveMask);
406449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    }
406549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
406649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    if (en || mEnabled || mFeatureActiveMask) {
406749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        res = masterEnable(1);
406849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    }
406949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    return res;
407049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow}
407149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
407249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chowint MPLSensor::openDmpOrientFd(void)
407349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow{
407449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    VFUNC_LOG;
407549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
407649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    if (!isDmpDisplayOrientationOn() || dmp_orient_fd >= 0) {
407749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        LOGV_IF(PROCESS_VERBOSE,
407849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                "HAL:DMP display orientation disabled or file desc opened");
407949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        return 0;
408049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    }
408149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
408249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    dmp_orient_fd = open(mpu.event_display_orientation, O_RDONLY| O_NONBLOCK);
408349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    if (dmp_orient_fd < 0) {
408449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        LOGE("HAL:ERR couldn't open dmpOrient node");
408549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        return -1;
408649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    } else {
408749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        LOGV_IF(PROCESS_VERBOSE,
408849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                "HAL:dmp_orient_fd opened : %d", dmp_orient_fd);
408949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        return 0;
409049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    }
409149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow}
409249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
409349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chowint MPLSensor::closeDmpOrientFd(void)
409449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow{
409549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    VFUNC_LOG;
409649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    if (dmp_orient_fd >= 0)
409749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        close(dmp_orient_fd);
409849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    return 0;
409949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow}
410049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
410149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chowint MPLSensor::dmpOrientHandler(int orient)
410249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow{
410349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    VFUNC_LOG;
410449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    LOGV_IF(PROCESS_VERBOSE, "HAL:orient %x", orient);
410549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    return 0;
410649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow}
410749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
410849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chowint MPLSensor::readDmpOrientEvents(sensors_event_t* data, int count)
410949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow{
411049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    VFUNC_LOG;
411149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
411249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    char dummy[4];
411349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    int screen_orientation = 0;
411449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    FILE *fp;
411549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
411649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    fp = fopen(mpu.event_display_orientation, "r");
411749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    if (fp == NULL) {
411849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        LOGE("HAL:cannot open event_display_orientation");
411949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        return 0;
412049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    }
412149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    fscanf(fp, "%d\n", &screen_orientation);
412249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    fclose(fp);
412349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
412449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    int numEventReceived = 0;
412549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
412649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    if (mDmpOrientationEnabled && count > 0) {
412749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        sensors_event_t temp;
412849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
412949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        temp.version = sizeof(sensors_event_t);
413049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        temp.sensor = ID_SO;
413149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        temp.acceleration.status
413249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            = SENSOR_STATUS_UNRELIABLE;
413349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow#ifdef ENABLE_DMP_SCREEN_AUTO_ROTATION
413449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        temp.type = SENSOR_TYPE_SCREEN_ORIENTATION;
413549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        temp.screen_orientation = screen_orientation;
413649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow#endif
413749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        struct timespec ts;
413849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        clock_gettime(CLOCK_MONOTONIC, &ts);
413949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        temp.timestamp = (int64_t) ts.tv_sec * 1000000000 + ts.tv_nsec;
414049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
414149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        *data++ = temp;
414249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        count--;
414349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        numEventReceived++;
414449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    }
414549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
414649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    // read dummy data per driver's request
414749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    dmpOrientHandler(screen_orientation);
414849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    read(dmp_orient_fd, dummy, 4);
414949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
415049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    return numEventReceived;
415149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow}
415249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
415349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chowint MPLSensor::getDmpOrientFd(void)
415449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow{
415549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    VFUNC_LOG;
415649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
415749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    LOGV_IF(EXTRA_VERBOSE,
415849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            "MPLSensor::getDmpOrientFd returning %d", dmp_orient_fd);
415949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    return dmp_orient_fd;
416049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
416149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow}
416249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
416349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chowint MPLSensor::checkDMPOrientation(void)
416449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow{
416549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    VFUNC_LOG;
416649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    return ((mFeatureActiveMask & INV_DMP_DISPL_ORIENTATION) ? 1 : 0);
416749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow}
416849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
416949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chowint MPLSensor::getDmpRate(int64_t *wanted)
417049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow{
417149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    VFUNC_LOG;
417249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
417349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow      // set DMP output rate to FIFO
417449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow      if(mDmpOn == 1) {
417549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)",
41764a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                int(1000000000.f / *wanted), mpu.three_axis_q_rate,
417749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                getTimestamp());
41784a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        write_sysfs_int(mpu.three_axis_q_rate, 1000000000.f / *wanted);
417949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        LOGV_IF(PROCESS_VERBOSE,
41804a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                "HAL:DMP three axis rate %.2f Hz", 1000000000.f / *wanted);
41814a28f9c897c46c42a255823f7e307169a828a025Rosa Chow
41824a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)",
41834a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                int(1000000000.f / *wanted), mpu.six_axis_q_rate,
41844a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                getTimestamp());
41854a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        write_sysfs_int(mpu.six_axis_q_rate, 1000000000.f / *wanted);
41864a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        LOGV_IF(PROCESS_VERBOSE,
41874a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                "HAL:DMP six axis rate %.2f Hz", 1000000000.f / *wanted);
41884a28f9c897c46c42a255823f7e307169a828a025Rosa Chow
41894a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)",
41904a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                int(1000000000.f / *wanted), mpu.ped_q_rate,
41914a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                getTimestamp());
41924a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        write_sysfs_int(mpu.ped_q_rate, 1000000000.f / *wanted);
41934a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        LOGV_IF(PROCESS_VERBOSE,
41944a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                "HAL:DMP ped quaternion rate %.2f Hz", 1000000000.f / *wanted);
41954a28f9c897c46c42a255823f7e307169a828a025Rosa Chow
419649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        //DMP running rate must be @ 200Hz
419749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        *wanted= RATE_200HZ;
419849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        LOGV_IF(PROCESS_VERBOSE,
419949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                "HAL:DMP rate= %.2f Hz", 1000000000.f / *wanted);
420049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    }
420149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    return 0;
420249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow}
420349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
420449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chowint MPLSensor::getPollTime(void)
420549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow{
420649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    VHANDLER_LOG;
420749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    return mPollTime;
420849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow}
420949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
421049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chowint MPLSensor::getStepCountPollTime(void)
421149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow{
421249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    VHANDLER_LOG;
421349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    if (mDmpStepCountEnabled) {
421449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    /* clamped to 1ms?, still rather large */
42154a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    LOGV_IF(0/*EXTRA_VERBOSE*/, "Step Count poll time = %lld ms",
421649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            mStepCountPollTime / 1000000LL);
421749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        return (mStepCountPollTime / 1000000LL);
421849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    }
421949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    return -1;
422049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow}
422149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
422249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chowbool MPLSensor::hasStepCountPendingEvents(void)
422349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow{
422449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    VHANDLER_LOG;
422549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    if (mDmpStepCountEnabled) {
422649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        struct timespec t_now;
422749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        int64_t interval = 0;
422849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
422949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        clock_gettime(CLOCK_MONOTONIC, &t_now);
423049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        interval = ((int64_t(t_now.tv_sec) * 1000000000LL + t_now.tv_nsec) -
423149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                    (int64_t(mt_pre.tv_sec) * 1000000000LL + mt_pre.tv_nsec));
423249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
423349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        if (interval < mStepCountPollTime) {
42344a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            LOGV_IF(0/*ENG_VERBOSE*/,
42354a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                    "Step Count interval elapsed: %lld, triggered: %d",
423649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                    interval, mStepCountPollTime);
423749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            return false;
423849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        } else {
423949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            clock_gettime(CLOCK_MONOTONIC, &mt_pre);
42404a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            LOGV_IF(0/*ENG_VERBOSE*/, "Step Count previous time: %ld ms",
424149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                    mt_pre.tv_nsec / 1000);
424249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            return true;
424349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        }
424449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    }
424549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    return false;
424649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow}
424749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
424849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chowbool MPLSensor::hasPendingEvents(void) const
424949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow{
425049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    VHANDLER_LOG;
425149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    // if we are using the polling workaround, force the main
425249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    // loop to check for data every time
425349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    return (mPollTime != -1);
425449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow}
425549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
425649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow/* TODO: support resume suspend when we gain more info about them*/
425749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chowvoid MPLSensor::sleepEvent(void)
425849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow{
425949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    VFUNC_LOG;
426049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow}
426149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
426249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chowvoid MPLSensor::wakeEvent(void)
426349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow{
426449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    VFUNC_LOG;
426549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow}
426649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
426749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chowint MPLSensor::inv_float_to_q16(float *fdata, long *ldata)
426849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow{
426949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    VHANDLER_LOG;
427049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
427149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    if (!fdata || !ldata)
427249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        return -1;
427349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    ldata[0] = (long)(fdata[0] * 65536.f);
427449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    ldata[1] = (long)(fdata[1] * 65536.f);
427549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    ldata[2] = (long)(fdata[2] * 65536.f);
427649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    return 0;
427749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow}
427849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
427949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chowint MPLSensor::inv_long_to_q16(long *fdata, long *ldata)
428049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow{
428149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    VHANDLER_LOG;
428249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
428349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    if (!fdata || !ldata)
428449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        return -1;
428549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    ldata[0] = (fdata[1] * 65536.f);
428649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    ldata[1] = (fdata[2] * 65536.f);
428749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    ldata[2] = (fdata[3] * 65536.f);
428849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    return 0;
428949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow}
429049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
429149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chowint MPLSensor::inv_float_to_round(float *fdata, long *ldata)
429249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow{
429349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    VHANDLER_LOG;
429449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
429549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    if (!fdata || !ldata)
429649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            return -1;
429749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    ldata[0] = (long)fdata[0];
429849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    ldata[1] = (long)fdata[1];
429949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    ldata[2] = (long)fdata[2];
430049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    return 0;
430149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow}
430249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
430349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chowint MPLSensor::inv_float_to_round2(float *fdata, short *ldata)
430449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow{
430549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    VHANDLER_LOG;
430649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
430749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    if (!fdata || !ldata)
430849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        return -1;
430949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    ldata[0] = (short)fdata[0];
431049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    ldata[1] = (short)fdata[1];
431149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    ldata[2] = (short)fdata[2];
431249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    return 0;
431349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow}
431449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
431549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chowint MPLSensor::inv_long_to_float(long *ldata, float *fdata)
431649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow{
431749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    VHANDLER_LOG;
431849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
431949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    if (!ldata || !fdata)
432049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        return -1;
432149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    fdata[0] = (float)ldata[0];
432249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    fdata[1] = (float)ldata[1];
432349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    fdata[2] = (float)ldata[2];
432449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    return 0;
432549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow}
432649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
432749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chowint MPLSensor::inv_read_temperature(long long *data)
432849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow{
432949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    VHANDLER_LOG;
433049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
433149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    int count = 0;
433249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    char raw_buf[40];
433349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    long raw = 0;
433449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
433549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    long long timestamp = 0;
433649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
433749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    memset(raw_buf, 0, sizeof(raw_buf));
433849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    count = read_attribute_sensor(gyro_temperature_fd, raw_buf,
433949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                                  sizeof(raw_buf));
434049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    if(count < 1) {
434149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        LOGE("HAL:error reading gyro temperature");
434249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        return -1;
434349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    }
434449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
434549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    count = sscanf(raw_buf, "%ld%lld", &raw, &timestamp);
434649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
434749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    if(count < 0) {
434849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        return -1;
434949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    }
435049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
435149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    LOGV_IF(ENG_VERBOSE,
435249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            "HAL:temperature raw = %ld, timestamp = %lld, count = %d",
435349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            raw, timestamp, count);
435449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    data[0] = raw;
435549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    data[1] = timestamp;
435649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
435749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    return 0;
435849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow}
435949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
436049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chowint MPLSensor::inv_read_dmp_state(int fd)
436149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow{
436249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    VFUNC_LOG;
436349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
436449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    if(fd < 0)
436549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        return -1;
436649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
436749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    int count = 0;
436849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    char raw_buf[10];
436949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    short raw = 0;
437049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
437149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    memset(raw_buf, 0, sizeof(raw_buf));
437249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    count = read_attribute_sensor(fd, raw_buf, sizeof(raw_buf));
437349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    if(count < 1) {
437449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        LOGE("HAL:error reading dmp state");
437549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        close(fd);
437649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        return -1;
437749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    }
437849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    count = sscanf(raw_buf, "%hd", &raw);
437949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    if(count < 0) {
438049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        LOGE("HAL:dmp state data is invalid");
438149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        close(fd);
438249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        return -1;
438349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    }
438449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    LOGV_IF(EXTRA_VERBOSE, "HAL:dmp state = %d, count = %d", raw, count);
438549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    close(fd);
438649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    return (int)raw;
438749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow}
438849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
438949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chowint MPLSensor::inv_read_sensor_bias(int fd, long *data)
439049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow{
439149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    VFUNC_LOG;
439249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
439349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    if(fd == -1) {
439449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        return -1;
439549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    }
439649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
439749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    char buf[50];
439849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    char x[15], y[15], z[15];
439949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
440049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    memset(buf, 0, sizeof(buf));
440149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    int count = read_attribute_sensor(fd, buf, sizeof(buf));
440249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    if(count < 1) {
440349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        LOGE("HAL:Error reading gyro bias");
440449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        return -1;
440549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    }
440649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    count = sscanf(buf, "%[^','],%[^','],%[^',']", x, y, z);
440749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    if(count) {
440849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        /* scale appropriately for MPL */
440949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        LOGV_IF(ENG_VERBOSE,
441049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                "HAL:pre-scaled bias: X:Y:Z (%ld, %ld, %ld)",
441149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                atol(x), atol(y), atol(z));
441249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
441349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        data[0] = (long)(atol(x) / 10000 * (1L << 16));
441449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        data[1] = (long)(atol(y) / 10000 * (1L << 16));
441549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        data[2] = (long)(atol(z) / 10000 * (1L << 16));
441649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
441749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        LOGV_IF(ENG_VERBOSE,
441849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                "HAL:scaled bias: X:Y:Z (%ld, %ld, %ld)",
441949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                data[0], data[1], data[2]);
442049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    }
442149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    return 0;
442249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow}
442349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
442449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow/** fill in the sensor list based on which sensors are configured.
442549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow *  return the number of configured sensors.
442649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow *  parameter list must point to a memory region of at least 7*sizeof(sensor_t)
442749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow *  parameter len gives the length of the buffer pointed to by list
442849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow */
442949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chowint MPLSensor::populateSensorList(struct sensor_t *list, int len)
443049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow{
443149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    VFUNC_LOG;
443249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
443349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    int numsensors;
443449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
443549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    if(len <
443649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        (int)((sizeof(sSensorList) / sizeof(sensor_t)) * sizeof(sensor_t))) {
443749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        LOGE("HAL:sensor list too small, not populating.");
443849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        return -(sizeof(sSensorList) / sizeof(sensor_t));
443949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    }
444049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
444149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    /* fill in the base values */
444249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    memcpy(list, sSensorList,
444349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow           sizeof (struct sensor_t) * (sizeof(sSensorList) / sizeof(sensor_t)));
444449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
444549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    /* first add gyro, accel and compass to the list */
444649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
444749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    /* fill in gyro/accel values */
444849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    if(chip_ID == NULL) {
444949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        LOGE("HAL:Can not get gyro/accel id");
445049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    }
445149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    fillGyro(chip_ID, list);
445249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    fillAccel(chip_ID, list);
445349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
445449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    // TODO: need fixes for unified HAL and 3rd-party solution
445549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    mCompassSensor->fillList(&list[MagneticField]);
445649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    mCompassSensor->fillList(&list[RawMagneticField]);
445749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
445849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    if(1) {
445949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        numsensors = (sizeof(sSensorList) / sizeof(sensor_t));
446049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        /* all sensors will be added to the list
446149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow           fill in orientation values */
446249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        fillOrientation(list);
446349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        /* fill in rotation vector values */
446449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        fillRV(list);
446549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        /* fill in game rotation vector values */
446649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        fillGRV(list);
446749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        /* fill in gravity values */
446849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        fillGravity(list);
446949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        /* fill in Linear accel values */
447049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        fillLinearAccel(list);
447149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        /* fill in Significant motion values */
447249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        fillSignificantMotion(list);
447349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow#ifdef ENABLE_DMP_SCREEN_AUTO_ROTATION
447449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        /* fill in screen orientation values */
447549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        fillScreenOrientation(list);
447649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow#endif
447749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    } else {
447849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        /* no 9-axis sensors, zero fill that part of the list */
447949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        numsensors = 3;
448049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        memset(list + 3, 0, 4 * sizeof(struct sensor_t));
448149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    }
448249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
448349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    return numsensors;
448449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow}
448549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
448649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chowvoid MPLSensor::fillAccel(const char* accel, struct sensor_t *list)
448749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow{
448849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    VFUNC_LOG;
448949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
449049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    if (accel) {
449149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        if(accel != NULL && strcmp(accel, "BMA250") == 0) {
449249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            list[Accelerometer].maxRange = ACCEL_BMA250_RANGE;
449349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            list[Accelerometer].resolution = ACCEL_BMA250_RESOLUTION;
449449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            list[Accelerometer].power = ACCEL_BMA250_POWER;
449549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            list[Accelerometer].minDelay = ACCEL_BMA250_MINDELAY;
449649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            return;
449749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        } else if (accel != NULL && strcmp(accel, "MPU6050") == 0) {
449849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            list[Accelerometer].maxRange = ACCEL_MPU6050_RANGE;
449949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            list[Accelerometer].resolution = ACCEL_MPU6050_RESOLUTION;
450049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            list[Accelerometer].power = ACCEL_MPU6050_POWER;
450149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            list[Accelerometer].minDelay = ACCEL_MPU6050_MINDELAY;
450249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            return;
450349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        } else if (accel != NULL && strcmp(accel, "MPU6500") == 0) {
450449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            list[Accelerometer].maxRange = ACCEL_MPU6500_RANGE;
450549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            list[Accelerometer].resolution = ACCEL_MPU6500_RESOLUTION;
450649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            list[Accelerometer].power = ACCEL_MPU6500_POWER;
450749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            list[Accelerometer].minDelay = ACCEL_MPU6500_MINDELAY;
450849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            return;
450949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow         } else if (accel != NULL && strcmp(accel, "MPU6515") == 0) {
451049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            list[Accelerometer].maxRange = ACCEL_MPU6500_RANGE;
451149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            list[Accelerometer].resolution = ACCEL_MPU6500_RESOLUTION;
451249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            list[Accelerometer].power = ACCEL_MPU6500_POWER;
451349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            list[Accelerometer].minDelay = ACCEL_MPU6500_MINDELAY;
451449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            return;
451549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        } else if (accel != NULL && strcmp(accel, "MPU6500") == 0) {
451649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            list[Accelerometer].maxRange = ACCEL_MPU6500_RANGE;
451749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            list[Accelerometer].resolution = ACCEL_MPU6500_RESOLUTION;
451849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            list[Accelerometer].power = ACCEL_MPU6500_POWER;
451949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            list[Accelerometer].minDelay = ACCEL_MPU6500_MINDELAY;
452049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            return;
452149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        } else if (accel != NULL && strcmp(accel, "MPU6500") == 0) {
452249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            list[Accelerometer].maxRange = ACCEL_MPU6500_RANGE;
452349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            list[Accelerometer].resolution = ACCEL_MPU6500_RESOLUTION;
452449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            list[Accelerometer].power = ACCEL_MPU6500_POWER;
452549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            list[Accelerometer].minDelay = ACCEL_MPU6500_MINDELAY;
452649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            return;
452749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        } else if (accel != NULL && strcmp(accel, "MPU9150") == 0) {
452849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            list[Accelerometer].maxRange = ACCEL_MPU9150_RANGE;
452949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            list[Accelerometer].resolution = ACCEL_MPU9150_RESOLUTION;
453049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            list[Accelerometer].power = ACCEL_MPU9150_POWER;
453149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            list[Accelerometer].minDelay = ACCEL_MPU9150_MINDELAY;
453249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            return;
453349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        } else if (accel != NULL && strcmp(accel, "MPU3050") == 0) {
453449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            list[Accelerometer].maxRange = ACCEL_BMA250_RANGE;
453549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            list[Accelerometer].resolution = ACCEL_BMA250_RESOLUTION;
453649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            list[Accelerometer].power = ACCEL_BMA250_POWER;
453749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            list[Accelerometer].minDelay = ACCEL_BMA250_MINDELAY;
453849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            return;
453949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        }
454049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    }
454149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
454249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    LOGE("HAL:unknown accel id %s -- "
454349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow         "params default to bma250 and might be wrong.",
454449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow         accel);
454549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    list[Accelerometer].maxRange = ACCEL_BMA250_RANGE;
454649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    list[Accelerometer].resolution = ACCEL_BMA250_RESOLUTION;
454749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    list[Accelerometer].power = ACCEL_BMA250_POWER;
454849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    list[Accelerometer].minDelay = ACCEL_BMA250_MINDELAY;
454949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow}
455049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
455149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chowvoid MPLSensor::fillGyro(const char* gyro, struct sensor_t *list)
455249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow{
455349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    VFUNC_LOG;
455449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
455549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    if ( gyro != NULL && strcmp(gyro, "MPU3050") == 0) {
455649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        list[Gyro].maxRange = GYRO_MPU3050_RANGE;
455749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        list[Gyro].resolution = GYRO_MPU3050_RESOLUTION;
455849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        list[Gyro].power = GYRO_MPU3050_POWER;
455949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        list[Gyro].minDelay = GYRO_MPU3050_MINDELAY;
456049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    } else if( gyro != NULL && strcmp(gyro, "MPU6050") == 0) {
456149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        list[Gyro].maxRange = GYRO_MPU6050_RANGE;
456249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        list[Gyro].resolution = GYRO_MPU6050_RESOLUTION;
456349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        list[Gyro].power = GYRO_MPU6050_POWER;
456449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        list[Gyro].minDelay = GYRO_MPU6050_MINDELAY;
456549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    } else if( gyro != NULL && strcmp(gyro, "MPU6500") == 0) {
456649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        list[Gyro].maxRange = GYRO_MPU6500_RANGE;
456749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        list[Gyro].resolution = GYRO_MPU6500_RESOLUTION;
456849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        list[Gyro].power = GYRO_MPU6500_POWER;
456949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        list[Gyro].minDelay = GYRO_MPU6500_MINDELAY;
457049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow     } else if( gyro != NULL && strcmp(gyro, "MPU6515") == 0) {
457149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        list[Gyro].maxRange = GYRO_MPU6500_RANGE;
457249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        list[Gyro].resolution = GYRO_MPU6500_RESOLUTION;
457349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        list[Gyro].power = GYRO_MPU6500_POWER;
457449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        list[Gyro].minDelay = GYRO_MPU6500_MINDELAY;
457549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    } else if( gyro != NULL && strcmp(gyro, "MPU9150") == 0) {
457649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        list[Gyro].maxRange = GYRO_MPU9150_RANGE;
457749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        list[Gyro].resolution = GYRO_MPU9150_RESOLUTION;
457849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        list[Gyro].power = GYRO_MPU9150_POWER;
457949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        list[Gyro].minDelay = GYRO_MPU9150_MINDELAY;
458049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    } else {
458149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        LOGE("HAL:unknown gyro id -- gyro params will be wrong.");
458249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        LOGE("HAL:default to use mpu3050 params");
458349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        list[Gyro].maxRange = GYRO_MPU3050_RANGE;
458449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        list[Gyro].resolution = GYRO_MPU3050_RESOLUTION;
458549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        list[Gyro].power = GYRO_MPU3050_POWER;
458649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        list[Gyro].minDelay = GYRO_MPU3050_MINDELAY;
458749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    }
458849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
458949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    list[RawGyro].maxRange = list[Gyro].maxRange;
459049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    list[RawGyro].resolution = list[Gyro].resolution;
459149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    list[RawGyro].power = list[Gyro].power;
459249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    list[RawGyro].minDelay = list[Gyro].minDelay;
459349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
459449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    return;
459549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow}
459649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
459749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow/* fillRV depends on values of gyro, accel and compass in the list */
459849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chowvoid MPLSensor::fillRV(struct sensor_t *list)
459949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow{
460049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    VFUNC_LOG;
460149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
460249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    /* compute power on the fly */
460349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    list[RotationVector].power = list[Gyro].power +
460449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                                 list[Accelerometer].power +
460549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                                 list[MagneticField].power;
460649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    list[RotationVector].resolution = .00001;
460749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    list[RotationVector].maxRange = 1.0;
460849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    list[RotationVector].minDelay = 5000;
460949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
461049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    return;
461149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow}
461249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
461349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow/* fillGMRV depends on values of accel and mag in the list */
461449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chowvoid MPLSensor::fillGMRV(struct sensor_t *list)
461549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow{
461649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    VFUNC_LOG;
461749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
461849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    /* compute power on the fly */
461949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    list[GeomagneticRotationVector].power = list[Accelerometer].power +
462049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                                 list[MagneticField].power;
462149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    list[GeomagneticRotationVector].resolution = .00001;
462249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    list[GeomagneticRotationVector].maxRange = 1.0;
462349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    list[GeomagneticRotationVector].minDelay = 5000;
462449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
462549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    return;
462649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow}
462749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
462849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow/* fillGRV depends on values of gyro and accel in the list */
462949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chowvoid MPLSensor::fillGRV(struct sensor_t *list)
463049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow{
463149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    VFUNC_LOG;
463249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
463349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    /* compute power on the fly */
463449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    list[GameRotationVector].power = list[Gyro].power +
463549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                                 list[Accelerometer].power;
463649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    list[GameRotationVector].resolution = .00001;
463749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    list[GameRotationVector].maxRange = 1.0;
463849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    list[GameRotationVector].minDelay = 5000;
463949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
464049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    return;
464149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow}
464249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
464349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chowvoid MPLSensor::fillOrientation(struct sensor_t *list)
464449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow{
464549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    VFUNC_LOG;
464649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
464749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    list[Orientation].power = list[Gyro].power +
464849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                              list[Accelerometer].power +
464949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                              list[MagneticField].power;
465049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    list[Orientation].resolution = .00001;
465149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    list[Orientation].maxRange = 360.0;
465249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    list[Orientation].minDelay = 5000;
465349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
465449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    return;
465549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow}
465649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
465749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chowvoid MPLSensor::fillGravity( struct sensor_t *list)
465849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow{
465949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    VFUNC_LOG;
466049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
466149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    list[Gravity].power = list[Gyro].power +
466249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                          list[Accelerometer].power +
466349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                          list[MagneticField].power;
466449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    list[Gravity].resolution = .00001;
466549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    list[Gravity].maxRange = 9.81;
466649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    list[Gravity].minDelay = 5000;
466749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
466849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    return;
466949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow}
467049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
467149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chowvoid MPLSensor::fillLinearAccel(struct sensor_t *list)
467249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow{
467349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    VFUNC_LOG;
467449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
467549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    list[LinearAccel].power = list[Gyro].power +
467649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                          list[Accelerometer].power +
467749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                          list[MagneticField].power;
467849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    list[LinearAccel].resolution = list[Accelerometer].resolution;
467949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    list[LinearAccel].maxRange = list[Accelerometer].maxRange;
468049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    list[LinearAccel].minDelay = 5000;
468149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
468249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    return;
468349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow}
468449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
468549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chowvoid MPLSensor::fillSignificantMotion(struct sensor_t *list)
468649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow{
468749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    VFUNC_LOG;
468849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
468949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    list[SignificantMotion].power = list[Accelerometer].power;
469049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    list[SignificantMotion].resolution = 1;
469149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    list[SignificantMotion].maxRange = 1;
469249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    list[SignificantMotion].minDelay = -1;
469349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow}
469449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
469549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow#ifdef ENABLE_DMP_SCREEN_AUTO_ROTATION
469649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chowvoid MPLSensor::fillScreenOrientation(struct sensor_t *list)
469749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow{
469849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    VFUNC_LOG;
469949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
470049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    list[NumSensors].power = list[Accelerometer].power;
470149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    list[NumSensors].resolution = 1;
470249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    list[NumSensors].maxRange = 3;
470349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    list[NumSensors].minDelay = 0;
470449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow}
470549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow#endif
470649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
470749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chowint MPLSensor::inv_init_sysfs_attributes(void)
470849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow{
470949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    VFUNC_LOG;
471049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
471149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    unsigned char i = 0;
471249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    char sysfs_path[MAX_SYSFS_NAME_LEN];
47134a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    char tbuf[2];
471449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    char *sptr;
471549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    char **dptr;
471649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    int num;
471749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
471849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    memset(sysfs_path, 0, sizeof(sysfs_path));
471949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
472049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    sysfs_names_ptr =
472149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            (char*)malloc(sizeof(char[MAX_SYSFS_ATTRB][MAX_SYSFS_NAME_LEN]));
472249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    sptr = sysfs_names_ptr;
472349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    if (sptr != NULL) {
472449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        dptr = (char**)&mpu;
472549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        do {
472649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            *dptr++ = sptr;
472749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            memset(sptr, 0, sizeof(sptr));
472849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            sptr += sizeof(char[MAX_SYSFS_NAME_LEN]);
472949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        } while (++i < MAX_SYSFS_ATTRB);
473049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    } else {
473149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        LOGE("HAL:couldn't alloc mem for sysfs paths");
473249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        return -1;
473349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    }
473449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
473549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    // get proper (in absolute) IIO path & build MPU's sysfs paths
473649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    inv_get_sysfs_path(sysfs_path);
473749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
47384a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    if (strcmp(sysfs_path, "") == 0)
473949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        return 0;
474049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
474149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    memcpy(mSysfsPath, sysfs_path, sizeof(sysfs_path));
474249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    sprintf(mpu.key, "%s%s", sysfs_path, "/key");
474349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    sprintf(mpu.chip_enable, "%s%s", sysfs_path, "/buffer/enable");
474449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    sprintf(mpu.buffer_length, "%s%s", sysfs_path, "/buffer/length");
474549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    sprintf(mpu.power_state, "%s%s", sysfs_path, "/power_state");
474649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
474749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    sprintf(mpu.in_timestamp_en, "%s%s", sysfs_path,
474849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            "/scan_elements/in_timestamp_en");
474949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    sprintf(mpu.in_timestamp_index, "%s%s", sysfs_path,
475049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            "/scan_elements/in_timestamp_index");
475149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    sprintf(mpu.in_timestamp_type, "%s%s", sysfs_path,
475249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            "/scan_elements/in_timestamp_type");
475349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
475449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    sprintf(mpu.dmp_firmware, "%s%s", sysfs_path, "/dmp_firmware");
475549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    sprintf(mpu.firmware_loaded, "%s%s", sysfs_path, "/firmware_loaded");
475649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    sprintf(mpu.dmp_on, "%s%s", sysfs_path, "/dmp_on");
475749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    sprintf(mpu.dmp_int_on, "%s%s", sysfs_path, "/dmp_int_on");
475849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    sprintf(mpu.dmp_event_int_on, "%s%s", sysfs_path, "/dmp_event_int_on");
475949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    sprintf(mpu.tap_on, "%s%s", sysfs_path, "/tap_on");
476049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
476149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    sprintf(mpu.self_test, "%s%s", sysfs_path, "/self_test");
476249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
476349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    sprintf(mpu.temperature, "%s%s", sysfs_path, "/temperature");
476449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    sprintf(mpu.gyro_enable, "%s%s", sysfs_path, "/gyro_enable");
476549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    sprintf(mpu.gyro_fifo_rate, "%s%s", sysfs_path, "/sampling_frequency");
476649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    sprintf(mpu.gyro_orient, "%s%s", sysfs_path, "/gyro_matrix");
476749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    sprintf(mpu.gyro_fifo_enable, "%s%s", sysfs_path, "/gyro_fifo_enable");
476849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    sprintf(mpu.gyro_fsr, "%s%s", sysfs_path, "/in_anglvel_scale");
476949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    sprintf(mpu.gyro_fifo_enable, "%s%s", sysfs_path, "/gyro_fifo_enable");
47704a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    sprintf(mpu.gyro_rate, "%s%s", sysfs_path, "/gyro_rate");
477149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
477249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    sprintf(mpu.accel_enable, "%s%s", sysfs_path, "/accel_enable");
477349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    sprintf(mpu.accel_fifo_rate, "%s%s", sysfs_path, "/sampling_frequency");
477449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    sprintf(mpu.accel_orient, "%s%s", sysfs_path, "/accel_matrix");
477549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    sprintf(mpu.accel_fifo_enable, "%s%s", sysfs_path, "/accel_fifo_enable");
47764a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    sprintf(mpu.accel_rate, "%s%s", sysfs_path, "/accel_rate");
477749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
477849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow#ifndef THIRD_PARTY_ACCEL //MPUxxxx
477949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    sprintf(mpu.accel_fsr, "%s%s", sysfs_path, "/in_accel_scale");
478049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
478149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    // DMP uses these values
478249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    sprintf(mpu.in_accel_x_dmp_bias, "%s%s", sysfs_path, "/in_accel_x_dmp_bias");
478349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    sprintf(mpu.in_accel_y_dmp_bias, "%s%s", sysfs_path, "/in_accel_y_dmp_bias");
478449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    sprintf(mpu.in_accel_z_dmp_bias, "%s%s", sysfs_path, "/in_accel_z_dmp_bias");
478549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
478649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    // MPU bias value is not set on purpose -
478749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    // raw accel value with factory cal is not requested
478849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow#endif
478949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
479049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    // DMP uses these bias values
479149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    sprintf(mpu.in_gyro_x_dmp_bias, "%s%s", sysfs_path, "/in_anglvel_x_dmp_bias");
479249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    sprintf(mpu.in_gyro_y_dmp_bias, "%s%s", sysfs_path, "/in_anglvel_y_dmp_bias");
479349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    sprintf(mpu.in_gyro_z_dmp_bias, "%s%s", sysfs_path, "/in_anglvel_z_dmp_bias");
479449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
479549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    // MPU uses these bias values
479649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    sprintf(mpu.in_gyro_x_offset, "%s%s", sysfs_path, "/in_anglvel_x_offset");
479749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    sprintf(mpu.in_gyro_y_offset, "%s%s", sysfs_path, "/in_anglvel_y_offset");
479849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    sprintf(mpu.in_gyro_z_offset, "%s%s", sysfs_path, "/in_anglvel_z_offset");
47994a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    sprintf(mpu.in_gyro_self_test_scale, "%s%s", sysfs_path, "/in_anglvel_self_test_scale");
480049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
480149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    sprintf(mpu.three_axis_q_on, "%s%s", sysfs_path, "/three_axes_q_on"); //formerly quaternion_on
48024a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    sprintf(mpu.three_axis_q_rate, "%s%s", sysfs_path, "/three_axes_q_rate");
48034a28f9c897c46c42a255823f7e307169a828a025Rosa Chow
480449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    sprintf(mpu.ped_q_on, "%s%s", sysfs_path, "/ped_q_on");
48054a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    sprintf(mpu.ped_q_rate, "%s%s", sysfs_path, "/ped_q_rate");
48064a28f9c897c46c42a255823f7e307169a828a025Rosa Chow
480749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    sprintf(mpu.six_axis_q_on, "%s%s", sysfs_path, "/six_axes_q_on");
48084a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    sprintf(mpu.six_axis_q_rate, "%s%s", sysfs_path, "/six_axes_q_rate");
48094a28f9c897c46c42a255823f7e307169a828a025Rosa Chow
48104a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    sprintf(mpu.step_detector_on, "%s%s", sysfs_path, "/step_detector_on");
48114a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    sprintf(mpu.step_indicator_on, "%s%s", sysfs_path, "/step_indicator_on");
481249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
481349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    sprintf(mpu.display_orientation_on, "%s%s", sysfs_path,
481449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            "/display_orientation_on");
481549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    sprintf(mpu.event_display_orientation, "%s%s", sysfs_path,
481649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            "/event_display_orientation");
481749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
481849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    sprintf(mpu.event_smd, "%s%s", sysfs_path,
481949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            "/event_smd");
482049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    sprintf(mpu.smd_enable, "%s%s", sysfs_path,
482149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            "/smd_enable");
482249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    sprintf(mpu.smd_delay_threshold, "%s%s", sysfs_path,
482349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            "/smd_delay_threshold");
482449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    sprintf(mpu.smd_delay_threshold2, "%s%s", sysfs_path,
482549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            "/smd_delay_threshold2");
482649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    sprintf(mpu.smd_threshold, "%s%s", sysfs_path,
482749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            "/smd_threshold");
482849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    sprintf(mpu.batchmode_timeout, "%s%s", sysfs_path,
482949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            "/batchmode_timeout");
483049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    sprintf(mpu.batchmode_wake_fifo_full_on, "%s%s", sysfs_path,
483149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            "/batchmode_wake_fifo_full_on");
483249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    sprintf(mpu.pedometer_on, "%s%s", sysfs_path,
483349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            "/pedometer_on");
483449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    sprintf(mpu.pedometer_int_on, "%s%s", sysfs_path,
483549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            "/pedometer_int_on");
483649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    sprintf(mpu.event_pedometer, "%s%s", sysfs_path,
483749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            "/event_pedometer");
483849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    sprintf(mpu.pedometer_steps, "%s%s", sysfs_path,
483949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            "/pedometer_steps");
484049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    return 0;
484149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow}
484249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
484349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chowbool MPLSensor::isMpuNonDmp(void)
484449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow{
484549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    if (!strcmp(chip_ID, "mpu3050") || !strcmp(chip_ID, "MPU3050"))
484649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        return true;
484749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    else
484849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        return false;
484949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow}
485049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
485149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chowint MPLSensor::isLowPowerQuatEnabled(void)
485249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow{
485349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow#ifdef ENABLE_LP_QUAT_FEAT
485449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    return !isMpuNonDmp();
485549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow#else
485649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    return 0;
485749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow#endif
485849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow}
485949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
486049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chowint MPLSensor::isDmpDisplayOrientationOn(void)
486149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow{
486249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow#ifdef ENABLE_DMP_DISPL_ORIENT_FEAT
486349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    if (isMpuNonDmp())
486449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        return 0;
486549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    return 1;
486649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow#else
486749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    return 0;
486849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow#endif
486949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow}
487049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
487149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow/* these functions can be consolidated
487249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chowwith inv_convert_to_body_with_scale */
487349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chowvoid MPLSensor::getCompassBias()
487449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow{
487549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    VFUNC_LOG;
487649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
487749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
487849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    long bias[3];
487949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    long compassBias[3];
488049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    unsigned short orient;
488149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    signed char orientMtx[9];
488249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    mCompassSensor->getOrientationMatrix(orientMtx);
488349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    orient = inv_orientation_matrix_to_scalar(orientMtx);
488449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    /* Get Values from MPL */
488549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    inv_get_compass_bias(bias);
488649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    //inv_convert_to_body_with_scale(unsigned short orientation, long sensitivity, const long *input, long *output);
488749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    inv_convert_to_body(orient, bias, compassBias);
48884a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    LOGV_IF(HANDLER_DATA, "Mpl Compass Bias (HW unit) %ld %ld %ld", bias[0], bias[1], bias[2]);
48894a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    LOGV_IF(HANDLER_DATA, "Mpl Compass Bias (HW unit) (body) %ld %ld %ld", compassBias[0], compassBias[1], compassBias[2]);
489049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    long compassSensitivity = inv_get_compass_sensitivity();
489149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    if (compassSensitivity == 0) {
489249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        compassSensitivity = mCompassScale;
489349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    }
489449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    for(int i=0; i<3; i++) {
489549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        /* convert to uT */
489649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        float temp = (float) compassSensitivity / (1L << 30);
489749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        mCompassBias[i] =(float) (compassBias[i] * temp / 65536.f);
489849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    }
489949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
490049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    return;
490149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow}
490249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
490349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chowvoid MPLSensor::getFactoryGyroBias()
490449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow{
490549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    VFUNC_LOG;
490649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
490749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    //TODO: mllite needs to add this function
490849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    //if(inv_factory_bias_available) {
490949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        /* Get Values from MPL */
491049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        inv_get_gyro_bias(mFactoryGyroBias);
49114a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        LOGV_IF(ENG_VERBOSE, "Factory Gyro Bias %ld %ld %ld", mFactoryGyroBias[0], mFactoryGyroBias[1], mFactoryGyroBias[2]);
491249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        mFactoryGyroBiasAvailable = true;
491349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    //}
491449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
491549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    return;
491649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow}
491749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
49184a28f9c897c46c42a255823f7e307169a828a025Rosa Chow/* set bias from factory cal file to MPU offset
49194a28f9c897c46c42a255823f7e307169a828a025Rosa Chow/* x = values store in cal file --> (v/1000 * 2^16 / (2000/250))
49204a28f9c897c46c42a255823f7e307169a828a025Rosa Chow/* offset = x/2^16 * (Gyro scale / self test scale used) * (-1) / offset scale
49214a28f9c897c46c42a255823f7e307169a828a025Rosa Chow/* i.e. self test default scale = 250
49224a28f9c897c46c42a255823f7e307169a828a025Rosa Chow/*       gyro scale default to = 2000
49234a28f9c897c46c42a255823f7e307169a828a025Rosa Chow/*       offset scale = 4 //as spec by hardware
49244a28f9c897c46c42a255823f7e307169a828a025Rosa Chow/*       offset = x/2^16 * (8) * (-1) / (4)
49254a28f9c897c46c42a255823f7e307169a828a025Rosa Chow*/
49264a28f9c897c46c42a255823f7e307169a828a025Rosa Chow
492749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chowvoid MPLSensor::setFactoryGyroBias()
492849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow{
492949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    VFUNC_LOG;
49304a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    int scaleRatio = mGyroScale / mGyroSelfTestScale;
49314a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    int offsetScale = 4;
49324a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    LOGV_IF(PROCESS_VERBOSE, "HAL: scaleRatio used =%d", scaleRatio);
49334a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    LOGV_IF(PROCESS_VERBOSE, "HAL: offsetScale used =%d", offsetScale);
493449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
493549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    /* Write to Driver */
49364a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)",
49374a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            (((int) (((float) mFactoryGyroBias[0]) / 65536.f * scaleRatio)) * -1 / offsetScale),
49384a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            mpu.in_gyro_x_offset, getTimestamp());
49394a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    if(write_attribute_sensor_continuous(gyro_x_offset_fd,
49404a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        (((int) (((float) mFactoryGyroBias[0]) / 65536.f * scaleRatio)) * -1 / offsetScale)) < 0)
494149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    {
494249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        LOGE("HAL:Error writing to gyro_x_offset");
494349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        return;
494449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    }
49454a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)",
49464a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            (((int) (((float) mFactoryGyroBias[1]) / 65536.f * scaleRatio)) * -1 / offsetScale),
49474a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            mpu.in_gyro_y_offset, getTimestamp());
49484a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    if(write_attribute_sensor_continuous(gyro_y_offset_fd,
49494a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        (((int) (((float) mFactoryGyroBias[1]) / 65536.f * scaleRatio)) * -1 / offsetScale)) < 0)
495049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    {
495149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        LOGE("HAL:Error writing to gyro_y_offset");
495249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        return;
495349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    }
49544a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)",
49554a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            (((int) (((float) mFactoryGyroBias[2]) / 65536.f * scaleRatio)) * -1 / offsetScale),
49564a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            mpu.in_gyro_z_offset, getTimestamp());
49574a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    if(write_attribute_sensor_continuous(gyro_z_offset_fd,
49584a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        (((int) (((float) mFactoryGyroBias[2]) / 65536.f * scaleRatio)) * -1 / offsetScale)) < 0)
495949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    {
496049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        LOGE("HAL:Error writing to gyro_z_offset");
496149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        return;
496249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    }
496349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    mFactoryGyroBiasAvailable = false;
496449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    LOGV_IF(EXTRA_VERBOSE, "HAL:Factory Gyro Calibrated Bias Applied");
496549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
496649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    return;
496749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow}
496849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
496949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow/* these functions can be consolidated
497049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chowwith inv_convert_to_body_with_scale */
497149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chowvoid MPLSensor::getGyroBias()
497249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow{
497349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    VFUNC_LOG;
497449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
497549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    long *temp = NULL;
497649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    long chipBias[3];
497749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    long bias[3];
497849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    unsigned short orient;
497949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
498049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    /* Get Values from MPL */
498149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    inv_get_mpl_gyro_bias(mGyroChipBias, temp);
498249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    orient = inv_orientation_matrix_to_scalar(mGyroOrientation);
498349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    //void inv_convert_to_body_with_scale(unsigned short orientation, long sensitivity, const long *input, long *output);
498449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    inv_convert_to_body(orient, mGyroChipBias, bias);
49854a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    LOGV_IF(ENG_VERBOSE, "Mpl Gyro Bias (HW unit) %ld %ld %ld", mGyroChipBias[0], mGyroChipBias[1], mGyroChipBias[2]);
49864a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    LOGV_IF(ENG_VERBOSE, "Mpl Gyro Bias (HW unit) (body) %ld %ld %ld", bias[0], bias[1], bias[2]);
498749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    long gyroSensitivity = inv_get_gyro_sensitivity();
498849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    if(gyroSensitivity == 0) {
498949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        gyroSensitivity = mGyroScale;
499049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    }
49914a28f9c897c46c42a255823f7e307169a828a025Rosa Chow
499249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    /* scale and convert to rad */
499349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    for(int i=0; i<3; i++) {
499449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        float temp = (float) gyroSensitivity / (1L << 30);
499549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        mGyroBias[i] = (float) (bias[i] * temp / (1<<16) / 180 * M_PI);
499649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        if (mGyroBias[i] != 0)
499749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            mGyroBiasAvailable = true;
499849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    }
499949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
500049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    return;
500149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow}
500249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
500349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chowvoid MPLSensor::setGyroBias()
500449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow{
500549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    VFUNC_LOG;
500649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
500749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    if(mGyroBiasAvailable == false)
500849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        return;
500949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
501049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    long bias[3];
501149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    long gyroSensitivity = inv_get_gyro_sensitivity();
501249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
501349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    if(gyroSensitivity == 0) {
501449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        gyroSensitivity = mGyroScale;
501549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    }
50164a28f9c897c46c42a255823f7e307169a828a025Rosa Chow
50174a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    inv_get_gyro_bias_dmp_units(bias);
501849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
501949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    /* Write to Driver */
502049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %ld > %s (%lld)",
502149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            bias[0], mpu.in_gyro_x_dmp_bias, getTimestamp());
502249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    if(write_attribute_sensor_continuous(gyro_x_dmp_bias_fd, bias[0]) < 0)
502349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    {
502449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        LOGE("HAL:Error writing to gyro_x_dmp_bias");
502549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        return;
502649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    }
502749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %ld > %s (%lld)",
502849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            bias[1], mpu.in_gyro_y_dmp_bias, getTimestamp());
502949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    if(write_attribute_sensor_continuous(gyro_y_dmp_bias_fd, bias[1]) < 0)
503049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    {
503149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        LOGE("HAL:Error writing to gyro_y_dmp_bias");
503249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        return;
503349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    }
503449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %ld > %s (%lld)",
503549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            bias[2], mpu.in_gyro_z_dmp_bias, getTimestamp());
503649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    if(write_attribute_sensor_continuous(gyro_z_dmp_bias_fd, bias[2]) < 0)
503749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    {
503849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        LOGE("HAL:Error writing to gyro_z_dmp_bias");
503949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        return;
504049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    }
504149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    mGyroBiasApplied = true;
504249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    mGyroBiasAvailable = false;
504349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    LOGV_IF(EXTRA_VERBOSE, "HAL:Gyro DMP Calibrated Bias Applied");
504449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
504549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    return;
504649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow}
504749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
504849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chowvoid MPLSensor::getFactoryAccelBias()
504949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow{
505049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    VFUNC_LOG;
505149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
50524a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    long temp;
505349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
50544a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    /* Get Values from MPL */
50554a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    inv_get_accel_bias(mAccelBias, &temp);
50564a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    LOGV_IF(HANDLER_DATA, "Factory Accel Bias (mg) %ld %ld %ld", mFactoryAccelBias[0], mFactoryAccelBias[1], mFactoryAccelBias[2]);
50574a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    mFactoryAccelBiasAvailable = true;
50584a28f9c897c46c42a255823f7e307169a828a025Rosa Chow
505949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    return;
506049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow}
506149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
506249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chowvoid MPLSensor::setFactoryAccelBias()
506349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow{
506449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    if(mFactoryAccelBiasAvailable == false)
506549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        return;
506649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
50674a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    /* TODO: add scaling here - depends on self test parameters */
50684a28f9c897c46c42a255823f7e307169a828a025Rosa Chow
506949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    /* Write to Driver */
507049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    if(write_attribute_sensor_continuous(accel_x_offset_fd, mFactoryAccelBias[0]) < 0)
507149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    {
507249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        LOGE("HAL:Error writing to accel_x_offset");
507349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        return;
507449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    }
507549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    if(write_attribute_sensor_continuous(accel_y_offset_fd, mFactoryAccelBias[1]) < 0)
507649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    {
507749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        LOGE("HAL:Error writing to accel_y_offset");
507849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        return;
507949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    }
508049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    if(write_attribute_sensor_continuous(accel_z_offset_fd, mFactoryAccelBias[2]) < 0)
508149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    {
508249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        LOGE("HAL:Error writing to accel_z_offset");
508349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        return;
508449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    }
508549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    mFactoryAccelBiasAvailable = false;
508649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    LOGV_IF(EXTRA_VERBOSE, "HAL:Factory Accel Calibrated Bias Applied");
508749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
508849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    return;
508949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow}
509049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
509149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chowvoid MPLSensor::getAccelBias()
509249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow{
509349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    VFUNC_LOG;
50944a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    long temp;
509549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
50964a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    /* Get Values from MPL */
50974a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    inv_get_accel_bias(mAccelBias, &temp);
50984a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    LOGV_IF(ENG_VERBOSE, "Accel Bias (mg) %ld %ld %ld", mAccelBias[0], mAccelBias[1], mAccelBias[2]);
50994a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    mAccelBiasAvailable = true;
510049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
510149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    return;
510249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow}
510349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
510449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chowvoid MPLSensor::setAccelBias()
510549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow{
510649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    VFUNC_LOG;
510749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
510849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    if(mAccelBiasAvailable == false)
510949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        return;
511049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
51114a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    long bias[3];
51124a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    unsigned short orient = inv_orientation_matrix_to_scalar(mAccelOrientation);
51134a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    inv_convert_to_body(orient, mAccelBias, bias);
51144a28f9c897c46c42a255823f7e307169a828a025Rosa Chow
511549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    /* Write to Driver */
511649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %ld > %s (%lld)",
51174a28f9c897c46c42a255823f7e307169a828a025Rosa Chow           (long) (mAccelBias[0] / 65536.f / 2), mpu.in_accel_x_dmp_bias, getTimestamp());
51184a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    if(write_attribute_sensor_continuous(accel_x_dmp_bias_fd, (long)(mAccelBias[0] / 65536.f / 2)) < 0)
511949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    {
512049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        LOGE("HAL:Error writing to accel_x_dmp_bias");
512149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        return;
512249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    }
512349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %ld > %s (%lld)",
51244a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            (long)(mAccelBias[1] / 65536.f / 2), mpu.in_accel_y_dmp_bias, getTimestamp());
51254a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    if(write_attribute_sensor_continuous(accel_y_dmp_bias_fd, (long)(mAccelBias[1] / 65536.f / 2)) < 0)
512649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    {
512749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        LOGE("HAL:Error writing to accel_y_dmp_bias");
512849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        return;
512949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    }
513049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %ld > %s (%lld)",
51314a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            (long)(mAccelBias[2] / 65536 / 2), mpu.in_accel_z_dmp_bias, getTimestamp());
51324a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    if(write_attribute_sensor_continuous(accel_z_dmp_bias_fd, (long)(mAccelBias[2] / 65536 / 2)) < 0)
513349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    {
513449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        LOGE("HAL:Error writing to accel_z_dmp_bias");
513549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        return;
513649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    }
513749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    mAccelBiasAvailable = false;
513849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    mAccelBiasApplied = true;
513949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    LOGV_IF(EXTRA_VERBOSE, "HAL:Accel DMP Calibrated Bias Applied");
514049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
514149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    return;
514249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow}
514349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
514449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chowint MPLSensor::isCompassDisabled(void)
514549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow{
514649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    if(mCompassSensor->getFd() < 0 && !mCompassSensor->isIntegrated()) {
514749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    LOGI_IF(EXTRA_VERBOSE, "HAL: Compass is disabled, Six-axis Sensor Fusion is used.");
514849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        return 1;
514949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    }
515049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    return 0;
515149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow}
515249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
51534a28f9c897c46c42a255823f7e307169a828a025Rosa Chow/* precondition: framework disallows this case, ie enable continuous sensor, */
51544a28f9c897c46c42a255823f7e307169a828a025Rosa Chow/* and enable batch sensor */
51554a28f9c897c46c42a255823f7e307169a828a025Rosa Chow/* if one sensor is in continuous mode, HAL disallows enabling batch for this sensor */
51564a28f9c897c46c42a255823f7e307169a828a025Rosa Chow/* or any other sensors */
515749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow#define DEBUG_BATCHING  (1)
515849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chowint MPLSensor::batch(int handle, int flags, int64_t period_ns, int64_t timeout)
515949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow{
516049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    VFUNC_LOG;
516149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
516249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    int res = 0;
516349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
516449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    if (isMpuNonDmp())
516549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        return res;
516649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
516749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    /* Enables batch mode and sets timeout for the given sensor */
516849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    /* enum SENSORS_BATCH_DRY_RUN, SENSORS_BATCH_WAKE_UPON_FIFO_FULL */
516949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    bool dryRun = false;
517049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    android::String8 sname;
517149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    int what = -1;
517249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    int enabled_sensors = mEnabled;
517349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    int batchMode = timeout > 0 ? 1 : 0;
517449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
517549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    LOGI_IF(DEBUG_BATCHING || ENG_VERBOSE,
517649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            "HAL:batch called - handle=%d, flags=%d, period=%lld, timeout=%lld",
517749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            handle, flags, period_ns, timeout);
517849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
517949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    if(flags & (1 << SENSORS_BATCH_DRY_RUN)) {
518049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        dryRun = true;
518149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        LOGI_IF(PROCESS_VERBOSE,
518249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                "HAL:batch - dry run mode is set (%d)", SENSORS_BATCH_DRY_RUN);
518349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    }
518449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
518549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    getHandle(handle, what, sname);
518649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    if(uint32_t(what) >= NumSensors) {
518749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        LOGE("HAL:batch sensors %d not found", what);
518849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        return -EINVAL;
518949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    }
519049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
519149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    int tempBatch = 0;
519249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    if (timeout > 0) {
519349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        tempBatch = mBatchEnabled | (1 << what);
519449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    } else {
519549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        tempBatch = mBatchEnabled & ~(1 << what);
519649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    }
519749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
519849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    if (!computeBatchSensorMask(mEnabled, tempBatch)) {
519949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        batchMode = 0;
52004a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    } else {
52014a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        batchMode = 1;
520249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    }
52034a28f9c897c46c42a255823f7e307169a828a025Rosa Chow
520449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    /* Supported sensors: Accel, Gyro, Raw Gyro, Compass, Raw Compass, GRV, Step Detector */
520549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    switch (what) {
520649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    case Orientation:
520749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    case LinearAccel:
520849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    case Gravity:
52094a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    case RotationVector:
521049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    case GeomagneticRotationVector:
521149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    case SignificantMotion:
521249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    case ID_SC:
521349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    case ID_SO:
521449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        LOGE("HAL:batch - "
521549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow             "sensor (handle %d) is not supported in batch mode", handle);
521649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        return -EINVAL;
521749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    }
521849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
521949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    /* get maximum possible bytes to batch per sample */
522049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    /* get minimum delay for each requested sensor    */
522149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    ssize_t nBytes = 0;
522249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    int64_t wanted = 1000000000LL, ns = 0;
522349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    int64_t timeoutInMs = 0;
522449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    for (int i = 0; i < NumSensors; i++) {
522549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        if (batchMode == 1) {
52264a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            ns = mBatchDelays[i];
522749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            LOGV_IF(DEBUG_BATCHING || EXTRA_VERBOSE,
52284a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                    "HAL:batch - requested sensor=0x%01x, batch delay=%lld", mEnabled & (1 << i), ns);
522949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            // take the min delay ==> max rate
523049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            wanted = (ns < wanted) ? ns : wanted;
523149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            if (i <= RawMagneticField) {
523249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                nBytes += 8;
523349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            }
523449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            if (i == Pressure) {
523549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                nBytes += 6;
523649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            }
523749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            if ((i == StepDetector) || (i == GameRotationVector)) {
523849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                nBytes += 16;
523949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            }
524049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        }
524149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    }
524249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
524349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    /* check if we can support issuing interrupt before FIFO fills-up */
524449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    /* in the given timeout.                                          */
524549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    if ((flags & (1 << SENSORS_BATCH_WAKE_UPON_FIFO_FULL)) &&
524649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            (batchMode == 1)) {
52474a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            LOGE("HAL: batch SENSORS_BATCH_WAKE_UPON_FIFO_FULL is not supported");
52484a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            return -EINVAL;
52494a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        /* provide messge if it exceeds hardware capability
525049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        if (nSamples * nBytes >= 1024) {
525149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            LOGE("HAL:batch - timeout - configuration is not supported, "
525249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                 "cannot provide requested amount of buffering (%lld ms)",
525349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                 timeout / 1000000LL);
52544a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        }*/
525549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    }
525649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
525749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    if(dryRun == true)
525849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        return 0;
525949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
526049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    /* starting from code below,  we will modify hardware */
526149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    /* first edit global batch mode mask */
526249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
52634a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    if (!timeout) {
526449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        mBatchEnabled &= ~(1 << what);
526549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        mBatchDelays[what] = 1000000000L;
52664a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        mBatchTimeouts[what] = 30000000000LL;
526749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        if (mBatchEnabled == 0) {
526849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            mFeatureActiveMask &= ~INV_DMP_BATCH_MODE;
526949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        }
527049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    } else {
527149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        mBatchEnabled |= (1 << what);
527249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        mBatchDelays[what] = period_ns;
52734a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        mBatchTimeouts[what] = timeout;
527449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        mFeatureActiveMask |= INV_DMP_BATCH_MODE;
527549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    }
52764a28f9c897c46c42a255823f7e307169a828a025Rosa Chow
52774a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    /* For these sensors, switch to different data output */
52784a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    /* These steps should be optimized at some point */
52794a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    int featureMask = computeBatchDataOutput();
52804a28f9c897c46c42a255823f7e307169a828a025Rosa Chow
52814a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    LOGV_IF(ENG_VERBOSE, "batchMode =%d, featureMask=0x%x, mEnabled=%d",
52824a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                batchMode, featureMask, mEnabled);
528349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    if (DEBUG_BATCHING || EXTRA_VERBOSE) {
528449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        LOGV("HAL:batch - sensor=0x%01x", mBatchEnabled);
52854a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        for (int d = 0; d < NumSensors; d++) {
52864a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            LOGV("HAL:batch - sensor status=0x%01x batch status=0x%01x timeout=%lld delay=%lld",
52874a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                            mEnabled & (1 << d), (mBatchEnabled & (1 << d)), mBatchTimeouts[d],
52884a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                            mBatchDelays[d]);
52894a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        }
52904a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    }
52914a28f9c897c46c42a255823f7e307169a828a025Rosa Chow
52924a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    /* take the minimum batchmode timeout */
52934a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    if (batchMode == 1) {
52944a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        int64_t tempTimeout = 30000000000LL;
52954a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        for (int i = 0; i < NumSensors; i++) {
52964a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            if ((mEnabled & (1 << i) && mBatchEnabled & (1 << i)) ||
52974a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                    (((featureMask & INV_DMP_PED_STANDALONE) && (mBatchEnabled & (1 << StepDetector))))) {
52984a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                LOGV_IF(ENG_VERBOSE, "i=%d, timeout=%lld", i, mBatchTimeouts[i]);
52994a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                ns = mBatchTimeouts[i];
53004a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                tempTimeout = (ns < tempTimeout) ? ns : tempTimeout;
53014a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            }
530249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        }
53034a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        timeout = tempTimeout;
53044a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        /* Convert ns to millisecond */
53054a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        timeoutInMs = timeout / 1000000;
53064a28f9c897c46c42a255823f7e307169a828a025Rosa Chow
53074a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        /* remember last timeout value */
53084a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        mBatchTimeoutInMs = timeoutInMs;
53094a28f9c897c46c42a255823f7e307169a828a025Rosa Chow
53104a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        /* TODO: Calculate nSamples */
53114a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        int nSamples = 0;
53124a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        nSamples = (unsigned long)(
53134a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            (1000000000.f / wanted) * ((float)timeout / 1000000000.f));
53144a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    } else {
53154a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        timeoutInMs = 0;
531649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    }
53174a28f9c897c46c42a255823f7e307169a828a025Rosa Chow
53184a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    LOGV_IF(DEBUG_BATCHING || EXTRA_VERBOSE,
53194a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                "HAL:batch - timeout - timeout=%lld ns, timeoutInMs=%lld, delay=%lld ns",
53204a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                timeout, timeoutInMs, wanted);
532149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
532249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    // reset master enable
532349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    res = masterEnable(0);
532449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    if (res < 0) {
532549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        return res;
532649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    }
532749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
53284a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    /* case for Ped standalone */
53294a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    if ((batchMode == 1) && (featureMask & INV_DMP_PED_STANDALONE) &&
53304a28f9c897c46c42a255823f7e307169a828a025Rosa Chow           (mFeatureActiveMask & INV_DMP_PEDOMETER)) {
53314a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        LOGI("ID_P only = 0x%x", mBatchEnabled);
53324a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        enablePedQuaternion(0);
53334a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        enablePedStandalone(1);
53344a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    } else {
53354a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        enablePedStandalone(0);
533649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        if (featureMask & INV_DMP_PED_QUATERNION) {
533749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            enableLPQuaternion(0);
533849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            enablePedQuaternion(1);
533949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        }
534049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    }
53414a28f9c897c46c42a255823f7e307169a828a025Rosa Chow
53424a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    /* case for Ped Quaternion */
53434a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    if ((batchMode == 1) && (featureMask & INV_DMP_PED_QUATERNION) &&
53444a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            (mEnabled & (1 << GameRotationVector)) &&
53454a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            (mFeatureActiveMask & INV_DMP_PEDOMETER)) {
53464a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        LOGI("ID_P and GRV or ALL = 0x%x", mBatchEnabled);
53474a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        LOGI("ID_P is enabled for batching, PED quat will be automatically enabled");
53484a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        enableLPQuaternion(0);
53494a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        enablePedQuaternion(1);
53504a28f9c897c46c42a255823f7e307169a828a025Rosa Chow
53514a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        wanted = mBatchDelays[GameRotationVector];
53524a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        /* set pedq rate */
53534a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)",
53544a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                int(1000000000.f / wanted), mpu.ped_q_rate,
53554a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                getTimestamp());
53564a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        write_sysfs_int(mpu.ped_q_rate, 1000000000.f / wanted);
53574a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        LOGV_IF(PROCESS_VERBOSE,
53584a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                "HAL:DMP ped quaternion rate %.2f Hz", 1000000000.f / wanted);
53594a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    } else if (!(featureMask & INV_DMP_PED_STANDALONE)){
53604a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        LOGI("Toggle back to normal 6 axis");
53614a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        if (mEnabled & (1 << GameRotationVector)) {
53624a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            enableLPQuaternion(1);
53634a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        }
53644a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        enablePedQuaternion(0);
536549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    }
536649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
53674a28f9c897c46c42a255823f7e307169a828a025Rosa Chow     /* case for Ped indicator */
53684a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    if ((batchMode == 1) && ((featureMask & INV_DMP_PED_INDICATOR))) {
53694a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        enablePedIndicator(1);
53704a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    } else {
53714a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        enablePedIndicator(0);
53724a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    }
53734a28f9c897c46c42a255823f7e307169a828a025Rosa Chow
53744a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    /* case for Six Axis Quaternion */
53754a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    if ((batchMode == 1) && (featureMask & INV_DMP_6AXIS_QUATERNION) &&
53764a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            (mEnabled & (1 << GameRotationVector))) {
537749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        LOGI("GRV = 0x%x", mBatchEnabled);
537849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        enableLPQuaternion(0);
537949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        enable6AxisQuaternion(1);
53804a28f9c897c46c42a255823f7e307169a828a025Rosa Chow
53814a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        wanted = mBatchDelays[GameRotationVector];
53824a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        /* set sixaxis rate */
53834a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)",
53844a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                int(1000000000.f / wanted), mpu.six_axis_q_rate,
53854a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                getTimestamp());
53864a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        write_sysfs_int(mpu.six_axis_q_rate, 1000000000.f / wanted);
53874a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        LOGV_IF(PROCESS_VERBOSE,
53884a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                "HAL:DMP three axis rate %.2f Hz", 1000000000.f / wanted);
53894a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    } else if (!(featureMask & INV_DMP_PED_QUATERNION)){
539049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        LOGI("Toggle back to normal 6 axis");
539149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        if (mEnabled & (1 << GameRotationVector)) {
539249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            enableLPQuaternion(1);
539349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        }
539449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        enable6AxisQuaternion(0);
53954a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    } else {
53964a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        enable6AxisQuaternion(0);
539749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    }
53984a28f9c897c46c42a255823f7e307169a828a025Rosa Chow
53994a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    /* TODO: This may make a come back some day */
540049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    /* write not to overflow hardware FIFO if flag is set */
54014a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    /*if (flags & (1 << SENSORS_BATCH_WAKE_UPON_FIFO_FULL)) {
540249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)",
540349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                0, mpu.batchmode_wake_fifo_full_on, getTimestamp());
540449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        if (write_sysfs_int(mpu.batchmode_wake_fifo_full_on, 0) < 0) {
540549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            LOGE("HAL:ERR can't write batchmode_wake_fifo_full_on");
540649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        }
54074a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    }*/
540849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
540949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    /* write required timeout to sysfs */
541049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %lld > %s (%lld)",
541149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            timeoutInMs, mpu.batchmode_timeout, getTimestamp());
541249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    if (write_sysfs_int(mpu.batchmode_timeout, timeoutInMs) < 0) {
541349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        LOGE("HAL:ERR can't write batchmode_timeout");
541449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    }
541549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
541649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    if (batchMode == 1) {
541749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        // enable DMP
541849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        res = onDmp(1);
541949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        if (res < 0) {
542049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            return res;
542149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        }
54224a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        // set batch rates
54234a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        if (setBatchDataRates() < 0) {
54244a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            LOGE("HAL:ERR can't set batch data rates");
54254a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        }
542649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        // default fifo rate to 200Hz
542749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)",
542849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                200, mpu.gyro_fifo_rate, getTimestamp());
542949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        if (write_sysfs_int(mpu.gyro_fifo_rate, 200) < 0) {
543049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            res = -1;
543149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            LOGE("HAL:ERR can't set DMP rate to 200Hz");
543249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            return res;
543349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        }
543449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    } else {
54354a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        if ((mFeatureActiveMask == 0) && !(mEnabled & VIRTUAL_SENSOR_ALL_MASK)) {
543649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            // disable DMP
543749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            res = onDmp(0);
543849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            if (res < 0) {
543949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                return res;
544049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            }
54414a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        }
54424a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        /* reset sensor rate */
54434a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        /*if (resetDataRates() < 0) {
54444a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            LOGE("HAL:ERR can't reset output rate back to original setting");
54454a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        }*/
544649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    }
544749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    if ((batchMode == 1) || enabled_sensors || mFeatureActiveMask) {
544849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        masterEnable(1);
544949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    }
545049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    return res;
545149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow}
545249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
545349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chowint MPLSensor::computeBatchDataOutput()
545449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow{
545549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    VFUNC_LOG;
545649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
545749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    int featureMask = 0;
545849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    if (mBatchEnabled == 0)
545949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        return 0;//h
546049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
54614a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    uint32_t hardwareSensorMask = (1<<Gyro) | (1<<RawGyro) | (1<<Accelerometer) | (1<<MagneticField) |
54624a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                                        (1<<RawMagneticField) | (1<<Pressure);
54634a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    LOGV_IF(ENG_VERBOSE, "hardwareSensorMask = 0x%0x, mBatchEnabled = 0x%0x", hardwareSensorMask, mBatchEnabled);
54644a28f9c897c46c42a255823f7e307169a828a025Rosa Chow
54654a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    if (mBatchEnabled & (1 << StepDetector)) {
54664a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        if (mBatchEnabled & (1 << GameRotationVector)) {
54674a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            if ((mBatchEnabled & hardwareSensorMask)) {
54684a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                featureMask |= INV_DMP_6AXIS_QUATERNION;//a
54694a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                featureMask |= INV_DMP_PED_INDICATOR;
54704a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            } else {
54714a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                featureMask |= INV_DMP_PED_QUATERNION; //b
54724a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                featureMask |= INV_DMP_PED_INDICATOR;  //always piggy back a bit
54734a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            }
54744a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        } else {
54754a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            if (mBatchEnabled & hardwareSensorMask) {
54764a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                featureMask |= INV_DMP_PED_INDICATOR; //c
54774a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            } else {
54784a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                featureMask |= INV_DMP_PED_STANDALONE; //d
54794a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                featureMask |= INV_DMP_PED_INDICATOR; //required for standalone
54804a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            }
548149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        }
54824a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    } else if (mBatchEnabled & (1 << GameRotationVector)) {
54834a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        featureMask |= INV_DMP_6AXIS_QUATERNION; //e,f
54844a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    } else {
54854a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        LOGV_IF(ENG_VERBOSE, "HAL:computeBatchDataOutput: featuerMask=0x%x", featureMask);
54864a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        return 0; //g
548749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    }
54884a28f9c897c46c42a255823f7e307169a828a025Rosa Chow
54894a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    LOGV_IF(ENG_VERBOSE, "HAL:computeBatchDataOutput: featuerMask=0x%x", featureMask);
549049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    return featureMask;
549149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow}
549249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
549349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chowint MPLSensor::getDmpPedometerFd()
549449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow{
549549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    LOGV_IF(EXTRA_VERBOSE, "MPLSensor::getDmpPedometerFd returning %d",
549649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow             dmp_pedometer_fd);
549749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    return dmp_pedometer_fd;
549849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow}
549949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
55004a28f9c897c46c42a255823f7e307169a828a025Rosa Chow/* @param [in] : outputType = 1 --derive from ped_q */
55014a28f9c897c46c42a255823f7e307169a828a025Rosa Chow/* outputType = 0 --derive from IRQ          */
550249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chowint MPLSensor::readDmpPedometerEvents(sensors_event_t* data, int count,
550349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                                      int32_t id, int32_t type, int outputType)
550449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow{
550549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    VFUNC_LOG;
550649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
550749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    int res = 0;
550849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    char dummy[4];
550949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    FILE *fp;
551049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    uint64_t stepCount = 0;
551149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    int numEventReceived = 0;
551249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    int update = 0;
551349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
551449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    if((mDmpStepCountEnabled || mDmpPedometerEnabled) && count > 0) {
551549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        /* handles return event */
551649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        sensors_event_t temp;
551749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
551849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        LOGI_IF(EXTRA_VERBOSE, "HAL: Read Pedometer Event ID=%d", id);
551949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        temp.version = sizeof(sensors_event_t);
552049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        temp.sensor = id;
552149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        temp.type = type;
552249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        temp.acceleration.status
552349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            = SENSOR_STATUS_UNRELIABLE;
552449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        /* sensors.h specified to return 1.0 */
552549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        if(id == ID_P) {
552649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow             temp.data[0] = 1;
552749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow             temp.data[1] = 0.f;
552849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow             temp.data[2] = 0.f;
552949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        } else {
553049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            fp = fopen(mpu.pedometer_steps, "r");
553149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            if (fp == NULL) {
553249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                LOGE("HAL:cannot open pedometer_steps");
553349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            } else{
55344a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                if (fscanf(fp, "%lld\n", &stepCount) < 0 || fclose(fp) < 0) {
55354a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                    LOGE("HAL:cannot read pedometer_steps");
55364a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                }
553749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            }
553849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            /* return onChange only*/
553949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            if (stepCount == mLastStepCount) {
554049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                return 0;
554149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            }
554249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            temp.data[0] = stepCount;
554349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            temp.data[1] = 0.f;
554449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            temp.data[2] = 0.f;
554549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            mLastStepCount = stepCount;
554649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        }
554749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
554849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        if (!outputType) {
554949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            struct timespec ts;
555049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            clock_gettime(CLOCK_MONOTONIC, &ts) ;
555149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            temp.timestamp = (int64_t)ts.tv_sec * 1000000000 + ts.tv_nsec;
555249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        }
555349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
555449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        *data++ = temp;
555549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        count--;
555649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        numEventReceived++;
555749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    }
555849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
555949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    if (!outputType) {
556049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        // read dummy data per driver's request
556149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        // only required if actual irq is issued
556249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        read(dmp_pedometer_fd, dummy, 4);
556349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    } else {
556449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        return 1;
556549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    }
556649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
556749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    return numEventReceived;
556849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow}
556949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
557049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chowint MPLSensor::getDmpSignificantMotionFd()
557149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow{
557249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    LOGV_IF(EXTRA_VERBOSE,
557349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            "MPLSensor::getDmpSignificantMotionFd returning %d",
557449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            dmp_sign_motion_fd);
557549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    return dmp_sign_motion_fd;
557649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow}
557749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
557849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chowint MPLSensor::readDmpSignificantMotionEvents(sensors_event_t* data, int count) {
557949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    VFUNC_LOG;
558049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
558149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    int res = 0;
558249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    char dummy[4];
558349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    int significantMotion;
558449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    FILE *fp;
558549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    int sensors = mEnabled;
558649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    int numEventReceived = 0;
558749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    int update = 0;
558849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
558949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    /* Technically this step is not necessary for now  */
559049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    /* In the future, we may have meaningful values */
559149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    fp = fopen(mpu.event_smd, "r");
559249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    if (fp == NULL) {
559349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        LOGE("HAL:cannot open event_smd");
559449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        return 0;
559549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    }
559649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    fscanf(fp, "%d\n", &significantMotion);
559749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    fclose(fp);
559849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
559949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    if(mDmpSignificantMotionEnabled && count > 0) {
560049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow       /* By implementation, smd is disabled once an event is triggered */
560149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        sensors_event_t temp;
560249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
560349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        /* Handles return event */
560449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        LOGI("HAL: SMD detected");
560549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        int update = smHandler(&temp);
560649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        if (update && count > 0) {
560749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            *data++ = temp;
560849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            count--;
560949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            numEventReceived++;
561049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            mDmpSignificantMotionEnabled = 0;
561149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            mFeatureActiveMask &= ~INV_DMP_SIGNIFICANT_MOTION;
561249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            if(mFeatureActiveMask == 0) {
561349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                LOGI("dmp off");
561449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                // disable DMP
561549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                masterEnable(0);
561649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                res = onDmp(0);
561749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                if (res < 0)
561849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                    return res;
561949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
562049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                // disable accel engine
562149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                if (!(mLocalSensorMask & mMasterSensorMask
562249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                        & INV_THREE_AXIS_ACCEL)) {
562349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                    res = enableAccel(0);
562449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                    if (res < 0)
562549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                        return res;
562649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                }
562749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            }
562849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            if(sensors != 0) {
562949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                 update_delay();
563049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                 masterEnable(1);
563149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            }
563249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        }
563349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    }
563449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
563549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    // read dummy data per driver's request
563649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    read(dmp_sign_motion_fd, dummy, 4);
563749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
563849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    return numEventReceived;
563949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow}
564049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
564149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chowint MPLSensor::enableDmpSignificantMotion(int en)
564249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow{
564349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    int res = 0;
564449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    VFUNC_LOG;
564549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
564649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    int enabled_sensors = mEnabled;
564749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
564849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    if (isMpuNonDmp())
564949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        return res;
565049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
565149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    // reset master enable
565249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    res = masterEnable(0);
565349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    if (res < 0)
565449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        return res;
565549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
565649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    //Toggle significant montion detection
565749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    if(en) {
565849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        LOGV_IF(PROCESS_VERBOSE, "HAL:Enabling Significant Motion");
565949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)",
566049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                1, mpu.smd_enable, getTimestamp());
566149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        if (write_sysfs_int(mpu.smd_enable, 1) < 0) {
566249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            LOGE("HAL:ERR can't write DMP smd_enable");
566349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            res = -1;   //Indicate an err
566449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        }
566549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
566649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        // enable DMP
566749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        res = onDmp(1);
566849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        if (res < 0)
566949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            return res;
567049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
567149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        // set DMP rate to 200Hz
567249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)",
567349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                200, mpu.accel_fifo_rate, getTimestamp());
567449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        if (write_sysfs_int(mpu.accel_fifo_rate, 200) < 0) {
567549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            res = -1;
56764a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            LOGE("HAL:ERR can't set rate to 200Hz");
567749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            return res;
567849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        }
567949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
568049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        // enable accel engine
568149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        res = enableAccel(1);
568249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        if (res < 0)
568349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            return res;
568449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
568549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        // disable accel FIFO
568649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        if (!(mLocalSensorMask & mMasterSensorMask & INV_THREE_AXIS_ACCEL)) {
568749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            res = turnOffAccelFifo();
568849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            if (res < 0)
568949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                return res;
569049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        }
569149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        mFeatureActiveMask |= INV_DMP_SIGNIFICANT_MOTION;
569249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    }
569349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    else {
569449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        LOGV_IF(PROCESS_VERBOSE, "HAL:Disabling Significant Motion");
569549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)",
569649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                0, mpu.smd_enable, getTimestamp());
569749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        if (write_sysfs_int(mpu.smd_enable, 0) < 0) {
569849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            LOGE("HAL:ERR write DMP smd_enable");
569949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        }
570049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        mFeatureActiveMask &= ~INV_DMP_SIGNIFICANT_MOTION;
570149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        // disable DMP
570249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        if (mFeatureActiveMask == 0) {
570349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            res = onDmp(0);
570449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
570549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            if (res < 0)
570649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                return res;
570749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
570849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            // disable accel engine
570949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            if (!(mLocalSensorMask & mMasterSensorMask
571049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                    & INV_THREE_AXIS_ACCEL)) {
571149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                res = enableAccel(0);
571249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                if (res < 0)
571349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                    return res;
571449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            }
571549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        }
571649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        if(enabled_sensors) {
571749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)",
571849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                en, mpu.dmp_event_int_on, getTimestamp());
571949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            if (write_sysfs_int(mpu.dmp_event_int_on, en) < 0) {
572049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                res = -1;
572149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                LOGE("HAL:ERR can't enable DMP event interrupt");
572249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            }
572349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow         }
572449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    }
572549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    if(en || enabled_sensors || mFeatureActiveMask) {
572649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        res = masterEnable(1);
572749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    }
572849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    return res;
572949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow}
573049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
573149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chowint MPLSensor::writeSignificantMotionParams(bool toggleEnable,
573249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                                            uint32_t delayThreshold1,
573349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                                            uint32_t delayThreshold2,
573449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                                            uint32_t motionThreshold)
573549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow{
573649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    int res = 0;
573749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
573849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    // Turn off enable
573949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    if (toggleEnable) {
574049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        masterEnable(0);
574149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    }
574249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
574349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    // Write supplied values
57444a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)",
57454a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            delayThreshold1, mpu.smd_delay_threshold, getTimestamp());
574649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    res = write_sysfs_int(mpu.smd_delay_threshold, delayThreshold1);
574749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    if (res == 0) {
57484a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)",
57494a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                delayThreshold2, mpu.smd_delay_threshold2, getTimestamp());
575049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        res = write_sysfs_int(mpu.smd_delay_threshold2, delayThreshold2);
575149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    }
575249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    if (res == 0) {
57534a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)",
57544a28f9c897c46c42a255823f7e307169a828a025Rosa Chow                motionThreshold, mpu.smd_threshold, getTimestamp());
575549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        res = write_sysfs_int(mpu.smd_threshold, motionThreshold);
575649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    }
575749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
575849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    // Turn on enable
575949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    if (toggleEnable) {
576049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        masterEnable(1);
576149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    }
576249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    return res;
576349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow}
576449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
57654a28f9c897c46c42a255823f7e307169a828a025Rosa Chow/* set batch data rate */
57664a28f9c897c46c42a255823f7e307169a828a025Rosa Chow/* this function should be optimized */
57674a28f9c897c46c42a255823f7e307169a828a025Rosa Chowint MPLSensor::setBatchDataRates()
57684a28f9c897c46c42a255823f7e307169a828a025Rosa Chow{
57694a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    VFUNC_LOG;
57704a28f9c897c46c42a255823f7e307169a828a025Rosa Chow
57714a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    int res = 0;
57724a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    int tempFd = -1;
57734a28f9c897c46c42a255823f7e307169a828a025Rosa Chow
57744a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    int64_t gyroRate;
57754a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    int64_t accelRate;
57764a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    int64_t compassRate;
57774a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    int64_t pressureRate;
57784a28f9c897c46c42a255823f7e307169a828a025Rosa Chow
57794a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    int mplGyroRate;
57804a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    int mplAccelRate;
57814a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    int mplCompassRate;
57824a28f9c897c46c42a255823f7e307169a828a025Rosa Chow
57834a28f9c897c46c42a255823f7e307169a828a025Rosa Chow#ifdef ENABLE_MULTI_RATE
57844a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    /* take care of case where only one type of gyro sensors or compass sensors is turned on */
57854a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    gyroRate = mBatchDelays[Gyro] < mBatchDelays[RawGyro] ? mBatchDelays[Gyro] : mBatchDelays[RawGyro];
57864a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    accelRate = mBatchDelays[Accelerometer];
57874a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    compassRate = mBatchDelays[MagneticField] < mBatchDelays[RawMagneticField] ? mBatchDelays[MagneticField] : mBatchDelays[RawMagneticField];
57884a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    pressureRate = mBatchDelays[Pressure];
57894a28f9c897c46c42a255823f7e307169a828a025Rosa Chow
57904a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    mplGyroRate = (int) gyroRate / 1000LL;
57914a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    mplAccelRate = (int) accelRate / 1000LL;
57924a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    mplCompassRate = (int) compassRate / 1000LL;
57934a28f9c897c46c42a255823f7e307169a828a025Rosa Chow
57944a28f9c897c46c42a255823f7e307169a828a025Rosa Chow     /* set rate in MPL */
57954a28f9c897c46c42a255823f7e307169a828a025Rosa Chow     /* compass can only do 100Hz max */
57964a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    inv_set_gyro_sample_rate(mplGyroRate);
57974a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    inv_set_accel_sample_rate(mplAccelRate);
57984a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    inv_set_compass_sample_rate(mplCompassRate);
57994a28f9c897c46c42a255823f7e307169a828a025Rosa Chow
58004a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    LOGV_IF(PROCESS_VERBOSE,
58014a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            "HAL:MPL gyro sample rate: (mpl)=%d us (mpu)=%.2f Hz", mplGyroRate, 1000000000.f / gyroRate);
58024a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    LOGV_IF(PROCESS_VERBOSE,
58034a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            "HAL:MPL accel sample rate: (mpl)=%d us (mpu)=%.2f Hz", mplAccelRate, 1000000000.f / accelRate);
58044a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    LOGV_IF(PROCESS_VERBOSE,
58054a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            "HAL:MPL compass sample rate: (mpl)=%d us (mpu)=%.2f Hz", mplCompassRate, 1000000000.f / compassRate);
58064a28f9c897c46c42a255823f7e307169a828a025Rosa Chow
58074a28f9c897c46c42a255823f7e307169a828a025Rosa Chow#else
58084a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    /* search the minimum delay requested across all enabled sensors */
58094a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    int64_t wanted = 1000000000LL;
58104a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    for (int i = 1; i < NumSensors; i++) {
58114a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        if (mBatchEnabled & (1 << i)) {
58124a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            int64_t ns = mBatchDelays[i];
58134a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            wanted = wanted < ns ? wanted : ns;
58144a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        }
58154a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    }
58164a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    gyroRate = wanted;
58174a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    accelRate = wanted;
58184a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    compassRate = wanted;
58194a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    pressureRate = wanted;
58204a28f9c897c46c42a255823f7e307169a828a025Rosa Chow#endif
58214a28f9c897c46c42a255823f7e307169a828a025Rosa Chow
58224a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %.0f > %s (%lld)",
58234a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            1000000000.f / gyroRate, mpu.gyro_rate,
58244a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            getTimestamp());
58254a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    tempFd = open(mpu.gyro_rate, O_RDWR);
58264a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    res = write_attribute_sensor(tempFd, 1000000000.f / gyroRate);
58274a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    if(res < 0) {
58284a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        LOGE("HAL:GYRO update delay error");
58294a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    }
58304a28f9c897c46c42a255823f7e307169a828a025Rosa Chow
58314a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %.0f > %s (%lld)",
58324a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            1000000000.f / accelRate, mpu.accel_rate,
58334a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            getTimestamp());
58344a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    tempFd = open(mpu.accel_rate, O_RDWR);
58354a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    res = write_attribute_sensor(tempFd, 1000000000.f / accelRate);
58364a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    LOGE_IF(res < 0, "HAL:ACCEL update delay error");
58374a28f9c897c46c42a255823f7e307169a828a025Rosa Chow
58384a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    if (compassRate < mCompassSensor->getMinDelay() * 1000LL) {
58394a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        compassRate = mCompassSensor->getMinDelay() * 1000LL;
58404a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    }
58414a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    mCompassSensor->setDelay(ID_M, compassRate);
58424a28f9c897c46c42a255823f7e307169a828a025Rosa Chow
58434a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    mPressureSensor->setDelay(ID_PS, pressureRate);
58444a28f9c897c46c42a255823f7e307169a828a025Rosa Chow
58454a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    return res;
58464a28f9c897c46c42a255823f7e307169a828a025Rosa Chow}
58474a28f9c897c46c42a255823f7e307169a828a025Rosa Chow
58484a28f9c897c46c42a255823f7e307169a828a025Rosa Chow/* Set sensor rate */
58494a28f9c897c46c42a255823f7e307169a828a025Rosa Chow/* this function should be optimized */
58504a28f9c897c46c42a255823f7e307169a828a025Rosa Chowint MPLSensor::resetDataRates()
58514a28f9c897c46c42a255823f7e307169a828a025Rosa Chow{
58524a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    VFUNC_LOG;
58534a28f9c897c46c42a255823f7e307169a828a025Rosa Chow
58544a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    int res = 0;
58554a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    int tempFd = -1;
58564a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    int64_t wanted = 1000000000LL;
58574a28f9c897c46c42a255823f7e307169a828a025Rosa Chow
58584a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    int64_t gyroRate;
58594a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    int64_t accelRate;
58604a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    int64_t compassRate;
58614a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    int64_t pressureRate;
58624a28f9c897c46c42a255823f7e307169a828a025Rosa Chow
58634a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    /* enable this once driver supports multi-rate in dmp off mode */
58644a28f9c897c46c42a255823f7e307169a828a025Rosa Chow
58654a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    /* search the minimum delay requested across all enabled sensors */
58664a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    for (int i = 1; i < NumSensors; i++) {
58674a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        if (mEnabled & (1 << i)) {
58684a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            int64_t ns = mDelays[i];
58694a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            wanted = wanted < ns ? wanted : ns;
58704a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        }
58714a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    }
58724a28f9c897c46c42a255823f7e307169a828a025Rosa Chow
58734a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    if (mDmpOn == 1) {
58744a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        gyroRate = mDelays[Gyro] < mDelays[RawGyro] ? mDelays[Gyro] : mDelays[RawGyro];
58754a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        accelRate = mDelays[Accelerometer];
58764a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        compassRate = mDelays[MagneticField] < mDelays[RawMagneticField] ? mDelays[MagneticField] : mDelays[RawMagneticField];
58774a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        pressureRate = mDelays[Pressure];
58784a28f9c897c46c42a255823f7e307169a828a025Rosa Chow
58794a28f9c897c46c42a255823f7e307169a828a025Rosa Chow#ifndef ENABLE_MULTI_RATE
58804a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        gyroRate = wanted;
58814a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        accelRate = wanted;
58824a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        compassRate = wanted;
58834a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        pressureRate = wanted;
58844a28f9c897c46c42a255823f7e307169a828a025Rosa Chow#endif
58854a28f9c897c46c42a255823f7e307169a828a025Rosa Chow
58864a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    } else {
58874a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        gyroRate = wanted;
58884a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        accelRate = wanted;
58894a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        compassRate = wanted;
58904a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        pressureRate = wanted;
58914a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    }
58924a28f9c897c46c42a255823f7e307169a828a025Rosa Chow
58934a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    /* set mpl data rate */
58944a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    inv_set_gyro_sample_rate((int)gyroRate/1000LL);
58954a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    inv_set_accel_sample_rate((int)accelRate/1000LL);
58964a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    inv_set_compass_sample_rate((int)compassRate/1000LL);
58974a28f9c897c46c42a255823f7e307169a828a025Rosa Chow
58984a28f9c897c46c42a255823f7e307169a828a025Rosa Chow   LOGV_IF(PROCESS_VERBOSE,
58994a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            "HAL:MPL gyro sample rate: (mpl)=%lld us (mpu)=%.2f Hz", gyroRate/1000LL, 1000000000.f / gyroRate);
59004a28f9c897c46c42a255823f7e307169a828a025Rosa Chow   LOGV_IF(PROCESS_VERBOSE,
59014a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            "HAL:MPL accel sample rate: (mpl)=%lld us (mpu)=%.2f Hz", accelRate/1000LL, 1000000000.f / accelRate);
59024a28f9c897c46c42a255823f7e307169a828a025Rosa Chow   LOGV_IF(PROCESS_VERBOSE,
59034a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            "HAL:MPL compass sample rate: (mpl)=%lld us (mpu)=%.2f Hz", compassRate/1000LL, 1000000000.f / compassRate);
59044a28f9c897c46c42a255823f7e307169a828a025Rosa Chow
59054a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    /* reset dmp rate */
59064a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    getDmpRate (&wanted);
59074a28f9c897c46c42a255823f7e307169a828a025Rosa Chow
59084a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %.0f > %s (%lld)",
59094a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            1000000000.f / wanted, mpu.gyro_fifo_rate,
59104a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            getTimestamp());
59114a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    tempFd = open(mpu.gyro_fifo_rate, O_RDWR);
59124a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    res = write_attribute_sensor(tempFd, 1000000000.f / wanted);
59134a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    LOGE_IF(res < 0, "HAL:sampling frequency update delay error");
59144a28f9c897c46c42a255823f7e307169a828a025Rosa Chow
59154a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %.0f > %s (%lld)",
59164a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            1000000000.f / gyroRate, mpu.gyro_rate,
59174a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            getTimestamp());
59184a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    tempFd = open(mpu.gyro_rate, O_RDWR);
59194a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    res = write_attribute_sensor(tempFd, 1000000000.f / gyroRate);
59204a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    if(res < 0) {
59214a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        LOGE("HAL:GYRO update delay error");
59224a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    }
59234a28f9c897c46c42a255823f7e307169a828a025Rosa Chow
59244a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %.0f > %s (%lld)",
59254a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            1000000000.f / accelRate, mpu.accel_rate,
59264a28f9c897c46c42a255823f7e307169a828a025Rosa Chow            getTimestamp());
59274a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    tempFd = open(mpu.accel_rate, O_RDWR);
59284a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    res = write_attribute_sensor(tempFd, 1000000000.f / accelRate);
59294a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    LOGE_IF(res < 0, "HAL:ACCEL update delay error");
59304a28f9c897c46c42a255823f7e307169a828a025Rosa Chow
59314a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    if (compassRate < mCompassSensor->getMinDelay() * 1000LL) {
59324a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        compassRate = mCompassSensor->getMinDelay() * 1000LL;
59334a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    }
59344a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    mCompassSensor->setDelay(ID_M, compassRate);
59354a28f9c897c46c42a255823f7e307169a828a025Rosa Chow
59364a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    mPressureSensor->setDelay(ID_PS, pressureRate);
59374a28f9c897c46c42a255823f7e307169a828a025Rosa Chow
59384a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    return res;
59394a28f9c897c46c42a255823f7e307169a828a025Rosa Chow}
59404a28f9c897c46c42a255823f7e307169a828a025Rosa Chow
59414a28f9c897c46c42a255823f7e307169a828a025Rosa Chowvoid MPLSensor::initBias()
59424a28f9c897c46c42a255823f7e307169a828a025Rosa Chow{
59434a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    LOGV_IF(ENG_VERBOSE, "HAL:inititalize dmp and device offsets to 0");
59444a28f9c897c46c42a255823f7e307169a828a025Rosa Chow
59454a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    if(write_attribute_sensor_continuous(accel_x_dmp_bias_fd, 0) < 0)
59464a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    {
59474a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        LOGE("HAL:Error writing to accel_x_dmp_bias");
59484a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    }
59494a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    if(write_attribute_sensor_continuous(accel_y_dmp_bias_fd, 0) < 0)
59504a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    {
59514a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        LOGE("HAL:Error writing to accel_y_dmp_bias");
59524a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    }
59534a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    if(write_attribute_sensor_continuous(accel_z_dmp_bias_fd, 0) < 0)
59544a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    {
59554a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        LOGE("HAL:Error writing to accel_z_dmp_bias");
59564a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    }
59574a28f9c897c46c42a255823f7e307169a828a025Rosa Chow
59584a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    if(write_attribute_sensor_continuous(gyro_x_dmp_bias_fd, 0) < 0)
59594a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    {
59604a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        LOGE("HAL:Error writing to gyro_x_dmp_bias");
59614a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    }
59624a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    if(write_attribute_sensor_continuous(gyro_y_dmp_bias_fd, 0) < 0)
59634a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    {
59644a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        LOGE("HAL:Error writing to gyro_y_dmp_bias");
59654a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    }
59664a28f9c897c46c42a255823f7e307169a828a025Rosa Chow     if(write_attribute_sensor_continuous(gyro_z_dmp_bias_fd, 0) < 0)
59674a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    {
59684a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        LOGE("HAL:Error writing to gyro_z_dmp_bias");
59694a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    }
59704a28f9c897c46c42a255823f7e307169a828a025Rosa Chow
59714a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    if(write_attribute_sensor_continuous(gyro_x_offset_fd, 0) < 0)
59724a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    {
59734a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        LOGE("HAL:Error writing to gyro_x_offset");
59744a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    }
59754a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    if(write_attribute_sensor_continuous(gyro_y_offset_fd, 0) < 0)
59764a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    {
59774a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        LOGE("HAL:Error writing to gyro_y_offset");
59784a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    }
59794a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    if(write_attribute_sensor_continuous(gyro_z_offset_fd, 0) < 0)
59804a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    {
59814a28f9c897c46c42a255823f7e307169a828a025Rosa Chow        LOGE("HAL:Error writing to gyro_z_offset");
59824a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    }
59834a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    return;
59844a28f9c897c46c42a255823f7e307169a828a025Rosa Chow}
59854a28f9c897c46c42a255823f7e307169a828a025Rosa Chow
598649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow/*TODO: reg_dump in a separate file*/
598749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chowvoid MPLSensor::sys_dump(bool fileMode)
598849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow{
598949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    VFUNC_LOG;
599049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
599149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    char sysfs_path[MAX_SYSFS_NAME_LEN];
599249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    char scan_element_path[MAX_SYSFS_NAME_LEN];
599349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
599449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    memset(sysfs_path, 0, sizeof(sysfs_path));
599549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    memset(scan_element_path, 0, sizeof(scan_element_path));
599649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    inv_get_sysfs_path(sysfs_path);
599749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    sprintf(scan_element_path, "%s%s", sysfs_path, "/scan_elements");
599849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
599949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    read_sysfs_dir(fileMode, sysfs_path);
600049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    read_sysfs_dir(fileMode, scan_element_path);
600149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
600249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    dump_dmp_img("/data/local/read_img.h");
600349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    return;
600449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow}
6005