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 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 65 PressureSensor::~PressureSensor() 66 { 67 VFUNC_LOG; 68 69 if( pressure_fd > 0) 70 close(pressure_fd); 71 } 72 73 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 */ 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 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 **/ 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 */ 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 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 181 int PressureSensor::inv_init_sysfs_attributes(void) 182 { 183 VFUNC_LOG; 184 185 pathP = (char*)malloc(sizeof(char[PRESSURE_MAX_SYSFS_ATTRB][MAX_SYSFS_NAME_LEN])); 186 char *sptr = pathP; 187 char **dptr = (char**)&pressureSysFs; 188 if (sptr == NULL) 189 return -1; 190 unsigned char i = 0; 191 do { 192 *dptr++ = sptr; 193 memset(sptr, 0, sizeof(sptr)); 194 sptr += sizeof(char[MAX_SYSFS_NAME_LEN]); 195 } while (++i < PRESSURE_MAX_SYSFS_ATTRB); 196 197 sprintf(pressureSysFs.pressure_enable, "%s%s", mSysfsPath, "/pressure_enable"); 198 sprintf(pressureSysFs.pressure_rate, "%s%s", mSysfsPath, "/pressure_rate"); 199 return 0; 200 } 201