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 43static int s_poll_time = -1; 44static int min_poll_time = 50; 45static struct timespec t_pre; 46 47/*****************************************************************************/ 48 49PressureSensor::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 65PressureSensor::~PressureSensor() 66{ 67 VFUNC_LOG; 68 69 if( pressure_fd > 0) 70 close(pressure_fd); 71} 72 73int 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 */ 88int 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 101int 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**/ 130int 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 */ 140int64_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 154void 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 181int 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