1 /* 2 * Author: Brendan Le Foll <brendan.le.foll (at) intel.com> 3 * Author: Thomas Ingleby <thomas.c.ingleby (at) intel.com> 4 * Copyright (c) 2014-2016 Intel Corporation. 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining 7 * a copy of this software and associated documentation files (the 8 * "Software"), to deal in the Software without restriction, including 9 * without limitation the rights to use, copy, modify, merge, publish, 10 * distribute, sublicense, and/or sell copies of the Software, and to 11 * permit persons to whom the Software is furnished to do so, subject to 12 * the following conditions: 13 * 14 * The above copyright notice and this permission notice shall be 15 * included in all copies or substantial portions of the Software. 16 * 17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 18 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 20 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 21 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 22 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 23 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 */ 25 26 #define _GNU_SOURCE 27 #if !defined(_XOPEN_SOURCE) || _XOPEN_SOURCE < 600 28 #define _XOPEN_SOURCE 600 /* Get nftw() and S_IFSOCK declarations */ 29 #endif 30 31 #include <stddef.h> 32 #include <stdlib.h> 33 #include <sched.h> 34 #include <string.h> 35 #include <pwd.h> 36 #include <glob.h> 37 #include <ftw.h> 38 #include <dirent.h> 39 #include <sys/stat.h> 40 #include <fcntl.h> 41 #include <string.h> 42 #include <stdio.h> 43 44 #include "mraa_internal.h" 45 #include "gpio.h" 46 #include "version.h" 47 48 #define IIO_DEVICE_WILDCARD "iio:device*" 49 mraa_board_t* plat = NULL; 50 mraa_iio_info_t* plat_iio = NULL; 51 52 static char* platform_name = NULL; 53 static char* platform_long_name = NULL; 54 55 static int num_i2c_devices = 0; 56 static int num_iio_devices = 0; 57 58 const char* 59 mraa_get_version() 60 { 61 return gVERSION; 62 } 63 64 mraa_result_t 65 mraa_set_log_level(int level) 66 { 67 if (level <= 7 && level >= 0) { 68 setlogmask(LOG_UPTO(level)); 69 syslog(LOG_DEBUG, "Loglevel %d is set", level); 70 return MRAA_SUCCESS; 71 } 72 syslog(LOG_NOTICE, "Invalid loglevel %d requested", level); 73 return MRAA_ERROR_INVALID_PARAMETER; 74 } 75 76 77 #if (defined SWIGPYTHON) || (defined SWIG) 78 mraa_result_t 79 #else 80 mraa_result_t __attribute__((constructor)) 81 #endif 82 mraa_init() 83 { 84 if (plat != NULL) { 85 return MRAA_ERROR_PLATFORM_ALREADY_INITIALISED; 86 } 87 88 uid_t proc_euid = geteuid(); 89 struct passwd* proc_user = getpwuid(proc_euid); 90 91 #ifdef DEBUG 92 setlogmask(LOG_UPTO(LOG_DEBUG)); 93 #else 94 setlogmask(LOG_UPTO(LOG_NOTICE)); 95 #endif 96 97 openlog("libmraa", LOG_CONS | LOG_PID | LOG_NDELAY, LOG_LOCAL1); 98 syslog(LOG_NOTICE, "libmraa version %s initialised by user '%s' with EUID %d", 99 mraa_get_version(), (proc_user != NULL) ? proc_user->pw_name : "<unknown>", proc_euid); 100 101 #ifdef SWIGPYTHON 102 // Initialise python threads, this allows use to grab the GIL when we are 103 // required to do so 104 Py_InitializeEx(0); 105 PyEval_InitThreads(); 106 #endif 107 108 mraa_platform_t platform_type; 109 #if defined(X86PLAT) 110 // Use runtime x86 platform detection 111 platform_type = mraa_x86_platform(); 112 #elif defined(ARMPLAT) 113 // Use runtime ARM platform detection 114 platform_type = mraa_arm_platform(); 115 #else 116 #error mraa_ARCH NOTHING 117 #endif 118 119 if (plat != NULL) { 120 plat->platform_type = platform_type; 121 } else { 122 platform_name = NULL; 123 } 124 125 #if defined(USBPLAT) 126 // This is a platform extender so create null base platform if one doesn't already exist 127 if (plat == NULL) { 128 plat = (mraa_board_t*) calloc(1, sizeof(mraa_board_t)); 129 if (plat != NULL) { 130 plat->platform_type = MRAA_NULL_PLATFORM; 131 plat->platform_name = "Unknown platform"; 132 } 133 } 134 // Now detect sub platform 135 if (plat != NULL) { 136 mraa_platform_t usb_platform_type = mraa_usb_platform_extender(plat); 137 if (plat->platform_type == MRAA_UNKNOWN_PLATFORM && usb_platform_type != MRAA_UNKNOWN_PLATFORM) { 138 plat->platform_type = usb_platform_type; 139 } else { 140 return MRAA_ERROR_PLATFORM_NOT_INITIALISED; 141 } 142 } 143 if (plat == NULL) { 144 printf("mraa: FATAL error, failed to initialise platform\n"); 145 return MRAA_ERROR_PLATFORM_NOT_INITIALISED; 146 } 147 #endif 148 149 // Look for IIO devices 150 mraa_iio_detect(); 151 152 if (plat != NULL) { 153 int length = strlen(plat->platform_name) + 1; 154 if (mraa_has_sub_platform()) { 155 length += strlen(plat->sub_platform->platform_name); 156 } 157 platform_name = calloc(length, sizeof(char)); 158 if (mraa_has_sub_platform()) { 159 snprintf(platform_name, length, "%s + %s", plat->platform_name, plat->sub_platform->platform_name); 160 } else { 161 strncpy(platform_name, plat->platform_name, length); 162 } 163 } 164 165 syslog(LOG_NOTICE, "libmraa initialised for platform '%s' of type %d", mraa_get_platform_name(), mraa_get_platform_type()); 166 return MRAA_SUCCESS; 167 } 168 169 void 170 mraa_deinit() 171 { 172 if (plat != NULL) { 173 if (plat->pins != NULL) { 174 free(plat->pins); 175 } 176 mraa_board_t* sub_plat = plat->sub_platform; 177 if (sub_plat != NULL) { 178 if (sub_plat->pins != NULL) { 179 free(sub_plat->pins); 180 } 181 free(sub_plat); 182 } 183 free(plat); 184 185 } 186 if (plat_iio != NULL) { 187 free(plat_iio); 188 } 189 closelog(); 190 } 191 192 int 193 mraa_set_priority(const unsigned int priority) 194 { 195 struct sched_param sched_s; 196 197 memset(&sched_s, 0, sizeof(struct sched_param)); 198 if (priority > sched_get_priority_max(SCHED_RR)) { 199 sched_s.sched_priority = sched_get_priority_max(SCHED_RR); 200 } else { 201 sched_s.sched_priority = priority; 202 } 203 204 return sched_setscheduler(0, SCHED_RR, &sched_s); 205 } 206 207 static int 208 mraa_count_iio_devices(const char* path, const struct stat* sb, int flag, struct FTW* ftwb) 209 { 210 // we are only interested in files with specific names 211 if (fnmatch(IIO_DEVICE_WILDCARD, basename(path), 0) == 0) { 212 num_iio_devices++; 213 } 214 return 0; 215 } 216 217 mraa_result_t 218 mraa_iio_detect() 219 { 220 plat_iio = (mraa_iio_info_t*) calloc(1, sizeof(mraa_iio_info_t)); 221 plat_iio->iio_device_count = num_iio_devices; 222 // Now detect IIO devices, linux only 223 // find how many iio devices we have if we haven't already 224 if (num_iio_devices == 0) { 225 if (nftw("/sys/bus/iio/devices", &mraa_count_iio_devices, 20, FTW_PHYS) == -1) { 226 return MRAA_ERROR_UNSPECIFIED; 227 } 228 } 229 char name[64], filepath[64]; 230 int fd, len, i; 231 plat_iio->iio_device_count = num_iio_devices; 232 plat_iio->iio_devices = calloc(num_iio_devices, sizeof(struct _iio)); 233 struct _iio* device; 234 for (i=0; i < num_iio_devices; i++) { 235 device = &plat_iio->iio_devices[i]; 236 device->num = i; 237 snprintf(filepath, 64, "/sys/bus/iio/devices/iio:device%d/name", i); 238 fd = open(filepath, O_RDONLY); 239 if (fd != -1) { 240 len = read(fd, &name, 64); 241 if (len > 1) { 242 // remove any trailing CR/LF symbols 243 name[strcspn(name, "\r\n")] = '\0'; 244 len = strlen(name); 245 // use strndup 246 device->name = malloc((sizeof(char) * len) + sizeof(char)); 247 strncpy(device->name, name, len+1); 248 } 249 close(fd); 250 } 251 } 252 return MRAA_SUCCESS; 253 } 254 255 256 mraa_result_t 257 mraa_setup_mux_mapped(mraa_pin_t meta) 258 { 259 int mi; 260 261 for (mi = 0; mi < meta.mux_total; mi++) { 262 mraa_gpio_context mux_i; 263 mux_i = mraa_gpio_init_raw(meta.mux[mi].pin); 264 if (mux_i == NULL) { 265 return MRAA_ERROR_INVALID_HANDLE; 266 } 267 // this function will sometimes fail, however this is not critical as 268 // long as the write succeeds - Test case galileo gen2 pin2 269 mraa_gpio_dir(mux_i, MRAA_GPIO_OUT); 270 mraa_gpio_owner(mux_i, 0); 271 272 if (mraa_gpio_write(mux_i, meta.mux[mi].value) != MRAA_SUCCESS) { 273 mraa_gpio_close(mux_i); 274 return MRAA_ERROR_INVALID_RESOURCE; 275 } 276 mraa_gpio_close(mux_i); 277 } 278 279 return MRAA_SUCCESS; 280 } 281 282 void 283 mraa_result_print(mraa_result_t result) 284 { 285 switch (result) { 286 case MRAA_SUCCESS: 287 fprintf(stdout, "MRAA: SUCCESS\n"); 288 break; 289 case MRAA_ERROR_FEATURE_NOT_IMPLEMENTED: 290 fprintf(stdout, "MRAA: Feature not implemented.\n"); 291 break; 292 case MRAA_ERROR_FEATURE_NOT_SUPPORTED: 293 fprintf(stdout, "MRAA: Feature not supported by Hardware.\n"); 294 break; 295 case MRAA_ERROR_INVALID_VERBOSITY_LEVEL: 296 fprintf(stdout, "MRAA: Invalid verbosity level.\n"); 297 break; 298 case MRAA_ERROR_INVALID_PARAMETER: 299 fprintf(stdout, "MRAA: Invalid parameter.\n"); 300 break; 301 case MRAA_ERROR_INVALID_HANDLE: 302 fprintf(stdout, "MRAA: Invalid Handle.\n"); 303 break; 304 case MRAA_ERROR_NO_RESOURCES: 305 fprintf(stdout, "MRAA: No resources.\n"); 306 break; 307 case MRAA_ERROR_INVALID_RESOURCE: 308 fprintf(stdout, "MRAA: Invalid resource.\n"); 309 break; 310 case MRAA_ERROR_INVALID_QUEUE_TYPE: 311 fprintf(stdout, "MRAA: Invalid Queue Type.\n"); 312 break; 313 case MRAA_ERROR_NO_DATA_AVAILABLE: 314 fprintf(stdout, "MRAA: No Data available.\n"); 315 break; 316 case MRAA_ERROR_INVALID_PLATFORM: 317 fprintf(stdout, "MRAA: Platform not recognised.\n"); 318 break; 319 case MRAA_ERROR_PLATFORM_NOT_INITIALISED: 320 fprintf(stdout, "MRAA: Platform not initialised.\n"); 321 break; 322 case MRAA_ERROR_PLATFORM_ALREADY_INITIALISED: 323 fprintf(stdout, "MRAA: Platform already initialised.\n"); 324 break; 325 case MRAA_ERROR_UNSPECIFIED: 326 fprintf(stdout, "MRAA: Unspecified Error.\n"); 327 break; 328 default: 329 fprintf(stdout, "MRAA: Unrecognised error.\n"); 330 break; 331 } 332 } 333 334 335 mraa_boolean_t 336 mraa_has_sub_platform() 337 { 338 return (plat != NULL) && (plat->sub_platform != NULL); 339 } 340 341 mraa_boolean_t 342 mraa_pin_mode_test(int pin, mraa_pinmodes_t mode) 343 { 344 if (plat == NULL) 345 return 0; 346 347 mraa_board_t* current_plat = plat; 348 if (mraa_is_sub_platform_id(pin)) { 349 current_plat = plat->sub_platform; 350 if (current_plat == NULL) { 351 syslog(LOG_ERR, "mraa_pin_mode_test: Sub platform Not Initialised"); 352 return 0; 353 } 354 pin = mraa_get_sub_platform_index(pin); 355 } 356 357 if (current_plat == NULL || current_plat->platform_type == MRAA_UNKNOWN_PLATFORM) { 358 return 0; 359 } 360 if (pin > (current_plat->phy_pin_count - 1) || pin < 0) 361 return 0; 362 363 switch (mode) { 364 case MRAA_PIN_VALID: 365 if (current_plat->pins[pin].capabilites.valid == 1) 366 return 1; 367 break; 368 case MRAA_PIN_GPIO: 369 if (current_plat->pins[pin].capabilites.gpio == 1) 370 return 1; 371 break; 372 case MRAA_PIN_PWM: 373 if (current_plat->pins[pin].capabilites.pwm == 1) 374 return 1; 375 break; 376 case MRAA_PIN_FAST_GPIO: 377 if (current_plat->pins[pin].capabilites.fast_gpio == 1) 378 return 1; 379 break; 380 case MRAA_PIN_SPI: 381 if (current_plat->pins[pin].capabilites.spi == 1) 382 return 1; 383 break; 384 case MRAA_PIN_I2C: 385 if (current_plat->pins[pin].capabilites.i2c == 1) 386 return 1; 387 break; 388 case MRAA_PIN_AIO: 389 if (current_plat->pins[pin].capabilites.aio == 1) 390 return 1; 391 break; 392 case MRAA_PIN_UART: 393 if (current_plat->pins[pin].capabilites.uart == 1) 394 return 1; 395 break; 396 default: 397 syslog(LOG_NOTICE, "requested pinmode invalid"); 398 break; 399 } 400 return 0; 401 } 402 403 mraa_platform_t 404 mraa_get_platform_type() 405 { 406 if (plat == NULL) 407 return MRAA_UNKNOWN_PLATFORM; 408 return plat->platform_type; 409 } 410 411 int 412 mraa_get_platform_combined_type() 413 { 414 int type = mraa_get_platform_type(); 415 int sub_type = mraa_has_sub_platform() ? plat->sub_platform->platform_type : MRAA_UNKNOWN_PLATFORM; 416 return type | (sub_type << 8); 417 } 418 419 unsigned int 420 mraa_adc_raw_bits() 421 { 422 if (plat == NULL) 423 return 0; 424 425 if (plat->aio_count == 0) 426 return 0; 427 428 return plat->adc_raw; 429 } 430 431 unsigned int 432 mraa_get_platform_adc_raw_bits(uint8_t platform_offset) 433 { 434 if (platform_offset == MRAA_MAIN_PLATFORM_OFFSET) 435 return mraa_adc_raw_bits(); 436 else { 437 if (!mraa_has_sub_platform()) 438 return 0; 439 440 if (plat->sub_platform->aio_count == 0) 441 return 0; 442 443 return plat->sub_platform->adc_raw; 444 } 445 } 446 447 448 unsigned int 449 mraa_adc_supported_bits() 450 { 451 if (plat == NULL) 452 return 0; 453 454 if (plat->aio_count == 0) 455 return 0; 456 457 return plat->adc_supported; 458 } 459 460 unsigned int 461 mraa_get_platform_adc_supported_bits(int platform_offset) 462 { 463 if (platform_offset == MRAA_MAIN_PLATFORM_OFFSET) 464 return mraa_adc_supported_bits(); 465 else { 466 if (!mraa_has_sub_platform()) 467 return 0; 468 469 if (plat->sub_platform->aio_count == 0) 470 return 0; 471 472 return plat->sub_platform->adc_supported; 473 } 474 } 475 476 const char* 477 mraa_get_platform_name() 478 { 479 return platform_name; 480 } 481 482 const char* 483 mraa_get_platform_version(int platform_offset) 484 { 485 if (plat == NULL) { 486 return NULL; 487 } 488 if (platform_offset == MRAA_MAIN_PLATFORM_OFFSET) { 489 return plat->platform_version; 490 } else { 491 return plat->sub_platform->platform_version; 492 } 493 } 494 495 int 496 mraa_get_i2c_bus_count() 497 { 498 if (plat == NULL) { 499 return -1; 500 } 501 return plat->i2c_bus_count; 502 } 503 504 int 505 mraa_get_i2c_bus_id(unsigned i2c_bus) 506 { 507 if (plat == NULL) { 508 return -1; 509 } 510 511 if (i2c_bus >= plat->i2c_bus_count) { 512 return -1; 513 } 514 515 return plat->i2c_bus[i2c_bus].bus_id; 516 } 517 518 unsigned int 519 mraa_get_pin_count() 520 { 521 if (plat == NULL) { 522 return 0; 523 } 524 return plat->phy_pin_count; 525 } 526 527 unsigned int 528 mraa_get_platform_pin_count(uint8_t platform_offset) 529 { 530 if (platform_offset == MRAA_MAIN_PLATFORM_OFFSET) 531 return mraa_get_pin_count(); 532 else { 533 if (mraa_has_sub_platform()) 534 return plat->sub_platform->phy_pin_count; 535 else 536 return 0; 537 } 538 } 539 540 541 char* 542 mraa_get_pin_name(int pin) 543 { 544 if (plat == NULL) 545 return 0; 546 547 mraa_board_t* current_plat = plat; 548 if (mraa_is_sub_platform_id(pin)) { 549 current_plat = plat->sub_platform; 550 if (current_plat == NULL) { 551 syslog(LOG_ERR, "mraa_get_pin_name: Sub platform Not Initialised"); 552 return 0; 553 } 554 pin = mraa_get_sub_platform_index(pin); 555 } 556 557 if (pin > (current_plat->phy_pin_count - 1) || pin < 0) 558 return NULL; 559 return (char*) current_plat->pins[pin].name; 560 } 561 562 int 563 mraa_get_default_i2c_bus(uint8_t platform_offset) 564 { 565 if (plat == NULL) 566 return -1; 567 if (platform_offset == MRAA_MAIN_PLATFORM_OFFSET) { 568 return plat->def_i2c_bus; 569 } else { 570 if (mraa_has_sub_platform()) 571 return plat->sub_platform->def_i2c_bus; 572 else 573 return -1; 574 } 575 } 576 577 578 mraa_boolean_t 579 mraa_file_exist(const char* filename) 580 { 581 glob_t results; 582 results.gl_pathc = 0; 583 glob(filename, 0, NULL, &results); 584 int file_found = results.gl_pathc == 1; 585 globfree(&results); 586 return file_found; 587 } 588 589 mraa_boolean_t 590 mraa_file_contains(const char* filename, const char* content) 591 { 592 mraa_boolean_t found = 0; 593 if ((filename == NULL) || (content == NULL)) { 594 return 0; 595 } 596 597 char* file = mraa_file_unglob(filename); 598 if (file != NULL) { 599 size_t len = 1024; 600 char* line = calloc(len, sizeof(char)); 601 if (line == NULL) { 602 free(file); 603 return 0; 604 } 605 FILE* fh = fopen(file, "r"); 606 if (fh == NULL) { 607 free(file); 608 free(line); 609 return 0; 610 } 611 while ((getline(&line, &len, fh) != -1) && (found == 0)) { 612 if (strstr(line, content)) { 613 found = 1; 614 break; 615 } 616 } 617 fclose(fh); 618 free(file); 619 free(line); 620 } 621 return found; 622 } 623 624 mraa_boolean_t 625 mraa_file_contains_both(const char* filename, const char* content, const char* content2) 626 { 627 mraa_boolean_t found = 0; 628 if ((filename == NULL) || (content == NULL)) { 629 return 0; 630 } 631 632 char* file = mraa_file_unglob(filename); 633 if (file != NULL) { 634 size_t len = 1024; 635 char* line = calloc(len, sizeof(char)); 636 if (line == NULL) { 637 free(file); 638 return 0; 639 } 640 FILE* fh = fopen(file, "r"); 641 if (fh == NULL) { 642 free(file); 643 free(line); 644 return 0; 645 } 646 while ((getline(&line, &len, fh) != -1) && (found == 0)) { 647 if (strstr(line, content) && strstr(line, content2)) { 648 found = 1; 649 break; 650 } 651 } 652 fclose(fh); 653 free(file); 654 free(line); 655 } 656 return found; 657 } 658 659 char* 660 mraa_file_unglob(const char* filename) 661 { 662 glob_t results; 663 char* res = NULL; 664 results.gl_pathc = 0; 665 glob(filename, 0, NULL, &results); 666 if (results.gl_pathc == 1) 667 res = strdup(results.gl_pathv[0]); 668 globfree(&results); 669 return res; 670 } 671 672 mraa_boolean_t 673 mraa_link_targets(const char* filename, const char* targetname) 674 { 675 int size = 100; 676 int nchars = 0; 677 char* buffer = NULL; 678 while (nchars == 0) { 679 buffer = (char*) realloc(buffer, size); 680 if (buffer == NULL) 681 return 0; 682 nchars = readlink(filename, buffer, size); 683 if (nchars < 0) { 684 free(buffer); 685 return 0; 686 } else { 687 buffer[nchars] = '\0'; 688 } 689 if (nchars >= size) { 690 size *= 2; 691 nchars = 0; 692 } 693 } 694 if (strstr(buffer, targetname)) { 695 free(buffer); 696 return 1; 697 } else { 698 free(buffer); 699 return 0; 700 } 701 } 702 703 static int 704 mraa_count_i2c_files(const char* path, const struct stat* sb, int flag, struct FTW* ftwb) 705 { 706 switch (sb->st_mode & S_IFMT) { 707 case S_IFLNK: 708 num_i2c_devices++; 709 break; 710 } 711 return 0; 712 } 713 714 int 715 mraa_find_i2c_bus(const char* devname, int startfrom) 716 { 717 char path[64]; 718 int fd; 719 int i = startfrom; 720 int ret = -1; 721 722 // because feeding mraa_find_i2c_bus result back into the function is 723 // useful treat -1 as 0 724 if (startfrom < 0) { 725 startfrom = 0; 726 } 727 728 // find how many i2c buses we have if we haven't already 729 if (num_i2c_devices == 0) { 730 if (nftw("/sys/class/i2c-dev/", &mraa_count_i2c_files, 20, FTW_PHYS) == -1) { 731 return -1; 732 } 733 } 734 735 // i2c devices are numbered numerically so 0 must exist otherwise there is 736 // no i2c-dev loaded 737 if (mraa_file_exist("/sys/class/i2c-dev/i2c-0")) { 738 for (i; i < num_i2c_devices; i++) { 739 off_t size, err; 740 snprintf(path, 64, "/sys/class/i2c-dev/i2c-%u/name", i); 741 fd = open(path, O_RDONLY); 742 if (fd < 0) { 743 break; 744 } 745 size = lseek(fd, 0, SEEK_END); 746 if (size < 0) { 747 syslog(LOG_WARNING, "mraa: failed to seek i2c filename file"); 748 close(fd); 749 break; 750 } 751 err = lseek(fd, 0, SEEK_SET); 752 if (err < 0) { 753 syslog(LOG_WARNING, "mraa: failed to seek i2c filename file"); 754 close(fd); 755 break; 756 } 757 char* value = malloc(size); 758 if (value == NULL) { 759 syslog(LOG_ERR, "mraa: failed to allocate memory for i2c file"); 760 close(fd); 761 break; 762 } 763 ssize_t r = read(fd, value, size); 764 if (r > 0) { 765 if (strcasestr(value, devname) != NULL) { 766 free(value); 767 close(fd); 768 return i; 769 } 770 } else { 771 syslog(LOG_ERR, "mraa: sysfs i2cdev failed"); 772 } 773 free(value); 774 close(fd); 775 } 776 } else { 777 syslog(LOG_WARNING, "mraa: no i2c-dev detected, load i2c-dev"); 778 } 779 780 return ret; 781 } 782 783 mraa_boolean_t 784 mraa_is_sub_platform_id(int pin_or_bus) 785 { 786 return (pin_or_bus & MRAA_SUB_PLATFORM_MASK) != 0; 787 } 788 789 int 790 mraa_get_sub_platform_id(int pin_or_bus) 791 { 792 return pin_or_bus | MRAA_SUB_PLATFORM_MASK; 793 } 794 795 int 796 mraa_get_sub_platform_index(int pin_or_bus) 797 { 798 return pin_or_bus & (~MRAA_SUB_PLATFORM_MASK); 799 } 800 801 int 802 mraa_get_iio_device_count() 803 { 804 return plat_iio->iio_device_count; 805 } 806 807 int 808 mraa_find_iio_device(const char* devicename) 809 { 810 int i = 0; 811 for (i; i < plat_iio->iio_device_count; i++) { 812 #if 0 813 // compare with devices array 814 if (!strcmp() { 815 } 816 #endif 817 } 818 return 0; 819 } 820