Home | History | Annotate | Download | only in libsensors_iio
      1 /*
      2 * Copyright (C) 2012 Invensense, Inc.
      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 <MPLSupport.h>
     20 #include <string.h>
     21 #include <stdio.h>
     22 #include <fcntl.h>
     23 
     24 #include "log.h"
     25 #include "SensorBase.h"
     26 
     27 #include "ml_sysfs_helper.h"
     28 #include "local_log_def.h"
     29 
     30 int64_t getTimestamp()
     31 {
     32     struct timespec t;
     33     t.tv_sec = t.tv_nsec = 0;
     34     clock_gettime(CLOCK_MONOTONIC, &t);
     35     return int64_t(t.tv_sec) * 1000000000LL + t.tv_nsec;
     36 }
     37 
     38 int64_t timevalToNano(timeval const& t) {
     39     return t.tv_sec * 1000000000LL + t.tv_usec * 1000;
     40 }
     41 
     42 int inv_read_data(char *fname, long *data)
     43 {
     44     VFUNC_LOG;
     45 
     46     char buf[sizeof(long) * 4];
     47     int count, fd;
     48 
     49     fd = open(fname, O_RDONLY);
     50     if(fd < 0) {
     51         LOGE("HAL:Error opening %s", fname);
     52         return -1;
     53     }
     54     memset(buf, 0, sizeof(buf));
     55     count = read_attribute_sensor(fd, buf, sizeof(buf));
     56     if(count < 1) {
     57         close(fd);
     58         return -1;
     59     } else {
     60         count = sscanf(buf, "%ld", data);
     61         if(count)
     62             LOGV_IF(EXTRA_VERBOSE, "HAL:Data= %ld", *data);
     63     }
     64     close(fd);
     65 
     66     return 0;
     67 }
     68 
     69 /* This one DOES NOT close FDs for you */
     70 int read_attribute_sensor(int fd, char* data, unsigned int size)
     71 {
     72     VFUNC_LOG;
     73 
     74     int count = 0;
     75     if (fd > 0) {
     76         count = pread(fd, data, size, 0);
     77         if(count < 1) {
     78             LOGE("HAL:read fails with error code=%d", count);
     79         }
     80     }
     81     return count;
     82 }
     83 
     84 /**
     85  *  @brief  Enable a sensor through the sysfs file descriptor
     86  *          provided.
     87  *  @note   this function one closes FD after the write
     88  *  @param  fd
     89  *              the file descriptor to write into
     90  *  @param  en
     91  *              the value to write, typically 1 or 0
     92  *  @return the errno whenever applicable.
     93  */
     94 int enable_sysfs_sensor(int fd, int en)
     95 {
     96     VFUNC_LOG;
     97 
     98     int nb;
     99     int err = 0;
    100 
    101     char c = en ? '1' : '0';
    102     nb = write(fd, &c, 1);
    103 
    104     if (nb <= 0) {
    105         err = errno;
    106         LOGE("HAL:enable_sysfs_sensor - write %c returned %d (%s / %d)",
    107              c, nb, strerror(err), err);
    108     }
    109     close(fd);
    110 
    111 
    112     return err;
    113 }
    114 
    115 /* This one closes FDs for you */
    116 int write_attribute_sensor(int fd, long data)
    117 {
    118     VFUNC_LOG;
    119 
    120     int num_b = 0;
    121 
    122     if (fd >= 0) {
    123         char buf[80];
    124         sprintf(buf, "%ld", data);
    125         num_b = write(fd, buf, strlen(buf) + 1);
    126         if (num_b <= 0) {
    127             int err = errno;
    128             LOGE("HAL:write fd %d returned '%s' (%d)", fd, strerror(err), err);
    129         } else {
    130             LOGV_IF(EXTRA_VERBOSE, "HAL:fd=%d write attribute to %ld", fd, data);
    131         }
    132         close(fd);
    133     }
    134 
    135     return num_b;
    136 }
    137 
    138 int read_sysfs_int(char *filename, int *var)
    139 {
    140     int res=0;
    141     FILE  *sysfsfp;
    142 
    143     sysfsfp = fopen(filename, "r");
    144     if (sysfsfp != NULL) {
    145         if (fscanf(sysfsfp, "%d\n", var) < 1) {
    146            LOGE("HAL:ERR failed to read an int from %s.", filename);
    147            res = -EINVAL;
    148         }
    149         fclose(sysfsfp);
    150     } else {
    151         res = -errno;
    152         LOGE("HAL:ERR open file %s to read with error %d", filename, res);
    153     }
    154     return res;
    155 }
    156 
    157 int write_sysfs_int(char *filename, int var)
    158 {
    159     int res = 0;
    160     FILE  *sysfsfp;
    161 
    162     LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)",
    163             var, filename, getTimestamp());
    164     sysfsfp = fopen(filename, "w");
    165     if (sysfsfp == NULL) {
    166         res = -errno;
    167         LOGE("HAL:ERR open file %s to write with error %d", filename, res);
    168         return res;
    169     }
    170     int fpres, fcres = 0;
    171     fpres = fprintf(sysfsfp, "%d\n", var);
    172     /* fprintf() can succeed because it never actually writes to the
    173      * underlying sysfs node.
    174      */
    175     if (fpres < 0) {
    176        res = -errno;
    177        fclose(sysfsfp);
    178     } else {
    179         fcres = fclose(sysfsfp);
    180         /* Check for errors from: fflush(), write(), and close() */
    181         if (fcres < 0) {
    182             res = -errno;
    183         }
    184     }
    185     if (fpres < 0 || fcres < 0) {
    186         LOGE("HAL:ERR failed to write %d to %s (err=%d) print/close=%d/%d",
    187             var, filename, res, fpres, fcres);
    188     }
    189     return res;
    190 }
    191