| /* |
| * 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; |
| } |