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