Home | History | Annotate | Download | only in libsensors_iio
      1 /*
      2 * Copyright (C) 2014 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 #include <MPLSupport.h>
     18 #include <dirent.h>
     19 #include <string.h>
     20 #include <stdio.h>
     21 #include "log.h"
     22 #include "SensorBase.h"
     23 #include <fcntl.h>
     24 
     25 #include "ml_sysfs_helper.h"
     26 #include "ml_load_dmp.h"
     27 
     28 int inv_read_data(char *fname, long *data)
     29 {
     30     VFUNC_LOG;
     31 
     32     char buf[sizeof(long) * 4];
     33     int count, fd;
     34 
     35     fd = open(fname, O_RDONLY);
     36     if(fd < 0) {
     37         LOGE("HAL:Error opening %s", fname);
     38         return -1;
     39     }
     40     memset(buf, 0, sizeof(buf));
     41     count = read_attribute_sensor(fd, buf, sizeof(buf));
     42     if(count < 1) {
     43         close(fd);
     44         return -1;
     45     } else {
     46         count = sscanf(buf, "%ld", data);
     47         if(count)
     48             LOGV_IF(EXTRA_VERBOSE, "HAL:Data= %ld", *data);
     49     }
     50     close(fd);
     51 
     52     return 0;
     53 }
     54 
     55 /* This one DOES NOT close FDs for you */
     56 int read_attribute_sensor(int fd, char* data, unsigned int size)
     57 {
     58     VFUNC_LOG;
     59 
     60     int count = 0;
     61     if (fd > 0) {
     62         count = pread(fd, data, size, 0);
     63         if(count < 1) {
     64             LOGE("HAL:read fails with error code=%d", count);
     65         }
     66     }
     67     return count;
     68 }
     69 
     70 /**
     71  *  @brief  Enable a sensor through the sysfs file descriptor
     72  *          provided.
     73  *  @note   this function one closes FD after the write
     74  *  @param  fd
     75  *              the file descriptor to write into
     76  *  @param  en
     77  *              the value to write, typically 1 or 0
     78  *  @return the errno whenever applicable.
     79  */
     80 int enable_sysfs_sensor(int fd, int en)
     81 {
     82     VFUNC_LOG;
     83 
     84     int nb;
     85     int err = 0;
     86 
     87     char c = en ? '1' : '0';
     88     nb = write(fd, &c, 1);
     89 
     90     if (nb <= 0) {
     91         err = errno;
     92         LOGE("HAL:enable_sysfs_sensor - write %c returned %d (%s / %d)",
     93              c, nb, strerror(err), err);
     94     }
     95     close(fd);
     96 
     97 
     98     return -err;
     99 }
    100 
    101 /* This one closes FDs for you */
    102 int write_attribute_sensor(int fd, long data)
    103 {
    104     VFUNC_LOG;
    105 
    106     int num_b = 0;
    107 
    108     if (fd >= 0) {
    109         char buf[80];
    110         sprintf(buf, "%ld", data);
    111         num_b = write(fd, buf, strlen(buf) + 1);
    112         if (num_b <= 0) {
    113             int err = errno;
    114             LOGE("HAL:write fd %d returned '%s' (%d)", fd, strerror(err), err);
    115         } else {
    116             LOGV_IF(EXTRA_VERBOSE, "HAL:fd=%d write attribute to %ld", fd, data);
    117         }
    118         close(fd);
    119     }
    120 
    121     return num_b;
    122 }
    123 
    124 /* This one DOES NOT close FDs for you */
    125 int write_attribute_sensor_continuous(int fd, long data)
    126 {
    127     VFUNC_LOG;
    128 
    129     int num_b = 0;
    130 
    131     if (fd >= 0) {
    132         char buf[80];
    133         sprintf(buf, "%ld", data);
    134         num_b = write(fd, buf, strlen(buf) + 1);
    135         if (num_b <= 0) {
    136             int err = errno;
    137             LOGE("HAL:write fd %d returned '%s' (%d)", fd, strerror(err), err);
    138         } else {
    139             LOGV_IF(EXTRA_VERBOSE, "HAL:fd=%d write attribute to %ld", fd, data);
    140         }
    141     }
    142 
    143     return num_b;
    144 }
    145 
    146 int read_sysfs_int(char *filename, int *var)
    147 {
    148     int res=0;
    149     FILE  *sysfsfp;
    150 
    151     sysfsfp = fopen(filename, "r");
    152     if (sysfsfp != NULL) {
    153         if (fscanf(sysfsfp, "%d\n", var) < 0 || fclose(sysfsfp) < 0) {
    154             res = errno;
    155             LOGE("HAL:ERR open file %s to read with error %d", filename, res);
    156         }
    157     }
    158     return -res;
    159 }
    160 
    161 int read_sysfs_int64(char *filename, int64_t *var)
    162 {
    163     int res=0;
    164     FILE  *sysfsfp;
    165 
    166     sysfsfp = fopen(filename, "r");
    167     if (sysfsfp != NULL) {
    168         if (fscanf(sysfsfp, "%lld\n", var) < 0 || fclose(sysfsfp) < 0) {
    169             res = errno;
    170             LOGE("HAL:ERR open file %s to read with error %d", filename, res);
    171         }
    172     }
    173     return -res;
    174 }
    175 
    176 void convert_long_to_hex_char(long* quat, unsigned char* hex, int numElement)
    177 {
    178     int bytePosition = 0;
    179     for (int index = 0; index < numElement; index++) {
    180         for (int i = 0; i < 4; i++) {
    181             hex[bytePosition] = (int) ((quat[index] >> (4-1-i) * 8) & 0xFF);
    182             //LOGI("e%d quat[%d]: %x", index, bytePosition, hex[bytePosition]);
    183             bytePosition++;
    184         }
    185     }
    186     return;
    187 }
    188 
    189 int write_sysfs_int(char *filename, int var)
    190 {
    191     int res=0;
    192     FILE  *sysfsfp;
    193 
    194     sysfsfp = fopen(filename, "w");
    195     if (sysfsfp != NULL) {
    196         if (fprintf(sysfsfp, "%d\n", var) < 0 || fclose(sysfsfp) < 0) {
    197             res = errno;
    198             LOGE("HAL:ERR open file %s to write with error %d", filename, res);
    199         }
    200     }
    201     return -res;
    202 }
    203 
    204 int write_sysfs_longlong(char *filename, int64_t var)
    205 {
    206     int res=0;
    207     FILE  *sysfsfp;
    208 
    209     sysfsfp = fopen(filename, "w");
    210     if (sysfsfp != NULL) {
    211         if (fprintf(sysfsfp, "%lld\n", var) < 0 || fclose(sysfsfp) < 0) {
    212             res = errno;
    213             LOGE("HAL:ERR open file %s to write with error %d", filename, res);
    214         }
    215     }
    216     return -res;
    217 }
    218 
    219 int fill_dev_full_name_by_prefix(const char* dev_prefix,
    220                                  char *dev_full_name, int len)
    221 {
    222     char cand_name[20];
    223     int prefix_len = strlen(dev_prefix);
    224     strncpy(cand_name, dev_prefix, sizeof(cand_name) / sizeof(cand_name[0]));
    225 
    226     // try adding a number, 0-9
    227     for(int cand_postfix = 0; cand_postfix < 10; cand_postfix++) {
    228         snprintf(&cand_name[prefix_len],
    229                  sizeof(cand_name) / sizeof(cand_name[0]),
    230                  "%d", cand_postfix);
    231         int dev_num = find_type_by_name(cand_name, "iio:device");
    232         if (dev_num != -ENODEV) {
    233             strncpy(dev_full_name, cand_name, len);
    234             return 0;
    235         }
    236     }
    237     // try adding a small letter, a-z
    238     for(char cand_postfix = 'a'; cand_postfix <= 'z'; cand_postfix++) {
    239         snprintf(&cand_name[prefix_len],
    240                  sizeof(cand_name) / sizeof(cand_name[0]),
    241                  "%c", cand_postfix);
    242         int dev_num = find_type_by_name(cand_name, "iio:device");
    243         if (dev_num != -ENODEV) {
    244             strncpy(dev_full_name, cand_name, len);
    245             return 0;
    246         }
    247     }
    248     // try adding a capital letter, A-Z
    249     for(char cand_postfix = 'A'; cand_postfix <= 'Z'; cand_postfix++) {
    250         snprintf(&cand_name[prefix_len],
    251                  sizeof(cand_name) / sizeof(cand_name[0]),
    252                  "%c", cand_postfix);
    253         int dev_num = find_type_by_name(cand_name, "iio:device");
    254         if (dev_num != -ENODEV) {
    255             strncpy(dev_full_name, cand_name, len);
    256             return 0;
    257         }
    258     }
    259     return 1;
    260 }
    261 
    262 void dump_dmp_img(const char *outFile)
    263 {
    264     FILE *fp;
    265     int i;
    266 
    267     char sysfs_path[MAX_SYSFS_NAME_LEN];
    268     char dmp_path[MAX_SYSFS_NAME_LEN];
    269 
    270     inv_get_sysfs_path(sysfs_path);
    271     sprintf(dmp_path, "%s%s", sysfs_path, "/dmp_firmware");
    272 
    273     LOGI("HAL DEBUG:dump DMP image");
    274     LOGI("HAL DEBUG:open %s\n", dmp_path);
    275     LOGI("HAL DEBUG:write to %s", outFile);
    276 
    277     read_dmp_img(dmp_path, (char *)outFile);
    278 }
    279 
    280 int read_sysfs_dir(bool fileMode, char *sysfs_path)
    281 {
    282     VFUNC_LOG;
    283 
    284     int res = 0;
    285     char full_path[MAX_SYSFS_NAME_LEN];
    286     int fd;
    287     char buf[sizeof(long) *4];
    288     long data;
    289 
    290     DIR *dp;
    291     struct dirent *ep;
    292 
    293     dp = opendir (sysfs_path);
    294 
    295     if (dp != NULL)
    296     {
    297         LOGI("******************** System Sysfs Dump ***************************");
    298         LOGV_IF(0,"HAL DEBUG: opened directory %s", sysfs_path);
    299         while ((ep = readdir (dp))) {
    300             if(ep != NULL) {
    301                 LOGV_IF(0,"file name %s", ep->d_name);
    302                 if(!strcmp(ep->d_name, ".") || !strcmp(ep->d_name, "..") ||
    303                          !strcmp(ep->d_name, "uevent") || !strcmp(ep->d_name, "dev") ||
    304                          !strcmp(ep->d_name, "self_test"))
    305                     continue;
    306                 sprintf(full_path, "%s%s%s", sysfs_path, "/", ep->d_name);
    307                 LOGV_IF(0,"HAL DEBUG: reading %s", full_path);
    308                 fd = open(full_path, O_RDONLY);
    309                 if (fd > -1) {
    310                     memset(buf, 0, sizeof(buf));
    311                     res = read_attribute_sensor(fd, buf, sizeof(buf));
    312                     close(fd);
    313                     if (res > 0) {
    314                         res = sscanf(buf, "%ld", &data);
    315                         if (res)
    316                             LOGI("HAL DEBUG:sysfs:cat %s = %ld", full_path, data);
    317                     } else {
    318                          LOGV_IF(0,"HAL DEBUG: error reading %s", full_path);
    319                     }
    320                 } else {
    321                     LOGV_IF(0,"HAL DEBUG: error opening %s", full_path);
    322                 }
    323                 close(fd);
    324             }
    325         }
    326         closedir(dp);
    327     } else{
    328         LOGI("HAL DEBUG: could not open directory %s", sysfs_path);
    329     }
    330 
    331     return res;
    332 }
    333 
    334 int inv_float_to_q16(float *fdata, long *ldata)
    335 {
    336 
    337     if (!fdata || !ldata)
    338         return -1;
    339     ldata[0] = (long)(fdata[0] * 65536.f);
    340     ldata[1] = (long)(fdata[1] * 65536.f);
    341     ldata[2] = (long)(fdata[2] * 65536.f);
    342     return 0;
    343 }
    344 
    345 int inv_long_to_q16(long *fdata, long *ldata)
    346 {
    347 
    348     if (!fdata || !ldata)
    349         return -1;
    350     ldata[0] = (fdata[1] * 65536.f);
    351     ldata[1] = (fdata[2] * 65536.f);
    352     ldata[2] = (fdata[3] * 65536.f);
    353     return 0;
    354 }
    355 
    356 int inv_float_to_round(float *fdata, long *ldata)
    357 {
    358 
    359     if (!fdata || !ldata)
    360             return -1;
    361     ldata[0] = (long)fdata[0];
    362     ldata[1] = (long)fdata[1];
    363     ldata[2] = (long)fdata[2];
    364     return 0;
    365 }
    366 
    367 int inv_float_to_round2(float *fdata, short *ldata)
    368 {
    369 
    370     if (!fdata || !ldata)
    371         return -1;
    372     ldata[0] = (short)fdata[0];
    373     ldata[1] = (short)fdata[1];
    374     ldata[2] = (short)fdata[2];
    375     return 0;
    376 }
    377 
    378 int inv_long_to_float(long *ldata, float *fdata)
    379 {
    380 
    381     if (!ldata || !fdata)
    382         return -1;
    383     fdata[0] = (float)ldata[0];
    384     fdata[1] = (float)ldata[1];
    385     fdata[2] = (float)ldata[2];
    386     return 0;
    387 }
    388