1 /*
2  * Copyright (C) 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 <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 
CompassSensor()38 CompassSensor::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 
~CompassSensor()51 CompassSensor::~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 
getFd(void) const62 int 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  */
enable(int32_t handle,int en)76 int 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 
setDelay(int32_t handle,int64_t ns)84 int 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 **/
getEnable(int32_t handle)96 int 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 **/
getDelay(int32_t handle)108 int64_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 **/
readSample(long * data,int64_t * timestamp)123 int 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 **/
readRawSample(float * data,int64_t * timestamp)138 int 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 
fillList(struct sensor_t * list)150 void 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
getOrientationMatrix(signed char * orient)182 void 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 
getAccuracy(void)197 int 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