/* * Copyright (C) 2014 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #define LOG_NDEBUG 0 #include <fcntl.h> #include <errno.h> #include <math.h> #include <unistd.h> #include <dirent.h> #include <sys/select.h> #include <cutils/log.h> #include <linux/input.h> #include <string.h> #include "PressureSensor.IIO.secondary.h" #include "sensors.h" #include "MPLSupport.h" #include "sensor_params.h" #include "ml_sysfs_helper.h" #pragma message("HAL:build pressure sensor on Invensense MPU secondary bus") /* dynamically get this when driver supports it */ #define CHIP_ID "BMP280" //#define TIMER (1) #define DEFAULT_POLL_TIME 300 #define PRESSURE_MAX_SYSFS_ATTRB sizeof(pressureSysFs) / sizeof(char*) static int s_poll_time = -1; static int min_poll_time = 50; static struct timespec t_pre; /*****************************************************************************/ PressureSensor::PressureSensor(const char *sysfs_path) : SensorBase(NULL, NULL), pressure_fd(-1) { VFUNC_LOG; mSysfsPath = sysfs_path; LOGV_IF(ENG_VERBOSE, "pressuresensor path: %s", mSysfsPath); if(inv_init_sysfs_attributes()) { LOGE("Error Instantiating Pressure Sensor\n"); return; } else { LOGI_IF(PROCESS_VERBOSE, "HAL:Secondary Chip Id: %s", CHIP_ID); } } PressureSensor::~PressureSensor() { VFUNC_LOG; if( pressure_fd > 0) close(pressure_fd); } int PressureSensor::getFd() const { VHANDLER_LOG; return pressure_fd; } /** * @brief This function will enable/disable sensor. * @param[in] handle * which sensor to enable/disable. * @param[in] en * en=1, enable; * en=0, disable * @return if the operation is successful. */ int PressureSensor::enable(int32_t handle, int en) { VFUNC_LOG; int res = 0; LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)", en, pressureSysFs.pressure_enable, getTimestamp()); res = write_sysfs_int(pressureSysFs.pressure_enable, en); return res; } int PressureSensor::setDelay(int32_t handle, int64_t ns) { VFUNC_LOG; int res = 0; mDelay = int(1000000000.f / ns); LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %lld > %s (%lld)", mDelay, pressureSysFs.pressure_rate, getTimestamp()); res = write_sysfs_int(pressureSysFs.pressure_rate, mDelay); #ifdef TIMER int t_poll_time = (int)(ns / 1000000LL); if (t_poll_time > min_poll_time) { s_poll_time = t_poll_time; } else { s_poll_time = min_poll_time; } LOGV_IF(PROCESS_VERBOSE, "HAL:setDelay : %llu ns, (%.2f Hz)", ns, 1000000000.f/ns); #endif return res; } /** @brief This function will return the state of the sensor. @return 1=enabled; 0=disabled **/ int PressureSensor::getEnable(int32_t handle) { VFUNC_LOG; return mEnable; } /** * @brief This function will return the current delay for this sensor. * @return delay in nanoseconds. */ int64_t PressureSensor::getDelay(int32_t handle) { VFUNC_LOG; #ifdef TIMER if (mEnable) { return s_poll_time; } else { return -1; } #endif return mDelay; } void PressureSensor::fillList(struct sensor_t *list) { VFUNC_LOG; const char *pressure = "BMP280"; if (pressure) { if(!strcmp(pressure, "BMP280")) { list->maxRange = PRESSURE_BMP280_RANGE; list->resolution = PRESSURE_BMP280_RESOLUTION; list->power = PRESSURE_BMP280_POWER; list->minDelay = PRESSURE_BMP280_MINDELAY; mMinDelay = list->minDelay; return; } } LOGE("HAL:unknown pressure id %s -- " "params default to bmp280 and might be wrong.", pressure); list->maxRange = PRESSURE_BMP280_RANGE; list->resolution = PRESSURE_BMP280_RESOLUTION; list->power = PRESSURE_BMP280_POWER; list->minDelay = PRESSURE_BMP280_MINDELAY; mMinDelay = list->minDelay; return; } int PressureSensor::inv_init_sysfs_attributes(void) { VFUNC_LOG; pathP = (char*)calloc(PRESSURE_MAX_SYSFS_ATTRB, sizeof(char[MAX_SYSFS_NAME_LEN])); if (pathP == NULL) return -1; char *sptr = pathP; char **dptr = reinterpret_cast<char **>(&pressureSysFs); for (size_t i = 0; i < PRESSURE_MAX_SYSFS_ATTRB; i++) { *dptr++ = sptr; sptr += sizeof(char[MAX_SYSFS_NAME_LEN]); } sprintf(pressureSysFs.pressure_enable, "%s%s", mSysfsPath, "/pressure_enable"); sprintf(pressureSysFs.pressure_rate, "%s%s", mSysfsPath, "/pressure_rate"); // Supported by driver ? FILE *sysfsfp; sysfsfp = fopen(pressureSysFs.pressure_rate, "r"); if (sysfsfp == NULL) { LOGE("HAL: HAL configured to support Pressure sensor but not by driver"); } else { fclose(sysfsfp); } return 0; }