149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow/*
249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow * Copyright (C) 2012 The Android Open Source Project
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#include <fcntl.h>
2049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow#include <errno.h>
2149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow#include <math.h>
2249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow#include <unistd.h>
2349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow#include <dirent.h>
2449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow#include <sys/select.h>
2549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow#include <cutils/log.h>
2649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow#include <linux/input.h>
2749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow#include <string.h>
2849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
2949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow#include "CompassSensor.IIO.9150.h"
3049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow#include "sensors.h"
3149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow#include "MPLSupport.h"
3249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow#include "sensor_params.h"
3349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow#include "ml_sysfs_helper.h"
3449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
3549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow#define COMPASS_MAX_SYSFS_ATTRB sizeof(compassSysFs) / sizeof(char*)
3649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow#define COMPASS_NAME "USE_SYSFS"
3749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
3849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow#if defined COMPASS_YAS53x
3949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow#pragma message("HAL:build Invensense compass cal with YAS53x IIO on secondary bus")
4049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow#define USE_MPL_COMPASS_HAL (1)
4149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow#define COMPASS_NAME        "INV_YAS530"
4249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
4349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow#elif defined COMPASS_AK8975
4449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow#pragma message("HAL:build Invensense compass cal with AK8975 on primary bus")
4549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow#define USE_MPL_COMPASS_HAL (1)
4649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow#define COMPASS_NAME        "INV_AK8975"
4749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
4849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow#elif defined INVENSENSE_COMPASS_CAL
4949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow#   define COMPASS_NAME                 "USE_SYSFS"
5049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow#pragma message("HAL:build Invensense compass cal with compass IIO on secondary bus")
5149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow#define USE_MPL_COMPASS_HAL (1)
5249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow#else
5349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow#pragma message("HAL:build third party compass cal HAL")
5449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow#define USE_MPL_COMPASS_HAL (0)
5549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow// TODO: change to vendor's name
5649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow#define COMPASS_NAME        "AKM8975"
5749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
5849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow#endif
5949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
6049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow/*****************************************************************************/
6149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
62cd79002b2edb60b25843e5f4f9a06e768bc1a568Nick VaccaroCompassSensor::CompassSensor()
6349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                  : SensorBase(NULL, NULL),
6449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                    compass_fd(-1),
6549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                    mCompassTimestamp(0),
6649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                    mCompassInputReader(8)
6749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow{
6849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    VFUNC_LOG;
6949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
7049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    if(!strcmp(COMPASS_NAME, "USE_SYSFS")) {
71cd79002b2edb60b25843e5f4f9a06e768bc1a568Nick Vaccaro        int result = find_name_by_sensor_type("in_magn_scale", "iio:device",
72cd79002b2edb60b25843e5f4f9a06e768bc1a568Nick Vaccaro                                              sensor_name);
7349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        if(result) {
7449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            LOGE("HAL:Cannot read secondary device name - (%d)", result);
7549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        }
7649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        dev_name = sensor_name;
7749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    }
78cd79002b2edb60b25843e5f4f9a06e768bc1a568Nick Vaccaro    LOGI_IF(PROCESS_VERBOSE, "HAL:Secondary Chip Id: %s", dev_name);
7949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
8049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    if(inv_init_sysfs_attributes()) {
8149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        LOGE("Error Instantiating Compass\n");
8249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        return;
8349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    }
8449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
8549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    memset(mCachedCompassData, 0, sizeof(mCachedCompassData));
8649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
8749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:cat %s (%lld)",
8849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            compassSysFs.compass_orient, getTimestamp());
8949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    FILE *fptr;
9049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    fptr = fopen(compassSysFs.compass_orient, "r");
9149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    if (fptr != NULL) {
9249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        int om[9];
93cd79002b2edb60b25843e5f4f9a06e768bc1a568Nick Vaccaro        if (fscanf(fptr, "%d,%d,%d,%d,%d,%d,%d,%d,%d",
9449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow               &om[0], &om[1], &om[2], &om[3], &om[4], &om[5],
95cd79002b2edb60b25843e5f4f9a06e768bc1a568Nick Vaccaro               &om[6], &om[7], &om[8]) < 0 || fclose(fptr) < 0) {
96cd79002b2edb60b25843e5f4f9a06e768bc1a568Nick Vaccaro            LOGE("HAL:Could not read compass mounting matrix");
97cd79002b2edb60b25843e5f4f9a06e768bc1a568Nick Vaccaro        } else {
98cd79002b2edb60b25843e5f4f9a06e768bc1a568Nick Vaccaro            LOGV_IF(EXTRA_VERBOSE, "HAL:compass mounting matrix: "
99cd79002b2edb60b25843e5f4f9a06e768bc1a568Nick Vaccaro                    "%+d %+d %+d %+d %+d %+d %+d %+d %+d", om[0], om[1], om[2],
100cd79002b2edb60b25843e5f4f9a06e768bc1a568Nick Vaccaro                    om[3], om[4], om[5], om[6], om[7], om[8]);
101cd79002b2edb60b25843e5f4f9a06e768bc1a568Nick Vaccaro            mCompassOrientation[0] = om[0];
102cd79002b2edb60b25843e5f4f9a06e768bc1a568Nick Vaccaro            mCompassOrientation[1] = om[1];
103cd79002b2edb60b25843e5f4f9a06e768bc1a568Nick Vaccaro            mCompassOrientation[2] = om[2];
104cd79002b2edb60b25843e5f4f9a06e768bc1a568Nick Vaccaro            mCompassOrientation[3] = om[3];
105cd79002b2edb60b25843e5f4f9a06e768bc1a568Nick Vaccaro            mCompassOrientation[4] = om[4];
106cd79002b2edb60b25843e5f4f9a06e768bc1a568Nick Vaccaro            mCompassOrientation[5] = om[5];
107cd79002b2edb60b25843e5f4f9a06e768bc1a568Nick Vaccaro            mCompassOrientation[6] = om[6];
108cd79002b2edb60b25843e5f4f9a06e768bc1a568Nick Vaccaro            mCompassOrientation[7] = om[7];
109cd79002b2edb60b25843e5f4f9a06e768bc1a568Nick Vaccaro            mCompassOrientation[8] = om[8];
110cd79002b2edb60b25843e5f4f9a06e768bc1a568Nick Vaccaro        }
11149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    }
11249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
11349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    if (!isIntegrated()) {
11449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        enable(ID_M, 0);
11549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    }
11649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow}
11749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
11849ea3e26ca3c6a779e527a0322e49a663333350aRosa ChowCompassSensor::~CompassSensor()
11949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow{
12049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    VFUNC_LOG;
12149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    free(pathP);
12249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    if( compass_fd > 0)
12349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        close(compass_fd);
12449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow}
12549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
12649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chowint CompassSensor::getFd() const
12749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow{
128cd79002b2edb60b25843e5f4f9a06e768bc1a568Nick Vaccaro    VFUNC_LOG;
12949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    return compass_fd;
13049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow}
13149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
13249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow/**
13349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow *  @brief        This function will enable/disable sensor.
13449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow *  @param[in]    handle
13549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow *                  which sensor to enable/disable.
13649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow *  @param[in]    en
13749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow *                  en=1, enable;
13849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow *                  en=0, disable
13949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow *  @return       if the operation is successful.
14049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow */
14149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chowint CompassSensor::enable(int32_t handle, int en)
14249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow{
14349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    VFUNC_LOG;
14449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    int res = 0;
14549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    res = write_sysfs_int(compassSysFs.compass_enable, en);
14649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    return res;
14749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow}
14849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
14949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chowint CompassSensor::setDelay(int32_t handle, int64_t ns)
15049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow{
15149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    VFUNC_LOG;
15249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    int tempFd;
15349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    int res;
15449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
15549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %.0f > %s (%lld)",
15649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            1000000000.f / ns, compassSysFs.compass_rate, getTimestamp());
15749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    mDelay = ns;
15849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    if (ns == 0)
15949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        return -1;
16049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    tempFd = open(compassSysFs.compass_rate, O_RDWR);
16149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    res = write_attribute_sensor(tempFd, 1000000000.f / ns);
16249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    if(res < 0) {
16349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        LOGE("HAL:Compass update delay error");
16449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    }
16549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    return res;
16649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow}
16749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
168cd79002b2edb60b25843e5f4f9a06e768bc1a568Nick Vaccaroint CompassSensor::turnOffCompassFifo(void)
169cd79002b2edb60b25843e5f4f9a06e768bc1a568Nick Vaccaro{
170cd79002b2edb60b25843e5f4f9a06e768bc1a568Nick Vaccaro    int i, res = 0, tempFd;
171cd79002b2edb60b25843e5f4f9a06e768bc1a568Nick Vaccaro    LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)",
172cd79002b2edb60b25843e5f4f9a06e768bc1a568Nick Vaccaro                        0, compassSysFs.compass_fifo_enable, getTimestamp());
173cd79002b2edb60b25843e5f4f9a06e768bc1a568Nick Vaccaro    res += write_sysfs_int(compassSysFs.compass_fifo_enable, 0);
174cd79002b2edb60b25843e5f4f9a06e768bc1a568Nick Vaccaro    return res;
175cd79002b2edb60b25843e5f4f9a06e768bc1a568Nick Vaccaro}
176cd79002b2edb60b25843e5f4f9a06e768bc1a568Nick Vaccaro
177cd79002b2edb60b25843e5f4f9a06e768bc1a568Nick Vaccaroint CompassSensor::turnOnCompassFifo(void)
178cd79002b2edb60b25843e5f4f9a06e768bc1a568Nick Vaccaro{
179cd79002b2edb60b25843e5f4f9a06e768bc1a568Nick Vaccaro    int i, res = 0, tempFd;
180cd79002b2edb60b25843e5f4f9a06e768bc1a568Nick Vaccaro    LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)",
181cd79002b2edb60b25843e5f4f9a06e768bc1a568Nick Vaccaro                        1, compassSysFs.compass_fifo_enable, getTimestamp());
182cd79002b2edb60b25843e5f4f9a06e768bc1a568Nick Vaccaro    res += write_sysfs_int(compassSysFs.compass_fifo_enable, 1);
183cd79002b2edb60b25843e5f4f9a06e768bc1a568Nick Vaccaro    return res;
184cd79002b2edb60b25843e5f4f9a06e768bc1a568Nick Vaccaro}
18549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
18649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow/**
18749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    @brief      This function will return the state of the sensor.
18849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    @return     1=enabled; 0=disabled
18949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow**/
19049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chowint CompassSensor::getEnable(int32_t handle)
19149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow{
19249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    VFUNC_LOG;
19349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    return mEnable;
19449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow}
19549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
19649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow/* use for Invensense compass calibration */
19749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow#define COMPASS_EVENT_DEBUG (0)
19849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chowvoid CompassSensor::processCompassEvent(const input_event *event)
19949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow{
20049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    VHANDLER_LOG;
20149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
20249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    switch (event->code) {
20349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    case EVENT_TYPE_ICOMPASS_X:
20449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        LOGV_IF(COMPASS_EVENT_DEBUG, "EVENT_TYPE_ICOMPASS_X\n");
20549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        mCachedCompassData[0] = event->value;
20649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        break;
20749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    case EVENT_TYPE_ICOMPASS_Y:
20849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        LOGV_IF(COMPASS_EVENT_DEBUG, "EVENT_TYPE_ICOMPASS_Y\n");
20949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        mCachedCompassData[1] = event->value;
21049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        break;
21149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    case EVENT_TYPE_ICOMPASS_Z:
21249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        LOGV_IF(COMPASS_EVENT_DEBUG, "EVENT_TYPE_ICOMPASS_Z\n");
21349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        mCachedCompassData[2] = event->value;
21449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        break;
21549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    }
21649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
21749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    mCompassTimestamp =
21849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        (int64_t)event->time.tv_sec * 1000000000L + event->time.tv_usec * 1000L;
21949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow}
22049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
22149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chowvoid CompassSensor::getOrientationMatrix(signed char *orient)
22249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow{
22349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    VFUNC_LOG;
22449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    memcpy(orient, mCompassOrientation, sizeof(mCompassOrientation));
22549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow}
22649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
22749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chowlong CompassSensor::getSensitivity()
22849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow{
22949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    VFUNC_LOG;
23049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
23149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    long sensitivity;
23249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:cat %s (%lld)",
23349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            compassSysFs.compass_scale, getTimestamp());
23449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    inv_read_data(compassSysFs.compass_scale, &sensitivity);
23549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    return sensitivity;
23649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow}
23749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
23849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow/**
23949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    @brief         This function is called by sensors_mpl.cpp
24049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                   to read sensor data from the driver.
24149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    @param[out]    data      sensor data is stored in this variable. Scaled such that
24249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                             1 uT = 2^16
24349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    @para[in]      timestamp data's timestamp
24449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    @return        1, if 1   sample read, 0, if not, negative if error
24549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow */
24649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chowint CompassSensor::readSample(long *data, int64_t *timestamp)
24749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow{
24849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    VHANDLER_LOG;
24949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
25049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    int numEventReceived = 0, done = 0;
25149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
25249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    ssize_t n = mCompassInputReader.fill(compass_fd);
25349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    if (n < 0) {
25449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        LOGE("HAL:no compass events read");
25549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        return n;
25649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    }
25749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
25849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    input_event const* event;
25949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
26049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    while (done == 0 && mCompassInputReader.readEvent(&event)) {
26149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        int type = event->type;
26249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        if (type == EV_REL) {
26349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            processCompassEvent(event);
26449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        } else if (type == EV_SYN) {
26549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            *timestamp = mCompassTimestamp;
26649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            memcpy(data, mCachedCompassData, sizeof(mCachedCompassData));
26749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            done = 1;
26849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        } else {
26949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            LOGE("HAL:Compass Sensor: unknown event (type=%d, code=%d)",
27049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                 type, event->code);
27149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        }
27249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        mCompassInputReader.next();
27349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    }
27449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
27549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    return done;
27649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow}
27749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
27849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow/**
27949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow *  @brief  This function will return the current delay for this sensor.
28049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow *  @return delay in nanoseconds.
28149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow */
28249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chowint64_t CompassSensor::getDelay(int32_t handle)
28349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow{
28449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    VFUNC_LOG;
28549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    return mDelay;
28649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow}
28749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
28849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chowvoid CompassSensor::fillList(struct sensor_t *list)
28949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow{
29049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    VFUNC_LOG;
29149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
29249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    const char *compass = sensor_name;
29349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
29449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    if (compass) {
29549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        if(!strcmp(compass, "INV_COMPASS")) {
29649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            list->maxRange = COMPASS_MPU9150_RANGE;
29749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            list->resolution = COMPASS_MPU9150_RESOLUTION;
29849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            list->power = COMPASS_MPU9150_POWER;
29949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            list->minDelay = COMPASS_MPU9150_MINDELAY;
30049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            return;
30149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        }
30249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        if(!strcmp(compass, "compass")
30349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                || !strcmp(compass, "INV_AK8975")
30449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                || !strncmp(compass, "AK89xx",2)
30549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                || !strncmp(compass, "ak89xx",2)) {
30649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            list->maxRange = COMPASS_AKM8975_RANGE;
30749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            list->resolution = COMPASS_AKM8975_RESOLUTION;
30849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            list->power = COMPASS_AKM8975_POWER;
30949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            list->minDelay = COMPASS_AKM8975_MINDELAY;
31049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            return;
31149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        }
312cd79002b2edb60b25843e5f4f9a06e768bc1a568Nick Vaccaro        if(!strcmp(compass, "compass")
313cd79002b2edb60b25843e5f4f9a06e768bc1a568Nick Vaccaro                || !strncmp(compass, "mlx90399",3)
314cd79002b2edb60b25843e5f4f9a06e768bc1a568Nick Vaccaro                || !strncmp(compass, "MLX90399",3)) {
315cd79002b2edb60b25843e5f4f9a06e768bc1a568Nick Vaccaro            list->maxRange = COMPASS_MPU9350_RANGE;
316cd79002b2edb60b25843e5f4f9a06e768bc1a568Nick Vaccaro            list->resolution = COMPASS_MPU9350_RESOLUTION;
317cd79002b2edb60b25843e5f4f9a06e768bc1a568Nick Vaccaro            list->power = COMPASS_MPU9350_POWER;
318cd79002b2edb60b25843e5f4f9a06e768bc1a568Nick Vaccaro            list->minDelay = COMPASS_MPU9350_MINDELAY;
319cd79002b2edb60b25843e5f4f9a06e768bc1a568Nick Vaccaro            return;
320cd79002b2edb60b25843e5f4f9a06e768bc1a568Nick Vaccaro        }
32149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        if(!strcmp(compass, "INV_YAS530")) {
32249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            list->maxRange = COMPASS_YAS53x_RANGE;
32349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            list->resolution = COMPASS_YAS53x_RESOLUTION;
32449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            list->power = COMPASS_YAS53x_POWER;
32549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            list->minDelay = COMPASS_YAS53x_MINDELAY;
32649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            return;
32749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        }
32849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        if(!strcmp(compass, "INV_AMI306")) {
32949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            list->maxRange = COMPASS_AMI306_RANGE;
33049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            list->resolution = COMPASS_AMI306_RESOLUTION;
33149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            list->power = COMPASS_AMI306_POWER;
33249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            list->minDelay = COMPASS_AMI306_MINDELAY;
33349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            return;
33449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        }
33549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    }
33649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    LOGE("HAL:unknown compass id %s -- "
33749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow         "params default to ak8975 and might be wrong.",
33849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow         compass);
33949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    list->maxRange = COMPASS_AKM8975_RANGE;
34049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    list->resolution = COMPASS_AKM8975_RESOLUTION;
34149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    list->power = COMPASS_AKM8975_POWER;
34249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    list->minDelay = COMPASS_AKM8975_MINDELAY;
34349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow}
34449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
34549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chowint CompassSensor::inv_init_sysfs_attributes(void)
34649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow{
34749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    VFUNC_LOG;
34849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
34949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    unsigned char i = 0;
35049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    char sysfs_path[MAX_SYSFS_NAME_LEN];
35149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    char iio_trigger_path[MAX_SYSFS_NAME_LEN], tbuf[2];
35249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    char *sptr;
35349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    char **dptr;
35449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    int num;
35549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
35649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    pathP = (char*)malloc(
35749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                    sizeof(char[COMPASS_MAX_SYSFS_ATTRB][MAX_SYSFS_NAME_LEN]));
35849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    sptr = pathP;
35949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    dptr = (char**)&compassSysFs;
36049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    if (sptr == NULL)
36149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        return -1;
36249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
36349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    memset(sysfs_path, 0, sizeof(sysfs_path));
36449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    memset(iio_trigger_path, 0, sizeof(iio_trigger_path));
36549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
36649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    do {
36749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        *dptr++ = sptr;
36849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        memset(sptr, 0, sizeof(sptr));
36949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        sptr += sizeof(char[MAX_SYSFS_NAME_LEN]);
37049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    } while (++i < COMPASS_MAX_SYSFS_ATTRB);
37149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
37249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    // get proper (in absolute/relative) IIO path & build MPU's sysfs paths
37349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    // inv_get_sysfs_abs_path(sysfs_path);
37449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    inv_get_sysfs_path(sysfs_path);
37549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    inv_get_iio_trigger_path(iio_trigger_path);
37649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
37749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    if (strcmp(sysfs_path, "") == 0  || strcmp(iio_trigger_path, "") == 0)
37849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        return 0;
37949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
38049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow#if defined COMPASS_AK8975
38149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    inv_get_input_number(dev_name, &num);
38249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    tbuf[0] = num + 0x30;
38349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    tbuf[1] = 0;
38449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    sprintf(sysfs_path, "%s%s", "sys/class/input/input", tbuf);
38549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    strcat(sysfs_path, "/ak8975");
38649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
38749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    sprintf(compassSysFs.compass_enable, "%s%s", sysfs_path, "/enable");
38849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    sprintf(compassSysFs.compass_rate, "%s%s", sysfs_path, "/rate");
38949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    sprintf(compassSysFs.compass_scale, "%s%s", sysfs_path, "/scale");
39049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    sprintf(compassSysFs.compass_orient, "%s%s", sysfs_path, "/compass_matrix");
39149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow#else
39249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    sprintf(compassSysFs.compass_enable, "%s%s", sysfs_path, "/compass_enable");
393cd79002b2edb60b25843e5f4f9a06e768bc1a568Nick Vaccaro    sprintf(compassSysFs.compass_fifo_enable, "%s%s", sysfs_path, "/compass_fifo_enable");
3944a28f9c897c46c42a255823f7e307169a828a025Rosa Chow    sprintf(compassSysFs.compass_rate, "%s%s", sysfs_path, "/compass_rate");
39549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    sprintf(compassSysFs.compass_scale, "%s%s", sysfs_path, "/in_magn_scale");
39649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    sprintf(compassSysFs.compass_orient, "%s%s", sysfs_path, "/compass_matrix");
39749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow#endif
39849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
39949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow#if 0
40049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    // test print sysfs paths
40149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    dptr = (char**)&compassSysFs;
40249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    for (i = 0; i < COMPASS_MAX_SYSFS_ATTRB; i++) {
40349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        LOGE("HAL:sysfs path: %s", *dptr++);
40449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    }
40549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow#endif
40649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    return 0;
40749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow}
408