1/*
2 * Copyright (C) 2012 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 <fcntl.h>
18#include <errno.h>
19#include <math.h>
20#include <poll.h>
21#include <unistd.h>
22#include <dirent.h>
23#include <sys/select.h>
24#include <cutils/log.h>
25#include <linux/input.h>
26
27#include "sensor_params.h"
28#include "MPLSupport.h"
29
30// TODO: include corresponding header file for 3rd party compass sensor
31#include "CompassSensor.AKM.h"
32
33// TODO: specify this for "fillList()" API
34#define COMPASS_NAME "AKM8963"
35
36/*****************************************************************************/
37
38CompassSensor::CompassSensor()
39                    : SensorBase(NULL, NULL)
40{
41    VFUNC_LOG;
42
43    // TODO: initiate 3rd-party's class, and disable its funtionalities
44    //       proper commands
45    mCompassSensor = new AkmSensor();
46    LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)",
47            0, "/sys/class/compass/akm8963/enable_mag", getTimestamp());
48    write_sysfs_int((char*)"/sys/class/compass/akm8963/enable_mag", 0);
49}
50
51CompassSensor::~CompassSensor()
52{
53    VFUNC_LOG;
54
55    // TODO: disable 3rd-party's funtionalities and delete the object
56    LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)",
57            0, "/sys/class/compass/akm8963/enable_mag", getTimestamp());
58    write_sysfs_int((char*)"/sys/class/compass/akm8963/enable_mag", 0);
59    delete mCompassSensor;
60}
61
62int CompassSensor::getFd(void) const
63{
64    VFUNC_LOG;
65
66    // TODO: return 3rd-party's file descriptor
67    return mCompassSensor->getFd();
68}
69
70/**
71 *  @brief        This function will enable/disable sensor.
72 *  @param[in]    handle    which sensor to enable/disable.
73 *  @param[in]    en        en=1 enable, en=0 disable
74 *  @return       if the operation is successful.
75 */
76int CompassSensor::enable(int32_t handle, int en)
77{
78    VFUNC_LOG;
79
80    // TODO: called 3rd-party's "set enable/disable" function
81    return mCompassSensor->setEnable(handle, en);
82}
83
84int CompassSensor::setDelay(int32_t handle, int64_t ns)
85{
86    VFUNC_LOG;
87
88    // TODO: called 3rd-party's "set delay" function
89    return mCompassSensor->setDelay(handle, ns);
90}
91
92/**
93    @brief      This function will return the state of the sensor.
94    @return     1=enabled; 0=disabled
95**/
96int CompassSensor::getEnable(int32_t handle)
97{
98    VFUNC_LOG;
99
100    // TODO: return if 3rd-party compass is enabled
101    return mCompassSensor->getEnable(handle);
102}
103
104/**
105    @brief      This function will return the current delay for this sensor.
106    @return     delay in nanoseconds.
107**/
108int64_t CompassSensor::getDelay(int32_t handle)
109{
110    VFUNC_LOG;
111
112    // TODO: return 3rd-party's delay time (should be in ns)
113    return mCompassSensor->getDelay(handle);
114}
115
116/**
117    @brief         Integrators need to implement this function per 3rd-party solution
118    @param[out]    data      sensor data is stored in this variable. Scaled such that
119                             1 uT = 2^16
120    @para[in]      timestamp data's timestamp
121    @return        1, if 1   sample read, 0, if not, negative if error
122**/
123int CompassSensor::readSample(long *data, int64_t *timestamp)
124{
125    VFUNC_LOG;
126
127    // TODO: need to implement "readSample()" for MPL in 3rd-party's .cpp file
128    return mCompassSensor->readSample(data, timestamp);
129}
130
131/**
132    @brief         Integrators need to implement this function per 3rd-party solution
133    @param[out]    data      sensor data is stored in this variable. Scaled such that
134                             1 uT = 2^16
135    @para[in]      timestamp data's timestamp
136    @return        1, if 1   sample read, 0, if not, negative if error
137**/
138int CompassSensor::readRawSample(float *data, int64_t *timestamp)
139{
140    VFUNC_LOG;
141    long ldata[3];
142
143    int res = mCompassSensor->readSample(ldata, timestamp);
144    for(int i=0; i<3; i++) {
145        data[i] = (float)ldata[i];
146    }
147    return res;
148}
149
150void CompassSensor::fillList(struct sensor_t *list)
151{
152    VFUNC_LOG;
153
154    const char *compass = COMPASS_NAME;
155
156    if (compass) {
157        if (!strcmp(compass, "AKM8963")) {
158            list->maxRange = COMPASS_AKM8963_RANGE;
159            list->resolution = COMPASS_AKM8963_RESOLUTION;
160            list->power = COMPASS_AKM8963_POWER;
161            list->minDelay = COMPASS_AKM8963_MINDELAY;
162            return;
163        }
164        if (!strcmp(compass, "AKM8975")) {
165            list->maxRange = COMPASS_AKM8975_RANGE;
166            list->resolution = COMPASS_AKM8975_RESOLUTION;
167            list->power = COMPASS_AKM8975_POWER;
168            list->minDelay = COMPASS_AKM8975_MINDELAY;
169            LOGW("HAL:support for AKM8975 is incomplete");
170        }
171    }
172
173    LOGE("HAL:unsupported compass id %s -- "
174         "this implementation only supports AKM compasses", compass);
175    list->maxRange = COMPASS_AKM8975_RANGE;
176    list->resolution = COMPASS_AKM8975_RESOLUTION;
177    list->power = COMPASS_AKM8975_POWER;
178    list->minDelay = COMPASS_AKM8975_MINDELAY;
179}
180
181// TODO: specify compass sensor's mounting matrix for MPL
182void CompassSensor::getOrientationMatrix(signed char *orient)
183{
184    VFUNC_LOG;
185
186    orient[0] = 1;
187    orient[1] = 0;
188    orient[2] = 0;
189    orient[3] = 0;
190    orient[4] = 1;
191    orient[5] = 0;
192    orient[6] = 0;
193    orient[7] = 0;
194    orient[8] = 1;
195}
196
197int CompassSensor::getAccuracy(void)
198{
199    VFUNC_LOG;
200
201    // TODO: need to implement "getAccuracy()" for MPL in 3rd-party's .cpp file
202    return mCompassSensor->getAccuracy();
203}
204