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 /* return the current time in nanoseconds */
     40 extern int64_t now_ns(void);
     41 
     42 inline int64_t now_ns(void)
     43 {
     44     struct timespec ts;
     45 
     46     clock_gettime(CLOCK_MONOTONIC, &ts);
     47     LOGV_IF(EXTRA_VERBOSE, "Time %lld", (int64_t)ts.tv_sec * 1000000000 + ts.tv_nsec);
     48     return (int64_t) ts.tv_sec * 1000000000 + ts.tv_nsec;
     49 }
     50 
     51 //#define TIMER (1)
     52 #define DEFAULT_POLL_TIME 300
     53 #define PRESSURE_MAX_SYSFS_ATTRB sizeof(pressureSysFs) / sizeof(char*)
     54 
     55 static int s_poll_time = -1;
     56 static int min_poll_time = 50;
     57 static struct timespec t_pre;
     58 
     59 /*****************************************************************************/
     60 
     61 PressureSensor::PressureSensor(const char *sysfs_path)
     62                   : SensorBase(NULL, NULL),
     63                     pressure_fd(-1)
     64 {
     65     VFUNC_LOG;
     66 
     67     mSysfsPath = sysfs_path;
     68     LOGI("pressuresensor path: %s", mSysfsPath);
     69     if(inv_init_sysfs_attributes()) {
     70         LOGE("Error Instantiating Pressure Sensor\n");
     71         return;
     72     } else {
     73         LOGI("HAL:Secondary Chip Id: %s", CHIP_ID);
     74     }
     75 }
     76 
     77 PressureSensor::~PressureSensor()
     78 {
     79     VFUNC_LOG;
     80 
     81     if( pressure_fd > 0)
     82         close(pressure_fd);
     83 }
     84 
     85 int PressureSensor::getFd() const
     86 {
     87     VHANDLER_LOG;
     88     return pressure_fd;
     89 }
     90 
     91 /**
     92  *  @brief        This function will enable/disable sensor.
     93  *  @param[in]    handle
     94  *                  which sensor to enable/disable.
     95  *  @param[in]    en
     96  *                  en=1, enable;
     97  *                  en=0, disable
     98  *  @return       if the operation is successful.
     99  */
    100 int PressureSensor::enable(int32_t handle, int en)
    101 {
    102     VFUNC_LOG;
    103 
    104     int res = 0;
    105 
    106     LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs: echo %d > %s (%lld)",
    107             en, pressureSysFs.pressure_enable, getTimestamp());
    108     res = write_sysfs_int(pressureSysFs.pressure_enable, en);
    109 
    110     return res;
    111 }
    112 
    113 int PressureSensor::setDelay(int32_t handle, int64_t ns)
    114 {
    115     VFUNC_LOG;
    116 
    117     int res = 0;
    118 
    119     mDelay = int(1000000000.f / ns);
    120     LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs: echo %lld > %s (%lld)",
    121             mDelay, pressureSysFs.pressure_rate, getTimestamp());
    122     res = write_sysfs_int(pressureSysFs.pressure_rate, mDelay);
    123 
    124 #ifdef TIMER
    125     int t_poll_time = (int)(ns / 1000000LL);
    126     if (t_poll_time > min_poll_time) {
    127         s_poll_time = t_poll_time;
    128     } else {
    129         s_poll_time = min_poll_time;
    130     }
    131     LOGV_IF(PROCESS_VERBOSE,
    132             "HAL:setDelay : %llu ns, (%.2f Hz)", ns, 1000000000.f/ns);
    133 #endif
    134     return res;
    135 }
    136 
    137 
    138 /**
    139     @brief      This function will return the state of the sensor.
    140     @return     1=enabled; 0=disabled
    141 **/
    142 int PressureSensor::getEnable(int32_t handle)
    143 {
    144     VFUNC_LOG;
    145     return mEnable;
    146 }
    147 
    148 /**
    149  *  @brief  This function will return the current delay for this sensor.
    150  *  @return delay in nanoseconds.
    151  */
    152 int64_t PressureSensor::getDelay(int32_t handle)
    153 {
    154     VFUNC_LOG;
    155 
    156 #ifdef TIMER
    157     if (mEnable) {
    158         return s_poll_time;
    159     } else {
    160         return -1;
    161     }
    162 #endif
    163     return mDelay;
    164 }
    165 
    166 void PressureSensor::fillList(struct sensor_t *list)
    167 {
    168     VFUNC_LOG;
    169 
    170     const char *pressure = "BMP280";
    171 
    172     if (pressure) {
    173         if(!strcmp(pressure, "BMP280")) {
    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             return;
    179         }
    180     }
    181     LOGE("HAL:unknown pressure id %s -- "
    182          "params default to bmp280 and might be wrong.",
    183          pressure);
    184     list->maxRange = PRESSURE_BMP280_RANGE;
    185     list->resolution = PRESSURE_BMP280_RESOLUTION;
    186     list->power = PRESSURE_BMP280_POWER;
    187     list->minDelay = PRESSURE_BMP280_MINDELAY;
    188 }
    189 
    190 int PressureSensor::inv_init_sysfs_attributes(void)
    191 {
    192     VFUNC_LOG;
    193 
    194     pathP = (char*)malloc(sizeof(char[PRESSURE_MAX_SYSFS_ATTRB][MAX_SYSFS_NAME_LEN]));
    195     char *sptr = pathP;
    196     char **dptr = (char**)&pressureSysFs;
    197     if (sptr == NULL)
    198         return -1;
    199     unsigned char i = 0;
    200     do {
    201         *dptr++ = sptr;
    202         memset(sptr, 0, sizeof(sptr));
    203         sptr += sizeof(char[MAX_SYSFS_NAME_LEN]);
    204     } while (++i < PRESSURE_MAX_SYSFS_ATTRB);
    205 
    206 
    207     if (mSysfsPath == NULL)
    208         return 0;
    209 
    210     sprintf(pressureSysFs.pressure_enable, "%s%s", mSysfsPath, "/pressure_enable");
    211     sprintf(pressureSysFs.pressure_rate, "%s%s", mSysfsPath, "/pressure_rate");
    212     return 0;
    213 }
    214