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 //#define TIMER (1)
40 #define DEFAULT_POLL_TIME 300
41 #define PRESSURE_MAX_SYSFS_ATTRB sizeof(pressureSysFs) / sizeof(char*)
42
43 #ifdef TIMER
44 static int s_poll_time = -1;
45 static int min_poll_time = 50;
46 #endif
47
48 /*****************************************************************************/
49
PressureSensor(const char * sysfs_path)50 PressureSensor::PressureSensor(const char *sysfs_path)
51 : SensorBase(NULL, NULL),
52 pressure_fd(-1)
53 {
54 VFUNC_LOG;
55
56 mSysfsPath = sysfs_path;
57 LOGV_IF(ENG_VERBOSE, "pressuresensor path: %s", mSysfsPath);
58 if(inv_init_sysfs_attributes()) {
59 LOGE("Error Instantiating Pressure Sensor\n");
60 return;
61 } else {
62 LOGI_IF(PROCESS_VERBOSE, "HAL:Secondary Chip Id: %s", CHIP_ID);
63 }
64 }
65
~PressureSensor()66 PressureSensor::~PressureSensor()
67 {
68 VFUNC_LOG;
69
70 if( pressure_fd > 0)
71 close(pressure_fd);
72 }
73
getFd() const74 int PressureSensor::getFd() const
75 {
76 VHANDLER_LOG;
77 return pressure_fd;
78 }
79
80 /**
81 * @brief This function will enable/disable sensor.
82 * @param[in] handle
83 * which sensor to enable/disable.
84 * @param[in] en
85 * en=1, enable;
86 * en=0, disable
87 * @return if the operation is successful.
88 */
enable(int32_t handle,int en)89 int PressureSensor::enable(int32_t handle, int en)
90 {
91 VFUNC_LOG;
92
93 int res = 0;
94
95 LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)",
96 en, pressureSysFs.pressure_enable, getTimestamp());
97 res = write_sysfs_int(pressureSysFs.pressure_enable, en);
98
99 return res;
100 }
101
setDelay(int32_t handle,int64_t ns)102 int PressureSensor::setDelay(int32_t handle, int64_t ns)
103 {
104 VFUNC_LOG;
105
106 int res = 0;
107
108 mDelay = int(1000000000.f / ns);
109 LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %lld > %s (%lld)",
110 mDelay, pressureSysFs.pressure_rate, getTimestamp());
111 res = write_sysfs_int(pressureSysFs.pressure_rate, mDelay);
112
113 #ifdef TIMER
114 int t_poll_time = (int)(ns / 1000000LL);
115 if (t_poll_time > min_poll_time) {
116 s_poll_time = t_poll_time;
117 } else {
118 s_poll_time = min_poll_time;
119 }
120 LOGV_IF(PROCESS_VERBOSE,
121 "HAL:setDelay : %llu ns, (%.2f Hz)", ns, 1000000000.f/ns);
122 #endif
123 return res;
124 }
125
126
127 /**
128 @brief This function will return the state of the sensor.
129 @return 1=enabled; 0=disabled
130 **/
getEnable(int32_t handle)131 int PressureSensor::getEnable(int32_t handle)
132 {
133 VFUNC_LOG;
134 return mEnable;
135 }
136
137 /**
138 * @brief This function will return the current delay for this sensor.
139 * @return delay in nanoseconds.
140 */
getDelay(int32_t handle)141 int64_t PressureSensor::getDelay(int32_t handle)
142 {
143 VFUNC_LOG;
144
145 #ifdef TIMER
146 if (mEnable) {
147 return s_poll_time;
148 } else {
149 return -1;
150 }
151 #endif
152 return mDelay;
153 }
154
fillList(struct sensor_t * list)155 void PressureSensor::fillList(struct sensor_t *list)
156 {
157 VFUNC_LOG;
158
159 const char *pressure = "BMP280";
160
161 if (pressure) {
162 if(!strcmp(pressure, "BMP280")) {
163 list->maxRange = PRESSURE_BMP280_RANGE;
164 list->resolution = PRESSURE_BMP280_RESOLUTION;
165 list->power = PRESSURE_BMP280_POWER;
166 list->minDelay = PRESSURE_BMP280_MINDELAY;
167 mMinDelay = list->minDelay;
168 return;
169 }
170 }
171 LOGE("HAL:unknown pressure id %s -- "
172 "params default to bmp280 and might be wrong.",
173 pressure);
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 mMinDelay = list->minDelay;
179 return;
180 }
181
inv_init_sysfs_attributes(void)182 int PressureSensor::inv_init_sysfs_attributes(void)
183 {
184 VFUNC_LOG;
185
186 pathP = (char*)calloc(PRESSURE_MAX_SYSFS_ATTRB,
187 sizeof(char[MAX_SYSFS_NAME_LEN]));
188 if (pathP == NULL)
189 return -1;
190
191 if (mSysfsPath == NULL)
192 return 0;
193
194 char *sptr = pathP;
195 char **dptr = reinterpret_cast<char **>(&pressureSysFs);
196 for (size_t i = 0; i < PRESSURE_MAX_SYSFS_ATTRB; i++) {
197 *dptr++ = sptr;
198 sptr += sizeof(char[MAX_SYSFS_NAME_LEN]);
199 }
200
201 sprintf(pressureSysFs.pressure_enable, "%s%s", mSysfsPath, "/pressure_enable");
202 sprintf(pressureSysFs.pressure_rate, "%s%s", mSysfsPath, "/pressure_rate");
203
204 return 0;
205 }
206