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 #define LOG_NDEBUG 0
18
19 #include <fcntl.h>
20 #include <errno.h>
21 #include <math.h>
22 #include <unistd.h>
23 #include <dirent.h>
24 #include <sys/select.h>
25 #include <cutils/log.h>
26 #include <linux/input.h>
27 #include <string.h>
28
29 #include "PressureSensor.IIO.secondary.h"
30 #include "sensors.h"
31 #include "MPLSupport.h"
32 #include "sensor_params.h"
33 #include "ml_sysfs_helper.h"
34
35 #pragma message("HAL:build pressure sensor on Invensense MPU secondary bus")
36 /* dynamically get this when driver supports it */
37 #define CHIP_ID "BMP280"
38
39 /* return the current time in nanoseconds */
40 extern int64_t now_ns(void);
41
now_ns(void)42 inline int64_t now_ns(void)
43 {
44 struct timespec ts;
45
46 clock_gettime(CLOCK_MONOTONIC, &ts);
47 LOGV_IF(EXTRA_VERBOSE, "Time %lld", (int64_t)ts.tv_sec * 1000000000 + ts.tv_nsec);
48 return (int64_t) ts.tv_sec * 1000000000 + ts.tv_nsec;
49 }
50
51 //#define TIMER (1)
52 #define DEFAULT_POLL_TIME 300
53 #define PRESSURE_MAX_SYSFS_ATTRB sizeof(pressureSysFs) / sizeof(char*)
54
55 static int s_poll_time = -1;
56 static int min_poll_time = 50;
57 static struct timespec t_pre;
58
59 /*****************************************************************************/
60
PressureSensor(const char * sysfs_path)61 PressureSensor::PressureSensor(const char *sysfs_path)
62 : SensorBase(NULL, NULL),
63 pressure_fd(-1)
64 {
65 VFUNC_LOG;
66
67 mSysfsPath = sysfs_path;
68 LOGI("pressuresensor path: %s", mSysfsPath);
69 if(inv_init_sysfs_attributes()) {
70 LOGE("Error Instantiating Pressure Sensor\n");
71 return;
72 } else {
73 LOGI("HAL:Secondary Chip Id: %s", CHIP_ID);
74 }
75 }
76
~PressureSensor()77 PressureSensor::~PressureSensor()
78 {
79 VFUNC_LOG;
80
81 if( pressure_fd > 0)
82 close(pressure_fd);
83 }
84
getFd() const85 int PressureSensor::getFd() const
86 {
87 VHANDLER_LOG;
88 return pressure_fd;
89 }
90
91 /**
92 * @brief This function will enable/disable sensor.
93 * @param[in] handle
94 * which sensor to enable/disable.
95 * @param[in] en
96 * en=1, enable;
97 * en=0, disable
98 * @return if the operation is successful.
99 */
enable(int32_t handle,int en)100 int PressureSensor::enable(int32_t handle, int en)
101 {
102 VFUNC_LOG;
103
104 int res = 0;
105
106 LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs: echo %d > %s (%lld)",
107 en, pressureSysFs.pressure_enable, getTimestamp());
108 res = write_sysfs_int(pressureSysFs.pressure_enable, en);
109
110 return res;
111 }
112
setDelay(int32_t handle,int64_t ns)113 int PressureSensor::setDelay(int32_t handle, int64_t ns)
114 {
115 VFUNC_LOG;
116
117 int res = 0;
118
119 mDelay = int(1000000000.f / ns);
120 LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs: echo %lld > %s (%lld)",
121 mDelay, pressureSysFs.pressure_rate, getTimestamp());
122 res = write_sysfs_int(pressureSysFs.pressure_rate, mDelay);
123
124 #ifdef TIMER
125 int t_poll_time = (int)(ns / 1000000LL);
126 if (t_poll_time > min_poll_time) {
127 s_poll_time = t_poll_time;
128 } else {
129 s_poll_time = min_poll_time;
130 }
131 LOGV_IF(PROCESS_VERBOSE,
132 "HAL:setDelay : %llu ns, (%.2f Hz)", ns, 1000000000.f/ns);
133 #endif
134 return res;
135 }
136
137
138 /**
139 @brief This function will return the state of the sensor.
140 @return 1=enabled; 0=disabled
141 **/
getEnable(int32_t handle)142 int PressureSensor::getEnable(int32_t handle)
143 {
144 VFUNC_LOG;
145 return mEnable;
146 }
147
148 /**
149 * @brief This function will return the current delay for this sensor.
150 * @return delay in nanoseconds.
151 */
getDelay(int32_t handle)152 int64_t PressureSensor::getDelay(int32_t handle)
153 {
154 VFUNC_LOG;
155
156 #ifdef TIMER
157 if (mEnable) {
158 return s_poll_time;
159 } else {
160 return -1;
161 }
162 #endif
163 return mDelay;
164 }
165
fillList(struct sensor_t * list)166 void PressureSensor::fillList(struct sensor_t *list)
167 {
168 VFUNC_LOG;
169
170 const char *pressure = "BMP280";
171
172 if (pressure) {
173 if(!strcmp(pressure, "BMP280")) {
174 list->maxRange = PRESSURE_BMP280_RANGE;
175 list->resolution = PRESSURE_BMP280_RESOLUTION;
176 list->power = PRESSURE_BMP280_POWER;
177 list->minDelay = PRESSURE_BMP280_MINDELAY;
178 return;
179 }
180 }
181 LOGE("HAL:unknown pressure id %s -- "
182 "params default to bmp280 and might be wrong.",
183 pressure);
184 list->maxRange = PRESSURE_BMP280_RANGE;
185 list->resolution = PRESSURE_BMP280_RESOLUTION;
186 list->power = PRESSURE_BMP280_POWER;
187 list->minDelay = PRESSURE_BMP280_MINDELAY;
188 }
189
inv_init_sysfs_attributes(void)190 int PressureSensor::inv_init_sysfs_attributes(void)
191 {
192 VFUNC_LOG;
193
194 pathP = (char*)malloc(sizeof(char[PRESSURE_MAX_SYSFS_ATTRB][MAX_SYSFS_NAME_LEN]));
195 char *sptr = pathP;
196 char **dptr = (char**)&pressureSysFs;
197 if (sptr == NULL)
198 return -1;
199 unsigned char i = 0;
200 do {
201 *dptr++ = sptr;
202 memset(sptr, 0, sizeof(sptr));
203 sptr += sizeof(char[MAX_SYSFS_NAME_LEN]);
204 } while (++i < PRESSURE_MAX_SYSFS_ATTRB);
205
206
207 if (mSysfsPath == NULL)
208 return 0;
209
210 sprintf(pressureSysFs.pressure_enable, "%s%s", mSysfsPath, "/pressure_enable");
211 sprintf(pressureSysFs.pressure_rate, "%s%s", mSysfsPath, "/pressure_rate");
212 return 0;
213 }
214