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 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 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 77 PressureSensor::~PressureSensor() 78 { 79 VFUNC_LOG; 80 81 if( pressure_fd > 0) 82 close(pressure_fd); 83 } 84 85 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 */ 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 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 **/ 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 */ 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 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 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