Home | History | Annotate | Download | only in libsensors_iio
      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 
     43 static int s_poll_time = -1;
     44 static int min_poll_time = 50;
     45 static struct timespec t_pre;
     46 
     47 /*****************************************************************************/
     48 
     49 PressureSensor::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 
     65 PressureSensor::~PressureSensor()
     66 {
     67     VFUNC_LOG;
     68 
     69     if( pressure_fd > 0)
     70         close(pressure_fd);
     71 }
     72 
     73 int 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  */
     88 int 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 
    101 int 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 **/
    130 int 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  */
    140 int64_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 
    154 void 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 
    181 int PressureSensor::inv_init_sysfs_attributes(void)
    182 {
    183     VFUNC_LOG;
    184 
    185     pathP = (char*)calloc(PRESSURE_MAX_SYSFS_ATTRB,
    186                           sizeof(char[MAX_SYSFS_NAME_LEN]));
    187     if (pathP == NULL)
    188         return -1;
    189 
    190     char *sptr = pathP;
    191     char **dptr = reinterpret_cast<char **>(&pressureSysFs);
    192     for (size_t i = 0; i < PRESSURE_MAX_SYSFS_ATTRB; i++) {
    193       *dptr++ = sptr;
    194       sptr += sizeof(char[MAX_SYSFS_NAME_LEN]);
    195     }
    196 
    197     sprintf(pressureSysFs.pressure_enable, "%s%s", mSysfsPath, "/pressure_enable");
    198     sprintf(pressureSysFs.pressure_rate, "%s%s", mSysfsPath, "/pressure_rate");
    199 
    200     // Supported by driver ?
    201     FILE  *sysfsfp;
    202     sysfsfp = fopen(pressureSysFs.pressure_rate, "r");
    203     if (sysfsfp == NULL) {
    204         LOGE("HAL: HAL configured to support Pressure sensor but not by driver");
    205     } else {
    206         fclose(sysfsfp);
    207     }
    208     return 0;
    209 }
    210