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#include <fcntl.h>
1849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow#include <errno.h>
1949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow#include <math.h>
2049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow#include <poll.h>
2149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow#include <unistd.h>
2249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow#include <dirent.h>
2349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow#include <sys/select.h>
2449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow#include <cutils/log.h>
2549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow#include <linux/input.h>
2649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
2749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow#include "sensor_params.h"
2849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow#include "MPLSupport.h"
2949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
3049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow// TODO: include corresponding header file for 3rd party compass sensor
3149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow#include "CompassSensor.AKM.h"
3249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
3349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow// TODO: specify this for "fillList()" API
3449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow#define COMPASS_NAME "AKM8963"
3549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
3649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow/*****************************************************************************/
3749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
3849ea3e26ca3c6a779e527a0322e49a663333350aRosa ChowCompassSensor::CompassSensor()
3949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                    : SensorBase(NULL, NULL)
4049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow{
4149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    VFUNC_LOG;
4249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
4349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    // TODO: initiate 3rd-party's class, and disable its funtionalities
4449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    //       proper commands
4549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    mCompassSensor = new AkmSensor();
4649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)",
4749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            0, "/sys/class/compass/akm8963/enable_mag", getTimestamp());
4849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    write_sysfs_int((char*)"/sys/class/compass/akm8963/enable_mag", 0);
4949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow}
5049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
5149ea3e26ca3c6a779e527a0322e49a663333350aRosa ChowCompassSensor::~CompassSensor()
5249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow{
5349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    VFUNC_LOG;
5449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
5549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    // TODO: disable 3rd-party's funtionalities and delete the object
5649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)",
5749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            0, "/sys/class/compass/akm8963/enable_mag", getTimestamp());
5849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    write_sysfs_int((char*)"/sys/class/compass/akm8963/enable_mag", 0);
5949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    delete mCompassSensor;
6049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow}
6149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
6249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chowint CompassSensor::getFd(void) const
6349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow{
6449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    VFUNC_LOG;
6549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
6649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    // TODO: return 3rd-party's file descriptor
6749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    return mCompassSensor->getFd();
6849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow}
6949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
7049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow/**
7149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow *  @brief        This function will enable/disable sensor.
7249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow *  @param[in]    handle    which sensor to enable/disable.
7349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow *  @param[in]    en        en=1 enable, en=0 disable
7449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow *  @return       if the operation is successful.
7549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow */
7649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chowint CompassSensor::enable(int32_t handle, int en)
7749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow{
7849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    VFUNC_LOG;
7949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
8049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    // TODO: called 3rd-party's "set enable/disable" function
8149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    return mCompassSensor->setEnable(handle, en);
8249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow}
8349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
8449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chowint CompassSensor::setDelay(int32_t handle, int64_t ns)
8549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow{
8649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    VFUNC_LOG;
8749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
8849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    // TODO: called 3rd-party's "set delay" function
8949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    return mCompassSensor->setDelay(handle, ns);
9049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow}
9149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
9249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow/**
9349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    @brief      This function will return the state of the sensor.
9449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    @return     1=enabled; 0=disabled
9549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow**/
9649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chowint CompassSensor::getEnable(int32_t handle)
9749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow{
9849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    VFUNC_LOG;
9949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
10049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    // TODO: return if 3rd-party compass is enabled
10149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    return mCompassSensor->getEnable(handle);
10249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow}
10349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
10449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow/**
10549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    @brief      This function will return the current delay for this sensor.
10649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    @return     delay in nanoseconds.
10749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow**/
10849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chowint64_t CompassSensor::getDelay(int32_t handle)
10949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow{
11049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    VFUNC_LOG;
11149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
11249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    // TODO: return 3rd-party's delay time (should be in ns)
11349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    return mCompassSensor->getDelay(handle);
11449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow}
11549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
11649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow/**
11749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    @brief         Integrators need to implement this function per 3rd-party solution
11849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    @param[out]    data      sensor data is stored in this variable. Scaled such that
11949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                             1 uT = 2^16
12049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    @para[in]      timestamp data's timestamp
12149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    @return        1, if 1   sample read, 0, if not, negative if error
12249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow**/
12349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chowint CompassSensor::readSample(long *data, int64_t *timestamp)
12449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow{
12549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    VFUNC_LOG;
12649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
12749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    // TODO: need to implement "readSample()" for MPL in 3rd-party's .cpp file
12849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    return mCompassSensor->readSample(data, timestamp);
12949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow}
13049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
13149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow/**
13249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    @brief         Integrators need to implement this function per 3rd-party solution
13349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    @param[out]    data      sensor data is stored in this variable. Scaled such that
13449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow                             1 uT = 2^16
13549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    @para[in]      timestamp data's timestamp
13649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    @return        1, if 1   sample read, 0, if not, negative if error
13749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow**/
13849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chowint CompassSensor::readRawSample(float *data, int64_t *timestamp)
13949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow{
14049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    VFUNC_LOG;
14149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    long ldata[3];
14249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
14349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    int res = mCompassSensor->readSample(ldata, timestamp);
14449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    for(int i=0; i<3; i++) {
14549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        data[i] = (float)ldata[i];
14649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    }
14749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    return res;
14849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow}
14949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
15049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chowvoid CompassSensor::fillList(struct sensor_t *list)
15149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow{
15249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    VFUNC_LOG;
15349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
15449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    const char *compass = COMPASS_NAME;
15549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
15649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    if (compass) {
15749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        if (!strcmp(compass, "AKM8963")) {
15849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            list->maxRange = COMPASS_AKM8963_RANGE;
15949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            list->resolution = COMPASS_AKM8963_RESOLUTION;
16049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            list->power = COMPASS_AKM8963_POWER;
16149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            list->minDelay = COMPASS_AKM8963_MINDELAY;
16249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            return;
16349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        }
16449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        if (!strcmp(compass, "AKM8975")) {
16549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            list->maxRange = COMPASS_AKM8975_RANGE;
16649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            list->resolution = COMPASS_AKM8975_RESOLUTION;
16749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            list->power = COMPASS_AKM8975_POWER;
16849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            list->minDelay = COMPASS_AKM8975_MINDELAY;
16949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow            LOGW("HAL:support for AKM8975 is incomplete");
17049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow        }
17149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    }
17249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
17349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    LOGE("HAL:unsupported compass id %s -- "
17449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow         "this implementation only supports AKM compasses", compass);
17549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    list->maxRange = COMPASS_AKM8975_RANGE;
17649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    list->resolution = COMPASS_AKM8975_RESOLUTION;
17749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    list->power = COMPASS_AKM8975_POWER;
17849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    list->minDelay = COMPASS_AKM8975_MINDELAY;
17949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow}
18049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
18149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow// TODO: specify compass sensor's mounting matrix for MPL
18249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chowvoid CompassSensor::getOrientationMatrix(signed char *orient)
18349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow{
18449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    VFUNC_LOG;
18549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
18649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    orient[0] = 1;
18749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    orient[1] = 0;
18849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    orient[2] = 0;
18949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    orient[3] = 0;
19049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    orient[4] = 1;
19149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    orient[5] = 0;
19249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    orient[6] = 0;
19349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    orient[7] = 0;
19449ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    orient[8] = 1;
19549ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow}
19649ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
19749ea3e26ca3c6a779e527a0322e49a663333350aRosa Chowint CompassSensor::getAccuracy(void)
19849ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow{
19949ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    VFUNC_LOG;
20049ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow
20149ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    // TODO: need to implement "getAccuracy()" for MPL in 3rd-party's .cpp file
20249ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow    return mCompassSensor->getAccuracy();
20349ea3e26ca3c6a779e527a0322e49a663333350aRosa Chow}
204