Home | History | Annotate | Download | only in libsensors_iio
      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