• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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