Home | History | Annotate | Download | only in libsensors
      1 /*
      2  * Copyright (C) 2008-2014 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #include <ctype.h>
     18 #include <dirent.h>
     19 #include <errno.h>
     20 #include <fcntl.h>
     21 #include <inttypes.h>
     22 #include <math.h>
     23 #include <poll.h>
     24 #include <pthread.h>
     25 #include <stdlib.h>
     26 #include <sys/select.h>
     27 #include <unistd.h>
     28 
     29 #define LOG_TAG "CwMcuSensor"
     30 #include <cutils/log.h>
     31 #include <cutils/properties.h>
     32 
     33 #include "CwMcuSensor.h"
     34 
     35 
     36 #define REL_Significant_Motion REL_WHEEL
     37 #define LIGHTSENSOR_LEVEL 10
     38 #define DEBUG_DATA 0
     39 #define COMPASS_CALIBRATION_DATA_SIZE 26
     40 #define G_SENSOR_CALIBRATION_DATA_SIZE 3
     41 #define NS_PER_MS 1000000LL
     42 #define EXHAUSTED_MAGIC 0x77
     43 
     44 /*****************************************************************************/
     45 #define IIO_MAX_BUFF_SIZE 4096
     46 #define IIO_MAX_DATA_SIZE 24
     47 #define IIO_MAX_NAME_LENGTH 30
     48 #define IIO_BUF_SIZE_RETRY 8
     49 #define INT32_CHAR_LEN 12
     50 
     51 #define INIT_TRIGGER_RETRY 5
     52 
     53 static const char iio_dir[] = "/sys/bus/iio/devices/";
     54 
     55 static int min(int a, int b) {
     56     return (a < b) ? a : b;
     57 }
     58 
     59 static int chomp(char *buf, size_t len) {
     60     if (buf == NULL)
     61         return -1;
     62 
     63     while (len > 0 && isspace(buf[len-1])) {
     64         buf[len - 1] = '\0';
     65         len--;
     66     }
     67 
     68     return 0;
     69 }
     70 
     71 int CwMcuSensor::sysfs_set_input_attr(const char *attr, char *value, size_t len) {
     72     char fname[PATH_MAX];
     73     int fd;
     74     int rc;
     75 
     76     snprintf(fname, sizeof(fname), "%s/%s", mDevPath, attr);
     77     fname[sizeof(fname) - 1] = '\0';
     78 
     79     fd = open(fname, O_WRONLY);
     80     if (fd < 0) {
     81         ALOGE("%s: fname = %s, fd = %d, failed: %s\n", __func__, fname, fd, strerror(errno));
     82         return -EACCES;
     83     }
     84 
     85     rc = write(fd, value, (size_t)len);
     86     if (rc < 0) {
     87         ALOGE("%s: write failed: fd = %d, rc = %d, strerr = %s\n", __func__, fd, rc, strerror(errno));
     88         close(fd);
     89         return -EIO;
     90     }
     91 
     92     close(fd);
     93 
     94     return 0;
     95 }
     96 
     97 int CwMcuSensor::sysfs_set_input_attr_by_int(const char *attr, int value) {
     98     char buf[INT32_CHAR_LEN];
     99 
    100     size_t n = snprintf(buf, sizeof(buf), "%d", value);
    101     if (n > sizeof(buf)) {
    102         return -1;
    103     }
    104 
    105     return sysfs_set_input_attr(attr, buf, n);
    106 }
    107 
    108 static inline int find_type_by_name(const char *name, const char *type) {
    109     const struct dirent *ent;
    110     int number, numstrlen;
    111 
    112     DIR *dp;
    113     char thisname[IIO_MAX_NAME_LENGTH];
    114     char *filename;
    115     size_t size;
    116     size_t typeLen = strlen(type);
    117     size_t nameLen = strlen(name);
    118 
    119     if (nameLen >= sizeof(thisname) - 1) {
    120         return -ERANGE;
    121     }
    122 
    123     dp = opendir(iio_dir);
    124     if (dp == NULL) {
    125         return -ENODEV;
    126     }
    127 
    128     while (ent = readdir(dp), ent != NULL) {
    129         if (strcmp(ent->d_name, ".") != 0 &&
    130                 strcmp(ent->d_name, "..") != 0 &&
    131                 strlen(ent->d_name) > typeLen &&
    132                 strncmp(ent->d_name, type, typeLen) == 0) {
    133             numstrlen = sscanf(ent->d_name + typeLen,
    134                                "%d", &number);
    135 
    136             /* verify the next character is not a colon */
    137             if (ent->d_name[strlen(type) + numstrlen] != ':') {
    138                 size = sizeof(iio_dir) - 1 + typeLen + numstrlen + 6;
    139                 filename = (char *)malloc(size);
    140 
    141                 if (filename == NULL)
    142                     return -ENOMEM;
    143 
    144                 snprintf(filename, size,
    145                          "%s%s%d/name",
    146                          iio_dir, type, number);
    147 
    148                 int fd = open(filename, O_RDONLY);
    149                 free(filename);
    150                 if (fd < 0) {
    151                     continue;
    152                 }
    153                 size = read(fd, thisname, sizeof(thisname) - 1);
    154                 close(fd);
    155                 if (size < nameLen) {
    156                     continue;
    157                 }
    158                 thisname[size] = '\0';
    159                 if (strncmp(name, thisname, nameLen)) {
    160                     continue;
    161                 }
    162                 // check for termination or whitespace
    163                 if (!thisname[nameLen] || isspace(thisname[nameLen])) {
    164                     return number;
    165                 }
    166             }
    167         }
    168     }
    169     return -ENODEV;
    170 }
    171 
    172 int fill_block_debug = 0;
    173 
    174 pthread_mutex_t sys_fs_mutex = PTHREAD_MUTEX_INITIALIZER;
    175 pthread_mutex_t sync_timestamp_algo_mutex = PTHREAD_MUTEX_INITIALIZER;
    176 pthread_mutex_t last_timestamp_mutex = PTHREAD_MUTEX_INITIALIZER;
    177 
    178 void CwMcuSensor::sync_time_thread_in_class(void) {
    179     int fd;
    180     char buf[24];
    181     int err;
    182     uint64_t mcu_current_time;
    183     uint64_t cpu_current_time;
    184     int open_errno;
    185 
    186     ALOGV("sync_time_thread_in_class++:\n");
    187 
    188     pthread_mutex_lock(&sys_fs_mutex);
    189 
    190     strcpy(&fixed_sysfs_path[fixed_sysfs_path_len], "batch_enable");
    191 
    192     fd = open(fixed_sysfs_path, O_RDWR);
    193     open_errno = errno;
    194     pthread_mutex_unlock(&sys_fs_mutex);
    195     if (fd >= 0) {
    196         err = read(fd, buf, sizeof(buf) - 1);
    197         cpu_current_time = getTimestamp();
    198         if (err < 0) {
    199             ALOGE("sync_time_thread_in_class: read fail, err = %d\n", err);
    200         } else {
    201             buf[err] = '\0';
    202             mcu_current_time = strtoull(buf, NULL, 10) * NS_PER_US;
    203             if (errno == ERANGE) {
    204                 ALOGE("sync_time_thread_in_class: strtoll fails, strerr = %s, buf = %s\n",
    205                       strerror(errno), buf);
    206             } else {
    207                 pthread_mutex_lock(&sync_timestamp_algo_mutex);
    208 
    209                 if (mcu_current_time == 0) {
    210                     // Do a recovery mechanism of timestamp estimation when the sensor_hub reset happened
    211                     ALOGE("Sync: sensor hub is on reset\n");
    212                     time_slope = 1;
    213                     memset(last_mcu_timestamp, 0, sizeof(last_mcu_timestamp));
    214                     memset(last_cpu_timestamp, 0, sizeof(last_cpu_timestamp));
    215                 } else if ((mcu_current_time <= last_mcu_sync_time) || (last_mcu_sync_time == 0)) {
    216                     ALOGV("Sync: time_slope was not estimated yet\n");
    217                     time_slope = 1;
    218                     time_offset = cpu_current_time - mcu_current_time;
    219                 } else {
    220                     time_slope = (float)(cpu_current_time - last_cpu_sync_time) /
    221                                  (float)(mcu_current_time - last_mcu_sync_time);
    222                     time_offset = cpu_current_time - mcu_current_time;
    223                 }
    224 
    225                 for (int i=0; i<numSensors; i++) {
    226                     offset_reset[i] = true;
    227                 }
    228 
    229                 ALOGV("Sync: time_offset = %" PRId64 ", time_slope = %f\n", time_offset, time_slope);
    230                 ALOGV("Sync: mcu_current_time = %" PRId64 ", last_mcu_sync_time = %" PRId64 "\n", mcu_current_time, last_mcu_sync_time);
    231                 ALOGV("Sync: cpu_current_time = %" PRId64 ", last_cpu_sync_time = %" PRId64 "\n", cpu_current_time, last_cpu_sync_time);
    232 
    233                 last_mcu_sync_time = mcu_current_time;
    234                 last_cpu_sync_time = cpu_current_time;
    235 
    236                 pthread_mutex_unlock(&sync_timestamp_algo_mutex);
    237             }
    238         }
    239         close(fd);
    240     } else {
    241         ALOGE("sync_time_thread_in_class: open failed, path = .../batch_enable, fd = %d,"
    242               " strerr = %s\n", fd, strerror(open_errno));
    243     }
    244 
    245     ALOGV("sync_time_thread_in_class--:\n");
    246 }
    247 
    248 void *sync_time_thread_run(void *context) {
    249     CwMcuSensor *myClass = (CwMcuSensor *)context;
    250 
    251     while (1) {
    252         ALOGV("sync_time_thread_run++:\n");
    253         myClass->sync_time_thread_in_class();
    254         sleep(PERIODIC_SYNC_TIME_SEC);
    255         ALOGV("sync_time_thread_run--:\n");
    256     }
    257     return NULL;
    258 }
    259 
    260 CwMcuSensor::CwMcuSensor()
    261     : SensorBase(NULL, "CwMcuSensor")
    262     , mEnabled(0)
    263     , mInputReader(IIO_MAX_BUFF_SIZE)
    264     , time_slope(1)
    265     , time_offset(0)
    266     , init_trigger_done(false) {
    267 
    268     int rc;
    269 
    270     memset(last_mcu_timestamp, 0, sizeof(last_mcu_timestamp));
    271     memset(last_cpu_timestamp, 0, sizeof(last_cpu_timestamp));
    272     for (int i=0; i<numSensors; i++) {
    273         offset_reset[i] = true;
    274     }
    275 
    276     mPendingEvents[CW_ACCELERATION].version = sizeof(sensors_event_t);
    277     mPendingEvents[CW_ACCELERATION].sensor = ID_A;
    278     mPendingEvents[CW_ACCELERATION].type = SENSOR_TYPE_ACCELEROMETER;
    279     mPendingEvents[CW_ACCELERATION].acceleration.status = SENSOR_STATUS_ACCURACY_HIGH;
    280 
    281     mPendingEvents[CW_MAGNETIC].version = sizeof(sensors_event_t);
    282     mPendingEvents[CW_MAGNETIC].sensor = ID_M;
    283     mPendingEvents[CW_MAGNETIC].type = SENSOR_TYPE_MAGNETIC_FIELD;
    284 
    285     mPendingEvents[CW_GYRO].version = sizeof(sensors_event_t);
    286     mPendingEvents[CW_GYRO].sensor = ID_GY;
    287     mPendingEvents[CW_GYRO].type = SENSOR_TYPE_GYROSCOPE;
    288     mPendingEvents[CW_GYRO].gyro.status = SENSOR_STATUS_ACCURACY_HIGH;
    289 
    290     mPendingEvents[CW_LIGHT].version = sizeof(sensors_event_t);
    291     mPendingEvents[CW_LIGHT].sensor = ID_L;
    292     mPendingEvents[CW_LIGHT].type = SENSOR_TYPE_LIGHT;
    293     memset(mPendingEvents[CW_LIGHT].data, 0, sizeof(mPendingEvents[CW_LIGHT].data));
    294 
    295     mPendingEvents[CW_PRESSURE].version = sizeof(sensors_event_t);
    296     mPendingEvents[CW_PRESSURE].sensor = ID_PS;
    297     mPendingEvents[CW_PRESSURE].type = SENSOR_TYPE_PRESSURE;
    298     memset(mPendingEvents[CW_PRESSURE].data, 0, sizeof(mPendingEvents[CW_PRESSURE].data));
    299 
    300     mPendingEvents[CW_ORIENTATION].version = sizeof(sensors_event_t);
    301     mPendingEvents[CW_ORIENTATION].sensor = ID_O;
    302     mPendingEvents[CW_ORIENTATION].type = SENSOR_TYPE_ORIENTATION;
    303     mPendingEvents[CW_ORIENTATION].orientation.status = SENSOR_STATUS_ACCURACY_HIGH;
    304 
    305     mPendingEvents[CW_ROTATIONVECTOR].version = sizeof(sensors_event_t);
    306     mPendingEvents[CW_ROTATIONVECTOR].sensor = ID_RV;
    307     mPendingEvents[CW_ROTATIONVECTOR].type = SENSOR_TYPE_ROTATION_VECTOR;
    308 
    309     mPendingEvents[CW_LINEARACCELERATION].version = sizeof(sensors_event_t);
    310     mPendingEvents[CW_LINEARACCELERATION].sensor = ID_LA;
    311     mPendingEvents[CW_LINEARACCELERATION].type = SENSOR_TYPE_LINEAR_ACCELERATION;
    312 
    313     mPendingEvents[CW_GRAVITY].version = sizeof(sensors_event_t);
    314     mPendingEvents[CW_GRAVITY].sensor = ID_G;
    315     mPendingEvents[CW_GRAVITY].type = SENSOR_TYPE_GRAVITY;
    316 
    317     mPendingEvents[CW_MAGNETIC_UNCALIBRATED].version = sizeof(sensors_event_t);
    318     mPendingEvents[CW_MAGNETIC_UNCALIBRATED].sensor = ID_CW_MAGNETIC_UNCALIBRATED;
    319     mPendingEvents[CW_MAGNETIC_UNCALIBRATED].type = SENSOR_TYPE_MAGNETIC_FIELD_UNCALIBRATED;
    320 
    321     mPendingEvents[CW_GYROSCOPE_UNCALIBRATED].version = sizeof(sensors_event_t);
    322     mPendingEvents[CW_GYROSCOPE_UNCALIBRATED].sensor = ID_CW_GYROSCOPE_UNCALIBRATED;
    323     mPendingEvents[CW_GYROSCOPE_UNCALIBRATED].type = SENSOR_TYPE_GYROSCOPE_UNCALIBRATED;
    324 
    325     mPendingEvents[CW_GAME_ROTATION_VECTOR].version = sizeof(sensors_event_t);
    326     mPendingEvents[CW_GAME_ROTATION_VECTOR].sensor = ID_CW_GAME_ROTATION_VECTOR;
    327     mPendingEvents[CW_GAME_ROTATION_VECTOR].type = SENSOR_TYPE_GAME_ROTATION_VECTOR;
    328 
    329     mPendingEvents[CW_GEOMAGNETIC_ROTATION_VECTOR].version = sizeof(sensors_event_t);
    330     mPendingEvents[CW_GEOMAGNETIC_ROTATION_VECTOR].sensor = ID_CW_GEOMAGNETIC_ROTATION_VECTOR;
    331     mPendingEvents[CW_GEOMAGNETIC_ROTATION_VECTOR].type = SENSOR_TYPE_GEOMAGNETIC_ROTATION_VECTOR;
    332 
    333     mPendingEvents[CW_SIGNIFICANT_MOTION].version = sizeof(sensors_event_t);
    334     mPendingEvents[CW_SIGNIFICANT_MOTION].sensor = ID_CW_SIGNIFICANT_MOTION;
    335     mPendingEvents[CW_SIGNIFICANT_MOTION].type = SENSOR_TYPE_SIGNIFICANT_MOTION;
    336 
    337     mPendingEvents[CW_STEP_DETECTOR].version = sizeof(sensors_event_t);
    338     mPendingEvents[CW_STEP_DETECTOR].sensor = ID_CW_STEP_DETECTOR;
    339     mPendingEvents[CW_STEP_DETECTOR].type = SENSOR_TYPE_STEP_DETECTOR;
    340 
    341     mPendingEvents[CW_STEP_COUNTER].version = sizeof(sensors_event_t);
    342     mPendingEvents[CW_STEP_COUNTER].sensor = ID_CW_STEP_COUNTER;
    343     mPendingEvents[CW_STEP_COUNTER].type = SENSOR_TYPE_STEP_COUNTER;
    344 
    345 
    346     mPendingEvents[CW_ACCELERATION_W].version = sizeof(sensors_event_t);
    347     mPendingEvents[CW_ACCELERATION_W].sensor = ID_A_W;
    348     mPendingEvents[CW_ACCELERATION_W].type = SENSOR_TYPE_ACCELEROMETER;
    349     mPendingEvents[CW_ACCELERATION_W].acceleration.status = SENSOR_STATUS_ACCURACY_HIGH;
    350 
    351     mPendingEvents[CW_MAGNETIC_W].version = sizeof(sensors_event_t);
    352     mPendingEvents[CW_MAGNETIC_W].sensor = ID_M_W;
    353     mPendingEvents[CW_MAGNETIC_W].type = SENSOR_TYPE_MAGNETIC_FIELD;
    354 
    355     mPendingEvents[CW_GYRO_W].version = sizeof(sensors_event_t);
    356     mPendingEvents[CW_GYRO_W].sensor = ID_GY_W;
    357     mPendingEvents[CW_GYRO_W].type = SENSOR_TYPE_GYROSCOPE;
    358     mPendingEvents[CW_GYRO_W].gyro.status = SENSOR_STATUS_ACCURACY_HIGH;
    359 
    360     mPendingEvents[CW_PRESSURE_W].version = sizeof(sensors_event_t);
    361     mPendingEvents[CW_PRESSURE_W].sensor = ID_PS_W;
    362     mPendingEvents[CW_PRESSURE_W].type = SENSOR_TYPE_PRESSURE;
    363     memset(mPendingEvents[CW_PRESSURE_W].data, 0, sizeof(mPendingEvents[CW_PRESSURE_W].data));
    364 
    365     mPendingEvents[CW_ORIENTATION_W].version = sizeof(sensors_event_t);
    366     mPendingEvents[CW_ORIENTATION_W].sensor = ID_O_W;
    367     mPendingEvents[CW_ORIENTATION_W].type = SENSOR_TYPE_ORIENTATION;
    368     mPendingEvents[CW_ORIENTATION_W].orientation.status = SENSOR_STATUS_ACCURACY_HIGH;
    369 
    370     mPendingEvents[CW_ROTATIONVECTOR_W].version = sizeof(sensors_event_t);
    371     mPendingEvents[CW_ROTATIONVECTOR_W].sensor = ID_RV_W;
    372     mPendingEvents[CW_ROTATIONVECTOR_W].type = SENSOR_TYPE_ROTATION_VECTOR;
    373 
    374     mPendingEvents[CW_LINEARACCELERATION_W].version = sizeof(sensors_event_t);
    375     mPendingEvents[CW_LINEARACCELERATION_W].sensor = ID_LA_W;
    376     mPendingEvents[CW_LINEARACCELERATION_W].type = SENSOR_TYPE_LINEAR_ACCELERATION;
    377 
    378     mPendingEvents[CW_GRAVITY_W].version = sizeof(sensors_event_t);
    379     mPendingEvents[CW_GRAVITY_W].sensor = ID_G_W;
    380     mPendingEvents[CW_GRAVITY_W].type = SENSOR_TYPE_GRAVITY;
    381 
    382     mPendingEvents[CW_MAGNETIC_UNCALIBRATED_W].version = sizeof(sensors_event_t);
    383     mPendingEvents[CW_MAGNETIC_UNCALIBRATED_W].sensor = ID_CW_MAGNETIC_UNCALIBRATED_W;
    384     mPendingEvents[CW_MAGNETIC_UNCALIBRATED_W].type = SENSOR_TYPE_MAGNETIC_FIELD_UNCALIBRATED;
    385 
    386     mPendingEvents[CW_GYROSCOPE_UNCALIBRATED_W].version = sizeof(sensors_event_t);
    387     mPendingEvents[CW_GYROSCOPE_UNCALIBRATED_W].sensor = ID_CW_GYROSCOPE_UNCALIBRATED_W;
    388     mPendingEvents[CW_GYROSCOPE_UNCALIBRATED_W].type = SENSOR_TYPE_GYROSCOPE_UNCALIBRATED;
    389 
    390     mPendingEvents[CW_GAME_ROTATION_VECTOR_W].version = sizeof(sensors_event_t);
    391     mPendingEvents[CW_GAME_ROTATION_VECTOR_W].sensor = ID_CW_GAME_ROTATION_VECTOR_W;
    392     mPendingEvents[CW_GAME_ROTATION_VECTOR_W].type = SENSOR_TYPE_GAME_ROTATION_VECTOR;
    393 
    394     mPendingEvents[CW_GEOMAGNETIC_ROTATION_VECTOR_W].version = sizeof(sensors_event_t);
    395     mPendingEvents[CW_GEOMAGNETIC_ROTATION_VECTOR_W].sensor = ID_CW_GEOMAGNETIC_ROTATION_VECTOR_W;
    396     mPendingEvents[CW_GEOMAGNETIC_ROTATION_VECTOR_W].type = SENSOR_TYPE_GEOMAGNETIC_ROTATION_VECTOR;
    397 
    398     mPendingEvents[CW_STEP_DETECTOR_W].version = sizeof(sensors_event_t);
    399     mPendingEvents[CW_STEP_DETECTOR_W].sensor = ID_CW_STEP_DETECTOR_W;
    400     mPendingEvents[CW_STEP_DETECTOR_W].type = SENSOR_TYPE_STEP_DETECTOR;
    401 
    402     mPendingEvents[CW_STEP_COUNTER_W].version = sizeof(sensors_event_t);
    403     mPendingEvents[CW_STEP_COUNTER_W].sensor = ID_CW_STEP_COUNTER_W;
    404     mPendingEvents[CW_STEP_COUNTER_W].type = SENSOR_TYPE_STEP_COUNTER;
    405 
    406 
    407     mPendingEventsFlush.version = META_DATA_VERSION;
    408     mPendingEventsFlush.sensor = 0;
    409     mPendingEventsFlush.type = SENSOR_TYPE_META_DATA;
    410 
    411     char buffer_access[PATH_MAX];
    412     const char *device_name = "CwMcuSensor";
    413     int rate = 20, dev_num, enabled = 0, i;
    414 
    415     dev_num = find_type_by_name(device_name, "iio:device");
    416     if (dev_num < 0)
    417         dev_num = 0;
    418 
    419     snprintf(buffer_access, sizeof(buffer_access),
    420             "/dev/iio:device%d", dev_num);
    421 
    422     data_fd = open(buffer_access, O_RDWR);
    423     if (data_fd < 0) {
    424         ALOGE("CwMcuSensor::CwMcuSensor: open file '%s' failed: %s\n",
    425               buffer_access, strerror(errno));
    426     }
    427 
    428     if (data_fd >= 0) {
    429         int i;
    430         int fd;
    431         int iio_buf_size;
    432 
    433         ALOGV("%s: 11 Before pthread_mutex_lock()\n", __func__);
    434         pthread_mutex_lock(&sys_fs_mutex);
    435         ALOGV("%s: 11 Acquired pthread_mutex_lock()\n", __func__);
    436 
    437         strcpy(fixed_sysfs_path,"/sys/class/htc_sensorhub/sensor_hub/");
    438         fixed_sysfs_path_len = strlen(fixed_sysfs_path);
    439 
    440         snprintf(mDevPath, sizeof(mDevPath), "%s%s", fixed_sysfs_path, "iio");
    441 
    442         snprintf(mTriggerName, sizeof(mTriggerName), "%s-dev%d",
    443                  device_name, dev_num);
    444         ALOGV("CwMcuSensor::CwMcuSensor: mTriggerName = %s\n", mTriggerName);
    445 
    446         if (sysfs_set_input_attr_by_int("buffer/enable", 0) < 0) {
    447             ALOGE("CwMcuSensor::CwMcuSensor: set IIO buffer enable failed00: %s\n",
    448                   strerror(errno));
    449         }
    450 
    451         // This is a piece of paranoia that retry for current_trigger
    452         for (i = 0; i < INIT_TRIGGER_RETRY; i++) {
    453             rc = sysfs_set_input_attr("trigger/current_trigger",
    454                                       mTriggerName, strlen(mTriggerName));
    455             if (rc < 0) {
    456                 if (sysfs_set_input_attr_by_int("buffer/enable", 0) < 0) {
    457                     ALOGE("CwMcuSensor::CwMcuSensor: set IIO buffer enable failed11: %s\n",
    458                           strerror(errno));
    459                 }
    460                 ALOGE("CwMcuSensor::CwMcuSensor: set current trigger failed: rc = %d, strerr() = %s"
    461                       ", i = %d\n",
    462                       rc, strerror(errno), i);
    463             } else {
    464                 init_trigger_done = true;
    465                 break;
    466             }
    467         }
    468 
    469         iio_buf_size = IIO_MAX_BUFF_SIZE;
    470         for (i = 0; i < IIO_BUF_SIZE_RETRY; i++) {
    471             if (sysfs_set_input_attr_by_int("buffer/length", iio_buf_size) < 0) {
    472                 ALOGE("CwMcuSensor::CwMcuSensor: set IIO buffer length (%d) failed: %s\n",
    473                       iio_buf_size, strerror(errno));
    474             } else {
    475                 if (sysfs_set_input_attr_by_int("buffer/enable", 1) < 0) {
    476                     ALOGE("CwMcuSensor::CwMcuSensor: set IIO buffer enable failed22: %s, "
    477                           "i = %d, iio_buf_size = %d\n", strerror(errno), i, iio_buf_size);
    478                 } else {
    479                     ALOGI("CwMcuSensor::CwMcuSensor: set IIO buffer length success: %d\n", iio_buf_size);
    480                     break;
    481                 }
    482             }
    483             iio_buf_size /= 2;
    484         }
    485 
    486         strcpy(&fixed_sysfs_path[fixed_sysfs_path_len], "calibrator_en");
    487         fd = open(fixed_sysfs_path, O_RDWR);
    488         if (fd >= 0) {
    489             static const char buf[] = "12";
    490 
    491             rc = write(fd, buf, sizeof(buf) - 1);
    492             if (rc < 0) {
    493                 ALOGE("%s: write buf = %s, failed: %s", __func__, buf, strerror(errno));
    494             }
    495 
    496             close(fd);
    497         } else {
    498             ALOGE("%s open %s failed: %s", __func__, fixed_sysfs_path, strerror(errno));
    499         }
    500 
    501         pthread_mutex_unlock(&sys_fs_mutex);
    502 
    503         ALOGV("%s: data_fd = %d", __func__, data_fd);
    504         ALOGV("%s: iio_device_path = %s", __func__, buffer_access);
    505         ALOGV("%s: ctrl sysfs_path = %s", __func__, fixed_sysfs_path);
    506 
    507         setEnable(0, 1); // Inside this function call, we use sys_fs_mutex
    508     }
    509 
    510     int gs_temp_data[G_SENSOR_CALIBRATION_DATA_SIZE] = {0};
    511     int compass_temp_data[COMPASS_CALIBRATION_DATA_SIZE] = {0};
    512 
    513 
    514     ALOGV("%s: 22 Before pthread_mutex_lock()\n", __func__);
    515     pthread_mutex_lock(&sys_fs_mutex);
    516     ALOGV("%s: 22 Acquired pthread_mutex_lock()\n", __func__);
    517 
    518     //Sensor Calibration init . Waiting for firmware ready
    519     rc = cw_read_calibrator_file(CW_MAGNETIC, SAVE_PATH_MAG, compass_temp_data);
    520     if (rc == 0) {
    521         ALOGD("Get compass calibration data from data/misc/ x is %d ,y is %d ,z is %d\n",
    522               compass_temp_data[0], compass_temp_data[1], compass_temp_data[2]);
    523         strcpy(&fixed_sysfs_path[fixed_sysfs_path_len], "calibrator_data_mag");
    524         cw_save_calibrator_file(CW_MAGNETIC, fixed_sysfs_path, compass_temp_data);
    525     } else {
    526         ALOGI("Compass calibration data does not exist\n");
    527     }
    528 
    529     rc = cw_read_calibrator_file(CW_ACCELERATION, SAVE_PATH_ACC, gs_temp_data);
    530     if (rc == 0) {
    531         ALOGD("Get g-sensor user calibration data from data/misc/ x is %d ,y is %d ,z is %d\n",
    532               gs_temp_data[0],gs_temp_data[1],gs_temp_data[2]);
    533         strcpy(&fixed_sysfs_path[fixed_sysfs_path_len], "calibrator_data_acc");
    534         if(!(gs_temp_data[0] == 0 && gs_temp_data[1] == 0 && gs_temp_data[2] == 0 )) {
    535             cw_save_calibrator_file(CW_ACCELERATION, fixed_sysfs_path, gs_temp_data);
    536         }
    537     } else {
    538         ALOGI("G-Sensor user calibration data does not exist\n");
    539     }
    540 
    541     pthread_mutex_unlock(&sys_fs_mutex);
    542 
    543     pthread_create(&sync_time_thread, (const pthread_attr_t *) NULL,
    544                     sync_time_thread_run, (void *)this);
    545 
    546 }
    547 
    548 CwMcuSensor::~CwMcuSensor() {
    549     if (!mEnabled.isEmpty()) {
    550         setEnable(0, 0);
    551     }
    552 }
    553 
    554 float CwMcuSensor::indexToValue(size_t index) const {
    555     static const float luxValues[LIGHTSENSOR_LEVEL] = {
    556         0.0, 10.0, 40.0, 90.0, 160.0,
    557         225.0, 320.0, 640.0, 1280.0,
    558         2600.0
    559     };
    560 
    561     const size_t maxIndex = (LIGHTSENSOR_LEVEL - 1);
    562     if (index > maxIndex) {
    563         index = maxIndex;
    564     }
    565     return luxValues[index];
    566 }
    567 
    568 int CwMcuSensor::find_handle(int32_t sensors_id) {
    569     switch (sensors_id) {
    570     case CW_ACCELERATION:
    571         return ID_A;
    572     case CW_MAGNETIC:
    573         return ID_M;
    574     case CW_GYRO:
    575         return ID_GY;
    576     case CW_PRESSURE:
    577         return ID_PS;
    578     case CW_ORIENTATION:
    579         return ID_O;
    580     case CW_ROTATIONVECTOR:
    581         return ID_RV;
    582     case CW_LINEARACCELERATION:
    583         return ID_LA;
    584     case CW_GRAVITY:
    585         return ID_G;
    586     case CW_MAGNETIC_UNCALIBRATED:
    587         return ID_CW_MAGNETIC_UNCALIBRATED;
    588     case CW_GYROSCOPE_UNCALIBRATED:
    589         return ID_CW_GYROSCOPE_UNCALIBRATED;
    590     case CW_GAME_ROTATION_VECTOR:
    591         return ID_CW_GAME_ROTATION_VECTOR;
    592     case CW_GEOMAGNETIC_ROTATION_VECTOR:
    593         return ID_CW_GEOMAGNETIC_ROTATION_VECTOR;
    594     case CW_LIGHT:
    595         return ID_L;
    596     case CW_SIGNIFICANT_MOTION:
    597         return ID_CW_SIGNIFICANT_MOTION;
    598     case CW_STEP_DETECTOR:
    599         return ID_CW_STEP_DETECTOR;
    600     case CW_STEP_COUNTER:
    601         return ID_CW_STEP_COUNTER;
    602     case CW_ACCELERATION_W:
    603         return ID_A_W;
    604     case CW_MAGNETIC_W:
    605         return ID_M_W;
    606     case CW_GYRO_W:
    607         return ID_GY_W;
    608     case CW_PRESSURE_W:
    609         return ID_PS_W;
    610     case CW_ORIENTATION_W:
    611         return ID_O_W;
    612     case CW_ROTATIONVECTOR_W:
    613         return ID_RV_W;
    614     case CW_LINEARACCELERATION_W:
    615         return ID_LA_W;
    616     case CW_GRAVITY_W:
    617         return ID_G_W;
    618     case CW_MAGNETIC_UNCALIBRATED_W:
    619         return ID_CW_MAGNETIC_UNCALIBRATED_W;
    620     case CW_GYROSCOPE_UNCALIBRATED_W:
    621         return ID_CW_GYROSCOPE_UNCALIBRATED_W;
    622     case CW_GAME_ROTATION_VECTOR_W:
    623         return ID_CW_GAME_ROTATION_VECTOR_W;
    624     case CW_GEOMAGNETIC_ROTATION_VECTOR_W:
    625         return ID_CW_GEOMAGNETIC_ROTATION_VECTOR_W;
    626     case CW_STEP_DETECTOR_W:
    627         return ID_CW_STEP_DETECTOR_W;
    628     case CW_STEP_COUNTER_W:
    629         return ID_CW_STEP_COUNTER_W;
    630     default:
    631         return 0xFF;
    632     }
    633 }
    634 
    635 bool CwMcuSensor::is_batch_wake_sensor(int32_t handle) {
    636     switch (handle) {
    637     case ID_A_W:
    638     case ID_M_W:
    639     case ID_GY_W:
    640     case ID_PS_W:
    641     case ID_O_W:
    642     case ID_RV_W:
    643     case ID_LA_W:
    644     case ID_G_W:
    645     case ID_CW_MAGNETIC_UNCALIBRATED_W:
    646     case ID_CW_GYROSCOPE_UNCALIBRATED_W:
    647     case ID_CW_GAME_ROTATION_VECTOR_W:
    648     case ID_CW_GEOMAGNETIC_ROTATION_VECTOR_W:
    649     case ID_CW_STEP_DETECTOR_W:
    650     case ID_CW_STEP_COUNTER_W:
    651         return true;
    652     default:
    653         return false;
    654     }
    655 }
    656 
    657 int CwMcuSensor::find_sensor(int32_t handle) {
    658     int what = -1;
    659 
    660     switch (handle) {
    661     case ID_A:
    662         what = CW_ACCELERATION;
    663         break;
    664     case ID_A_W:
    665         what = CW_ACCELERATION_W;
    666         break;
    667     case ID_M:
    668         what = CW_MAGNETIC;
    669         break;
    670     case ID_M_W:
    671         what = CW_MAGNETIC_W;
    672         break;
    673     case ID_GY:
    674         what = CW_GYRO;
    675         break;
    676     case ID_GY_W:
    677         what = CW_GYRO_W;
    678         break;
    679     case ID_PS:
    680         what = CW_PRESSURE;
    681         break;
    682     case ID_PS_W:
    683         what = CW_PRESSURE_W;
    684         break;
    685     case ID_O:
    686         what = CW_ORIENTATION;
    687         break;
    688     case ID_O_W:
    689         what = CW_ORIENTATION_W;
    690         break;
    691     case ID_RV:
    692         what = CW_ROTATIONVECTOR;
    693         break;
    694     case ID_RV_W:
    695         what = CW_ROTATIONVECTOR_W;
    696         break;
    697     case ID_LA:
    698         what = CW_LINEARACCELERATION;
    699         break;
    700     case ID_LA_W:
    701         what = CW_LINEARACCELERATION_W;
    702         break;
    703     case ID_G:
    704         what = CW_GRAVITY;
    705         break;
    706     case ID_G_W:
    707         what = CW_GRAVITY_W;
    708         break;
    709     case ID_CW_MAGNETIC_UNCALIBRATED:
    710         what = CW_MAGNETIC_UNCALIBRATED;
    711         break;
    712     case ID_CW_MAGNETIC_UNCALIBRATED_W:
    713         what = CW_MAGNETIC_UNCALIBRATED_W;
    714         break;
    715     case ID_CW_GYROSCOPE_UNCALIBRATED:
    716         what = CW_GYROSCOPE_UNCALIBRATED;
    717         break;
    718     case ID_CW_GYROSCOPE_UNCALIBRATED_W:
    719         what = CW_GYROSCOPE_UNCALIBRATED_W;
    720         break;
    721     case ID_CW_GAME_ROTATION_VECTOR:
    722         what = CW_GAME_ROTATION_VECTOR;
    723         break;
    724     case ID_CW_GAME_ROTATION_VECTOR_W:
    725         what = CW_GAME_ROTATION_VECTOR_W;
    726         break;
    727     case ID_CW_GEOMAGNETIC_ROTATION_VECTOR:
    728         what = CW_GEOMAGNETIC_ROTATION_VECTOR;
    729         break;
    730     case ID_CW_GEOMAGNETIC_ROTATION_VECTOR_W:
    731         what = CW_GEOMAGNETIC_ROTATION_VECTOR_W;
    732         break;
    733     case ID_CW_SIGNIFICANT_MOTION:
    734         what = CW_SIGNIFICANT_MOTION;
    735         break;
    736     case ID_CW_STEP_DETECTOR:
    737         what = CW_STEP_DETECTOR;
    738         break;
    739     case ID_CW_STEP_DETECTOR_W:
    740         what = CW_STEP_DETECTOR_W;
    741         break;
    742     case ID_CW_STEP_COUNTER:
    743         what = CW_STEP_COUNTER;
    744         break;
    745     case ID_CW_STEP_COUNTER_W:
    746         what = CW_STEP_COUNTER_W;
    747         break;
    748     case ID_L:
    749         what = CW_LIGHT;
    750         break;
    751     }
    752 
    753     return what;
    754 }
    755 
    756 int CwMcuSensor::getEnable(int32_t handle) {
    757     ALOGV("CwMcuSensor::getEnable: handle = %d\n", handle);
    758     return  0;
    759 }
    760 
    761 int CwMcuSensor::setEnable(int32_t handle, int en) {
    762 
    763     int what;
    764     int err = 0;
    765     int flags = !!en;
    766     int fd;
    767     char buf[10];
    768     int temp_data[COMPASS_CALIBRATION_DATA_SIZE];
    769     char value[PROPERTY_VALUE_MAX] = {0};
    770     int rc;
    771 
    772     ALOGV("%s: Before pthread_mutex_lock()\n", __func__);
    773     pthread_mutex_lock(&sys_fs_mutex);
    774     ALOGV("%s: Acquired pthread_mutex_lock()\n", __func__);
    775 
    776     property_get("debug.sensorhal.fill.block", value, "0");
    777     ALOGV("CwMcuSensor::setEnable: debug.sensorhal.fill.block= %s", value);
    778     fill_block_debug = atoi(value) == 1;
    779 
    780     what = find_sensor(handle);
    781 
    782     ALOGV("CwMcuSensor::setEnable: "
    783           "[v13-Dynamic adjust the IIO buffer], handle = %d, en = %d, what = %d\n",
    784           handle, en, what);
    785 
    786     if (uint32_t(what) >= numSensors) {
    787         pthread_mutex_unlock(&sys_fs_mutex);
    788         return -EINVAL;
    789     }
    790 
    791     if (en) offset_reset[what] = true;
    792 
    793     strcpy(&fixed_sysfs_path[fixed_sysfs_path_len], "enable");
    794     fd = open(fixed_sysfs_path, O_RDWR);
    795     if (fd >= 0) {
    796         int n = snprintf(buf, sizeof(buf), "%d %d\n", what, flags);
    797         err = write(fd, buf, min(n, sizeof(buf)));
    798         if (err < 0) {
    799             ALOGE("%s: write failed: %s", __func__, strerror(errno));
    800         }
    801 
    802         close(fd);
    803 
    804         if (flags) {
    805             mEnabled.markBit(what);
    806         } else {
    807             mEnabled.clearBit(what);
    808         }
    809 
    810         if (mEnabled.isEmpty()) {
    811             if (sysfs_set_input_attr_by_int("buffer/enable", 0) < 0) {
    812                 ALOGE("CwMcuSensor::setEnable: set buffer disable failed: %s\n", strerror(errno));
    813             } else {
    814                 ALOGV("CwMcuSensor::setEnable: set IIO buffer enable = 0\n");
    815             }
    816         }
    817     } else {
    818         ALOGE("%s open failed: %s", __func__, strerror(errno));
    819     }
    820 
    821 
    822     // Sensor Calibration init. Waiting for firmware ready
    823     if (!flags &&
    824             ((what == CW_MAGNETIC) ||
    825              (what == CW_ORIENTATION) ||
    826              (what == CW_ROTATIONVECTOR))) {
    827         ALOGV("Save Compass calibration data");
    828         strcpy(&fixed_sysfs_path[fixed_sysfs_path_len], "calibrator_data_mag");
    829         rc = cw_read_calibrator_file(CW_MAGNETIC, fixed_sysfs_path, temp_data);
    830         if (rc== 0) {
    831             cw_save_calibrator_file(CW_MAGNETIC, SAVE_PATH_MAG, temp_data);
    832         } else {
    833             ALOGI("Compass calibration data from driver fails\n");
    834         }
    835     }
    836 
    837     pthread_mutex_unlock(&sys_fs_mutex);
    838     return 0;
    839 }
    840 
    841 int CwMcuSensor::batch(int handle, int flags, int64_t period_ns, int64_t timeout)
    842 {
    843     int what;
    844     int fd;
    845     char buf[32] = {0};
    846     int err;
    847     int delay_ms;
    848     int timeout_ms;
    849     bool dryRun = false;
    850 
    851     ALOGV("CwMcuSensor::batch++: handle = %d, flags = %d, period_ns = %" PRId64 ", timeout = %" PRId64 "\n",
    852         handle, flags, period_ns, timeout);
    853 
    854     what = find_sensor(handle);
    855     delay_ms = period_ns/NS_PER_MS; // int64_t is being dropped to an int type
    856     timeout_ms = timeout/NS_PER_MS; // int64_t is being dropped to an int type
    857 
    858     if(flags & SENSORS_BATCH_DRY_RUN) {
    859         dryRun = true;
    860     }
    861 
    862     if (uint32_t(what) >= CW_SENSORS_ID_END) {
    863         return -EINVAL;
    864     }
    865 
    866     if(is_batch_wake_sensor(handle)) {
    867         flags |= SENSORS_BATCH_WAKE_UPON_FIFO_FULL;
    868         ALOGV("CwMcuSensor::batch: SENSORS_BATCH_WAKE_UPON_FIFO_FULL~!!\n");
    869     } else
    870         flags &= ~SENSORS_BATCH_WAKE_UPON_FIFO_FULL;
    871 
    872     switch (what) {
    873     case CW_LIGHT:
    874     case CW_SIGNIFICANT_MOTION:
    875         if (timeout > 0) {
    876             ALOGI("CwMcuSensor::batch: handle = %d, not support batch mode", handle);
    877             return -EINVAL;
    878         }
    879         break;
    880     default:
    881         break;
    882     }
    883 
    884     if (dryRun == true) {
    885         ALOGV("CwMcuSensor::batch: SENSORS_BATCH_DRY_RUN is set\n");
    886         return 0;
    887     }
    888 
    889     ALOGV("%s: Before pthread_mutex_lock()\n", __func__);
    890     pthread_mutex_lock(&sys_fs_mutex);
    891     ALOGV("%s: Acquired pthread_mutex_lock()\n", __func__);
    892 
    893     if (mEnabled.isEmpty()) {
    894         int i;
    895         int iio_buf_size;
    896 
    897         if (!init_trigger_done) {
    898             err = sysfs_set_input_attr("trigger/current_trigger",
    899                                       mTriggerName, strlen(mTriggerName));
    900             if (err < 0) {
    901                 ALOGE("CwMcuSensor::batch: set current trigger failed: err = %d, strerr() = %s\n",
    902                       err, strerror(errno));
    903             } else {
    904                 init_trigger_done = true;
    905             }
    906         }
    907 
    908         iio_buf_size = IIO_MAX_BUFF_SIZE;
    909         for (i = 0; i < IIO_BUF_SIZE_RETRY; i++) {
    910             if (sysfs_set_input_attr_by_int("buffer/length", iio_buf_size) < 0) {
    911                 ALOGE("CwMcuSensor::batch: set IIO buffer length (%d) failed: %s\n",
    912                       iio_buf_size, strerror(errno));
    913             } else {
    914                 if (sysfs_set_input_attr_by_int("buffer/enable", 1) < 0) {
    915                     ALOGE("CwMcuSensor::batch: set IIO buffer enable failed: %s, i = %d, "
    916                           "iio_buf_size = %d\n", strerror(errno), i , iio_buf_size);
    917                 } else {
    918                     ALOGI("CwMcuSensor::batch: set IIO buffer length = %d, success\n", iio_buf_size);
    919                     break;
    920                 }
    921             }
    922             iio_buf_size /= 2;
    923         }
    924     }
    925 
    926     strcpy(&fixed_sysfs_path[fixed_sysfs_path_len], "batch_enable");
    927 
    928     fd = open(fixed_sysfs_path, O_RDWR);
    929     if (fd < 0) {
    930         err = -errno;
    931     } else {
    932         int n = snprintf(buf, sizeof(buf), "%d %d %d %d\n", what, flags, delay_ms, timeout_ms);
    933         err = write(fd, buf, min(n, sizeof(buf)));
    934         if (err < 0) {
    935             err = -errno;
    936         } else {
    937             err = 0;
    938         }
    939         close(fd);
    940     }
    941     pthread_mutex_unlock(&sys_fs_mutex);
    942 
    943     ALOGV("CwMcuSensor::batch: fd = %d, sensors_id = %d, flags = %d, delay_ms= %d,"
    944           " timeout_ms = %d, path = %s, err = %d\n",
    945           fd , what, flags, delay_ms, timeout_ms, fixed_sysfs_path, err);
    946 
    947     return err;
    948 }
    949 
    950 
    951 int CwMcuSensor::flush(int handle)
    952 {
    953     int what;
    954     int fd;
    955     char buf[10] = {0};
    956     int err;
    957 
    958     what = find_sensor(handle);
    959 
    960     if (uint32_t(what) >= CW_SENSORS_ID_END) {
    961         return -EINVAL;
    962     }
    963 
    964     ALOGV("%s: Before pthread_mutex_lock()\n", __func__);
    965     pthread_mutex_lock(&sys_fs_mutex);
    966     ALOGV("%s: Acquired pthread_mutex_lock()\n", __func__);
    967 
    968     strcpy(&fixed_sysfs_path[fixed_sysfs_path_len], "flush");
    969 
    970     fd = open(fixed_sysfs_path, O_RDWR);
    971     if (fd >= 0) {
    972         int n = snprintf(buf, sizeof(buf), "%d\n", what);
    973         err = write(fd, buf, min(n, sizeof(buf)));
    974         if (err < 0) {
    975             err = -errno;
    976         } else {
    977             err = 0;
    978         }
    979         close(fd);
    980     } else {
    981         ALOGI("CwMcuSensor::flush: flush not supported\n");
    982         err = -EINVAL;
    983     }
    984 
    985     pthread_mutex_unlock(&sys_fs_mutex);
    986     ALOGI("CwMcuSensor::flush: fd = %d, sensors_id = %d, path = %s, err = %d\n",
    987           fd, what, fixed_sysfs_path, err);
    988     return err;
    989 }
    990 
    991 
    992 bool CwMcuSensor::hasPendingEvents() const {
    993     return !mPendingMask.isEmpty();
    994 }
    995 
    996 int CwMcuSensor::setDelay(int32_t handle, int64_t delay_ns) {
    997     char buf[80];
    998     int fd;
    999     int what;
   1000     int rc;
   1001 
   1002     ALOGV("%s: Before pthread_mutex_lock()\n", __func__);
   1003     pthread_mutex_lock(&sys_fs_mutex);
   1004     ALOGV("%s: Acquired pthread_mutex_lock()\n", __func__);
   1005 
   1006     ALOGV("CwMcuSensor::setDelay: handle = %" PRId32 ", delay_ns = %" PRId64 "\n",
   1007             handle, delay_ns);
   1008 
   1009     what = find_sensor(handle);
   1010     if (uint32_t(what) >= numSensors) {
   1011         pthread_mutex_unlock(&sys_fs_mutex);
   1012         return -EINVAL;
   1013     }
   1014     strcpy(&fixed_sysfs_path[fixed_sysfs_path_len], "delay_ms");
   1015     fd = open(fixed_sysfs_path, O_RDWR);
   1016     if (fd >= 0) {
   1017         size_t n = snprintf(buf, sizeof(buf), "%d %lld\n", what, (delay_ns/NS_PER_MS));
   1018         write(fd, buf, min(n, sizeof(buf)));
   1019         close(fd);
   1020     }
   1021 
   1022     pthread_mutex_unlock(&sys_fs_mutex);
   1023     return 0;
   1024 
   1025 }
   1026 
   1027 void CwMcuSensor::calculate_rv_4th_element(int sensors_id) {
   1028     switch (sensors_id) {
   1029     case CW_ROTATIONVECTOR:
   1030     case CW_GAME_ROTATION_VECTOR:
   1031     case CW_GEOMAGNETIC_ROTATION_VECTOR:
   1032     case CW_ROTATIONVECTOR_W:
   1033     case CW_GAME_ROTATION_VECTOR_W:
   1034     case CW_GEOMAGNETIC_ROTATION_VECTOR_W:
   1035         float q0, q1, q2, q3;
   1036 
   1037         q1 = mPendingEvents[sensors_id].data[0];
   1038         q2 = mPendingEvents[sensors_id].data[1];
   1039         q3 = mPendingEvents[sensors_id].data[2];
   1040 
   1041         q0 = 1 - q1*q1 - q2*q2 - q3*q3;
   1042         q0 = (q0 > 0) ? (float)sqrt(q0) : 0;
   1043 
   1044         mPendingEvents[sensors_id].data[3] = q0;
   1045         break;
   1046     default:
   1047         break;
   1048     }
   1049 }
   1050 
   1051 int CwMcuSensor::readEvents(sensors_event_t* data, int count) {
   1052     uint64_t mtimestamp;
   1053 
   1054     if (count < 1) {
   1055         return -EINVAL;
   1056     }
   1057 
   1058     ALOGD_IF(fill_block_debug == 1, "CwMcuSensor::readEvents: Before fill\n");
   1059     ssize_t n = mInputReader.fill(data_fd);
   1060     ALOGD_IF(fill_block_debug == 1, "CwMcuSensor::readEvents: After fill, n = %zd\n", n);
   1061     if (n < 0) {
   1062         return n;
   1063     }
   1064 
   1065     cw_event const* event;
   1066     uint8_t data_temp[24];
   1067     int id;
   1068     int numEventReceived = 0;
   1069 
   1070     while (count && mInputReader.readEvent(&event)) {
   1071 
   1072         memcpy(data_temp, event->data, sizeof(data_temp));
   1073 
   1074         id = processEvent(data_temp);
   1075         if (id == CW_META_DATA) {
   1076             *data++ = mPendingEventsFlush;
   1077             count--;
   1078             numEventReceived++;
   1079             ALOGV("CwMcuSensor::readEvents: metadata = %d\n", mPendingEventsFlush.meta_data.sensor);
   1080         } else if ((id == TIME_DIFF_EXHAUSTED) || (id == CW_TIME_BASE)) {
   1081             ALOGV("readEvents: id = %d\n", id);
   1082         } else {
   1083             /*** The algorithm which parsed mcu_time into cpu_time for each event ***/
   1084             uint64_t event_mcu_time = mPendingEvents[id].timestamp;
   1085             uint64_t event_cpu_time;
   1086 
   1087             if (event_mcu_time < last_mcu_timestamp[id]) {
   1088                 ALOGE("Do syncronization due to wrong delta mcu_timestamp\n");
   1089                 ALOGE("curr_ts = %" PRIu64 " ns, last_ts = %" PRIu64 " ns",
   1090                     event_mcu_time, last_mcu_timestamp[id]);
   1091                 sync_time_thread_in_class();
   1092             }
   1093 
   1094             pthread_mutex_lock(&sync_timestamp_algo_mutex);
   1095 
   1096             if (offset_reset[id]) {
   1097                 ALOGV("offset changed, id = %d, offset = %" PRId64 "\n", id, time_offset);
   1098                 offset_reset[id] = false;
   1099                 event_cpu_time = event_mcu_time + time_offset;
   1100                 if (event_cpu_time <= last_cpu_timestamp[id]) {
   1101                     int64_t event_mcu_diff = (event_mcu_time - last_mcu_timestamp[id]);
   1102                     int64_t event_cpu_diff = event_mcu_diff * time_slope;
   1103                     event_cpu_time = last_cpu_timestamp[id] + event_cpu_diff;
   1104                 }
   1105             } else {
   1106                 int64_t event_mcu_diff = (event_mcu_time - last_mcu_timestamp[id]);
   1107                 int64_t event_cpu_diff = event_mcu_diff * time_slope;
   1108                 event_cpu_time = last_cpu_timestamp[id] + event_cpu_diff;
   1109             }
   1110             pthread_mutex_unlock(&sync_timestamp_algo_mutex);
   1111 
   1112             pthread_mutex_lock(&last_timestamp_mutex);
   1113 
   1114             mtimestamp = getTimestamp();
   1115             ALOGV("readEvents: id = %d, accuracy = %d\n"
   1116                   , id
   1117                   , mPendingEvents[id].acceleration.status);
   1118             ALOGV("readEvents: id = %d,"
   1119                   " mcu_time = %" PRId64 " ms,"
   1120                   " cpu_time = %" PRId64 " ns,"
   1121                   " delta = %" PRId64 " us,"
   1122                   " HALtime = %" PRId64 " ns\n",
   1123                   id,
   1124                   event_mcu_time / NS_PER_MS,
   1125                   event_cpu_time,
   1126                   (event_cpu_time - last_cpu_timestamp[id]) / NS_PER_US,
   1127                   mtimestamp);
   1128             event_cpu_time = (mtimestamp > event_cpu_time) ? event_cpu_time : mtimestamp;
   1129             last_mcu_timestamp[id] = event_mcu_time;
   1130             last_cpu_timestamp[id] = event_cpu_time;
   1131             pthread_mutex_unlock(&last_timestamp_mutex);
   1132             /*** The algorithm which parsed mcu_time into cpu_time for each event ***/
   1133 
   1134             mPendingEvents[id].timestamp = event_cpu_time;
   1135 
   1136             if (mEnabled.hasBit(id)) {
   1137                 if (id == CW_SIGNIFICANT_MOTION) {
   1138                     setEnable(ID_CW_SIGNIFICANT_MOTION, 0);
   1139                 }
   1140                 calculate_rv_4th_element(id);
   1141                 *data++ = mPendingEvents[id];
   1142                 count--;
   1143                 numEventReceived++;
   1144             }
   1145         }
   1146 
   1147         mInputReader.next();
   1148     }
   1149     return numEventReceived;
   1150 }
   1151 
   1152 
   1153 int CwMcuSensor::processEvent(uint8_t *event) {
   1154     int sensorsid = 0;
   1155     int16_t data[3];
   1156     int16_t bias[3];
   1157     int64_t time;
   1158 
   1159     sensorsid = (int)event[0];
   1160     memcpy(data, &event[1], 6);
   1161     memcpy(bias, &event[7], 6);
   1162     memcpy(&time, &event[13], 8);
   1163 
   1164     mPendingEvents[sensorsid].timestamp = time * NS_PER_MS;
   1165 
   1166     switch (sensorsid) {
   1167     case CW_ORIENTATION:
   1168     case CW_ORIENTATION_W:
   1169         mPendingMask.markBit(sensorsid);
   1170         if ((sensorsid == CW_ORIENTATION) || (sensorsid == CW_ORIENTATION_W)) {
   1171             mPendingEvents[sensorsid].orientation.status = bias[0];
   1172         }
   1173         mPendingEvents[sensorsid].data[0] = (float)data[0] * CONVERT_10;
   1174         mPendingEvents[sensorsid].data[1] = (float)data[1] * CONVERT_10;
   1175         mPendingEvents[sensorsid].data[2] = (float)data[2] * CONVERT_10;
   1176         break;
   1177     case CW_ACCELERATION:
   1178     case CW_MAGNETIC:
   1179     case CW_GYRO:
   1180     case CW_LINEARACCELERATION:
   1181     case CW_GRAVITY:
   1182     case CW_ACCELERATION_W:
   1183     case CW_MAGNETIC_W:
   1184     case CW_GYRO_W:
   1185     case CW_LINEARACCELERATION_W:
   1186     case CW_GRAVITY_W:
   1187         mPendingMask.markBit(sensorsid);
   1188         if ((sensorsid == CW_MAGNETIC) || (sensorsid == CW_MAGNETIC_W)) {
   1189             mPendingEvents[sensorsid].magnetic.status = bias[0];
   1190             ALOGV("CwMcuSensor::processEvent: magnetic accuracy = %d\n",
   1191                   mPendingEvents[sensorsid].magnetic.status);
   1192         }
   1193         mPendingEvents[sensorsid].data[0] = (float)data[0] * CONVERT_100;
   1194         mPendingEvents[sensorsid].data[1] = (float)data[1] * CONVERT_100;
   1195         mPendingEvents[sensorsid].data[2] = (float)data[2] * CONVERT_100;
   1196         break;
   1197     case CW_PRESSURE:
   1198     case CW_PRESSURE_W:
   1199         mPendingMask.markBit(sensorsid);
   1200         // .pressure is data[0] and the unit is hectopascal (hPa)
   1201         mPendingEvents[sensorsid].pressure = ((float)*(int32_t *)(&data[0])) * CONVERT_100;
   1202         // data[1] is not used, and data[2] is the temperature
   1203         mPendingEvents[sensorsid].data[2] = ((float)data[2]) * CONVERT_100;
   1204         break;
   1205     case CW_ROTATIONVECTOR:
   1206     case CW_GAME_ROTATION_VECTOR:
   1207     case CW_GEOMAGNETIC_ROTATION_VECTOR:
   1208     case CW_ROTATIONVECTOR_W:
   1209     case CW_GAME_ROTATION_VECTOR_W:
   1210     case CW_GEOMAGNETIC_ROTATION_VECTOR_W:
   1211         mPendingMask.markBit(sensorsid);
   1212         mPendingEvents[sensorsid].data[0] = (float)data[0] * CONVERT_10000;
   1213         mPendingEvents[sensorsid].data[1] = (float)data[1] * CONVERT_10000;
   1214         mPendingEvents[sensorsid].data[2] = (float)data[2] * CONVERT_10000;
   1215         break;
   1216     case CW_MAGNETIC_UNCALIBRATED:
   1217     case CW_GYROSCOPE_UNCALIBRATED:
   1218     case CW_MAGNETIC_UNCALIBRATED_W:
   1219     case CW_GYROSCOPE_UNCALIBRATED_W:
   1220         mPendingMask.markBit(sensorsid);
   1221         mPendingEvents[sensorsid].data[0] = (float)data[0] * CONVERT_100;
   1222         mPendingEvents[sensorsid].data[1] = (float)data[1] * CONVERT_100;
   1223         mPendingEvents[sensorsid].data[2] = (float)data[2] * CONVERT_100;
   1224         mPendingEvents[sensorsid].data[3] = (float)bias[0] * CONVERT_100;
   1225         mPendingEvents[sensorsid].data[4] = (float)bias[1] * CONVERT_100;
   1226         mPendingEvents[sensorsid].data[5] = (float)bias[2] * CONVERT_100;
   1227         break;
   1228     case CW_SIGNIFICANT_MOTION:
   1229         mPendingMask.markBit(sensorsid);
   1230         mPendingEvents[sensorsid].data[0] = 1.0;
   1231         ALOGV("SIGNIFICANT timestamp = %" PRIu64 "\n", mPendingEvents[sensorsid].timestamp);
   1232         break;
   1233     case CW_LIGHT:
   1234         mPendingMask.markBit(sensorsid);
   1235         mPendingEvents[sensorsid].light = indexToValue(data[0]);
   1236         break;
   1237     case CW_STEP_DETECTOR:
   1238     case CW_STEP_DETECTOR_W:
   1239         mPendingMask.markBit(sensorsid);
   1240         mPendingEvents[sensorsid].data[0] = data[0];
   1241         ALOGV("STEP_DETECTOR, timestamp = %" PRIu64 "\n", mPendingEvents[sensorsid].timestamp);
   1242         break;
   1243     case CW_STEP_COUNTER:
   1244     case CW_STEP_COUNTER_W:
   1245         mPendingMask.markBit(sensorsid);
   1246         // We use 4 bytes in SensorHUB
   1247         mPendingEvents[sensorsid].u64.step_counter = *(uint32_t *)&data[0];
   1248         mPendingEvents[sensorsid].u64.step_counter += 0x100000000LL * (*(uint32_t *)&bias[0]);
   1249         ALOGV("processEvent: step counter = %" PRId64 "\n",
   1250               mPendingEvents[sensorsid].u64.step_counter);
   1251         break;
   1252     case CW_META_DATA:
   1253         mPendingEventsFlush.meta_data.what = META_DATA_FLUSH_COMPLETE;
   1254         mPendingEventsFlush.meta_data.sensor = find_handle(data[0]);
   1255         ALOGV("CW_META_DATA: meta_data.sensor = %d, data[0] = %d\n",
   1256               mPendingEventsFlush.meta_data.sensor, data[0]);
   1257         break;
   1258     default:
   1259         ALOGW("%s: Unknown sensorsid = %d\n", __func__, sensorsid);
   1260         break;
   1261     }
   1262 
   1263     return sensorsid;
   1264 }
   1265 
   1266 
   1267 void CwMcuSensor::cw_save_calibrator_file(int type, const char * path, int* str) {
   1268     FILE *fp_file;
   1269     int i;
   1270     int rc;
   1271 
   1272     ALOGV("CwMcuSensor::cw_save_calibrator_file: path = %s\n", path);
   1273 
   1274     fp_file = fopen(path, "w+");
   1275     if (!fp_file) {
   1276         ALOGE("CwMcuSensor::cw_save_calibrator_file: open file '%s' failed: %s\n",
   1277               path, strerror(errno));
   1278         return;
   1279     }
   1280 
   1281     if ((type == CW_GYRO) || (type == CW_ACCELERATION)) {
   1282         fprintf(fp_file, "%d %d %d\n", str[0], str[1], str[2]);
   1283     } else if(type == CW_MAGNETIC) {
   1284         for (i = 0; i < COMPASS_CALIBRATION_DATA_SIZE; i++) {
   1285             ALOGV("CwMcuSensor::cw_save_calibrator_file: str[%d] = %d\n", i, str[i]);
   1286             rc = fprintf(fp_file, "%d%c", str[i], (i == (COMPASS_CALIBRATION_DATA_SIZE-1)) ? '\n' : ' ');
   1287             if (rc < 0) {
   1288                 ALOGE("CwMcuSensor::cw_save_calibrator_file: fprintf fails, rc = %d\n", rc);
   1289             }
   1290         }
   1291     }
   1292 
   1293     fclose(fp_file);
   1294     return;
   1295 }
   1296 
   1297 int CwMcuSensor::cw_read_calibrator_file(int type, const char * path, int* str) {
   1298     FILE *fp;
   1299     int readBytes;
   1300     int data[COMPASS_CALIBRATION_DATA_SIZE] = {0};
   1301     unsigned int i;
   1302     int my_errno;
   1303 
   1304     ALOGV("CwMcuSensor::cw_read_calibrator_file: path = %s\n", path);
   1305 
   1306     fp = fopen(path, "r");
   1307     if (!fp) {
   1308         ALOGE("CwMcuSensor::cw_read_calibrator_file: open file '%s' failed: %s\n",
   1309               path, strerror(errno));
   1310         // errno is reset to 0 before return
   1311         return -1;
   1312     }
   1313 
   1314     if (type == CW_GYRO || type == CW_ACCELERATION) {
   1315         readBytes = fscanf(fp, "%d %d %d\n", &str[0], &str[1], &str[2]);
   1316         my_errno = errno;
   1317         if (readBytes != 3) {
   1318             ALOGE("CwMcuSensor::cw_read_calibrator_file: fscanf3, readBytes = %d, strerror = %s\n", readBytes, strerror(my_errno));
   1319         }
   1320 
   1321     } else if (type == CW_MAGNETIC) {
   1322         ALOGV("CwMcuSensor::cw_read_calibrator_file: COMPASS_CALIBRATION_DATA_SIZE = %d\n", COMPASS_CALIBRATION_DATA_SIZE);
   1323         // COMPASS_CALIBRATION_DATA_SIZE is 26
   1324         for (i = 0; i < COMPASS_CALIBRATION_DATA_SIZE; i++) {
   1325             readBytes = fscanf(fp, "%d ", &str[i]);
   1326             my_errno = errno;
   1327             ALOGV("CwMcuSensor::cw_read_calibrator_file: str[%d] = %d\n", i, str[i]);
   1328             if (readBytes < 1) {
   1329                 ALOGE("CwMcuSensor::cw_read_calibrator_file: fscanf26, readBytes = %d, strerror = %s\n", readBytes, strerror(my_errno));
   1330                 fclose(fp);
   1331                 return readBytes;
   1332             }
   1333         }
   1334     }
   1335     fclose(fp);
   1336     return 0;
   1337 }
   1338