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 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 66 PressureSensor::~PressureSensor() 67 { 68 VFUNC_LOG; 69 70 if( pressure_fd > 0) 71 close(pressure_fd); 72 } 73 74 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 */ 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 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 **/ 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 */ 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 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 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