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 #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 fscanf(sysfsfp, "%d\n", var); 154 fclose(sysfsfp); 155 } else { 156 res = errno; 157 LOGE("HAL:ERR open file %s to read with error %d", filename, res); 158 } 159 return -res; 160 } 161 162 int write_sysfs_int(char *filename, int var) 163 { 164 int res=0; 165 FILE *sysfsfp; 166 167 sysfsfp = fopen(filename, "w"); 168 if (sysfsfp!=NULL) { 169 fprintf(sysfsfp, "%d\n", var); 170 fclose(sysfsfp); 171 } else { 172 res = errno; 173 LOGE("HAL:ERR open file %s to write with error %d", filename, res); 174 } 175 return -res; 176 } 177 178 int write_sysfs_longlong(char *filename, int64_t var) 179 { 180 int res=0; 181 FILE *sysfsfp; 182 183 sysfsfp = fopen(filename, "w"); 184 if (sysfsfp!=NULL) { 185 fprintf(sysfsfp, "%lld\n", var); 186 fclose(sysfsfp); 187 } else { 188 res = errno; 189 LOGE("HAL:ERR open file %s to write with error %d", filename, res); 190 } 191 return -res; 192 } 193 194 int fill_dev_full_name_by_prefix(const char* dev_prefix, 195 char *dev_full_name, int len) 196 { 197 char cand_name[20]; 198 int prefix_len = strlen(dev_prefix); 199 strncpy(cand_name, dev_prefix, sizeof(cand_name) / sizeof(cand_name[0])); 200 201 // try adding a number, 0-9 202 for(int cand_postfix = 0; cand_postfix < 10; cand_postfix++) { 203 snprintf(&cand_name[prefix_len], 204 sizeof(cand_name) / sizeof(cand_name[0]), 205 "%d", cand_postfix); 206 int dev_num = find_type_by_name(cand_name, "iio:device"); 207 if (dev_num != -ENODEV) { 208 strncpy(dev_full_name, cand_name, len); 209 return 0; 210 } 211 } 212 // try adding a small letter, a-z 213 for(char cand_postfix = 'a'; cand_postfix <= 'z'; cand_postfix++) { 214 snprintf(&cand_name[prefix_len], 215 sizeof(cand_name) / sizeof(cand_name[0]), 216 "%c", cand_postfix); 217 int dev_num = find_type_by_name(cand_name, "iio:device"); 218 if (dev_num != -ENODEV) { 219 strncpy(dev_full_name, cand_name, len); 220 return 0; 221 } 222 } 223 // try adding a capital letter, A-Z 224 for(char cand_postfix = 'A'; cand_postfix <= 'Z'; cand_postfix++) { 225 snprintf(&cand_name[prefix_len], 226 sizeof(cand_name) / sizeof(cand_name[0]), 227 "%c", cand_postfix); 228 int dev_num = find_type_by_name(cand_name, "iio:device"); 229 if (dev_num != -ENODEV) { 230 strncpy(dev_full_name, cand_name, len); 231 return 0; 232 } 233 } 234 return 1; 235 } 236 237 void dump_dmp_img(const char *outFile) 238 { 239 FILE *fp; 240 int i; 241 242 char sysfs_path[MAX_SYSFS_NAME_LEN]; 243 char dmp_path[MAX_SYSFS_NAME_LEN]; 244 245 inv_get_sysfs_path(sysfs_path); 246 sprintf(dmp_path, "%s%s", sysfs_path, "/dmp_firmware"); 247 248 LOGI("HAL DEBUG:dump DMP image"); 249 LOGI("HAL DEBUG:open %s\n", dmp_path); 250 LOGI("HAL DEBUG:write to %s", outFile); 251 252 read_dmp_img(dmp_path, (char *)outFile); 253 } 254 255 int read_sysfs_dir(bool fileMode, char *sysfs_path) 256 { 257 VFUNC_LOG; 258 259 int res = 0; 260 char full_path[MAX_SYSFS_NAME_LEN]; 261 int fd; 262 char buf[sizeof(long) *4]; 263 long data; 264 265 DIR *dp; 266 struct dirent *ep; 267 268 dp = opendir (sysfs_path); 269 270 if (dp != NULL) 271 { 272 LOGI("******************** System Sysfs Dump ***************************"); 273 LOGV_IF(0,"HAL DEBUG: opened directory %s", sysfs_path); 274 while ((ep = readdir (dp))) { 275 if(ep != NULL) { 276 LOGV_IF(0,"file name %s", ep->d_name); 277 if(!strcmp(ep->d_name, ".") || !strcmp(ep->d_name, "..") || 278 !strcmp(ep->d_name, "uevent") || !strcmp(ep->d_name, "dev") || 279 !strcmp(ep->d_name, "self_test")) 280 continue; 281 sprintf(full_path, "%s%s%s", sysfs_path, "/", ep->d_name); 282 LOGV_IF(0,"HAL DEBUG: reading %s", full_path); 283 fd = open(full_path, O_RDONLY); 284 if (fd > -1) { 285 memset(buf, 0, sizeof(buf)); 286 res = read_attribute_sensor(fd, buf, sizeof(buf)); 287 close(fd); 288 if (res > 0) { 289 res = sscanf(buf, "%ld", &data); 290 if (res) 291 LOGI("HAL DEBUG:sysfs:cat %s = %ld", full_path, data); 292 } else { 293 LOGV_IF(0,"HAL DEBUG: error reading %s", full_path); 294 } 295 } else { 296 LOGV_IF(0,"HAL DEBUG: error opening %s", full_path); 297 } 298 close(fd); 299 } 300 } 301 closedir(dp); 302 } else{ 303 LOGI("HAL DEBUG: could not open directory %s", sysfs_path); 304 } 305 306 return res; 307 } 308