From df0dbb0c739ed4bf958594ce9b046ff37cda8bbf Mon Sep 17 00:00:00 2001 From: Brendan Le Foll Date: Fri, 10 Jul 2015 17:52:50 +0100 Subject: [PATCH] mraa: add internal mraa_find_i2c_bus function Signed-off-by: Brendan Le Foll --- include/mraa_internal.h | 10 ++++++ src/mraa.c | 86 +++++++++++++++++++++++++++++++++++++++++++++- src/x86/intel_de3815.c | 80 ++++++++---------------------------------- src/x86/intel_minnow_max.c | 26 +++++++------- 4 files changed, 122 insertions(+), 80 deletions(-) diff --git a/include/mraa_internal.h b/include/mraa_internal.h index c9eaa7b..f35a197 100644 --- a/include/mraa_internal.h +++ b/include/mraa_internal.h @@ -105,6 +105,16 @@ mraa_boolean_t mraa_file_contains_both(const char* filename, const char* content */ mraa_boolean_t mraa_link_targets(const char* filename, const char* targetname); +/** + * helper function to find the first i2c bus containing devname starting from + * i2c-n where n is startfrom + * + * @param device name to match + * @param i2c-dev number to start search from + * @return the matching i2c-dev bus id or -1 + */ +int mraa_find_i2c_bus(const char* devname, int startfrom); + #ifdef __cplusplus } #endif diff --git a/src/mraa.c b/src/mraa.c index 75084e5..6a4914e 100644 --- a/src/mraa.c +++ b/src/mraa.c @@ -23,13 +23,23 @@ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +#define _GNU_SOURCE +#if !defined(_XOPEN_SOURCE) || _XOPEN_SOURCE < 600 +#define _XOPEN_SOURCE 600 /* Get nftw() and S_IFSOCK declarations */ +#endif + #include #include #include #include #include #include - +#include +#include +#include +#include +#include +#include #include "mraa_internal.h" #include "gpio.h" @@ -426,3 +436,77 @@ mraa_link_targets(const char* filename, const char* targetname) return 0; } } + +static int num_i2c_devices = 0; + +static int +mraa_count_files(const char* path, const struct stat* sb, int flag, struct FTW* ftwb) +{ + switch (sb->st_mode & S_IFMT) { + case S_IFLNK: + num_i2c_devices++; + break; + } + return 0; +} + +int +mraa_find_i2c_bus(const char* devname, int startfrom) +{ + char path[64], value[64]; + int fd; + int i = startfrom; + int ret = -1; + + // because feeding mraa_find_i2c_bus result back into the function is + // useful treat -1 as 0 + if (startfrom < 0) { + startfrom = 0; + } + + // find how many i2c buses we have if we haven't already + if (num_i2c_devices == 0) { + if (nftw("/sys/class/i2c-dev/", &mraa_count_files, 20, FTW_PHYS) == -1) { + return -1; + } + } + + // i2c devices are numbered numerically so 0 must exist otherwise there is + // no i2c-dev loaded + if (mraa_file_exist("/sys/class/i2c-dev/i2c-0")) { + for (i; i < num_i2c_devices; i++) { + off_t size, err; + snprintf(path, 64, "/sys/class/i2c-dev/i2c-%u/name", i); + fd = open(path, O_RDONLY); + if (fd < 0) { + break; + } + size = lseek(fd, 0, SEEK_END); + if (size < 0) { + syslog(LOG_WARNING, "mraa: failed to seek i2c filename file"); + close(fd); + break; + } + err = lseek(fd, 0, SEEK_SET); + if (err < 0) { + syslog(LOG_WARNING, "mraa: failed to seek i2c filename file"); + close(fd); + break; + } + ssize_t r = read(fd, value, size); + if (r > 0) { + if (strcasestr(value, devname) != NULL) { + close(fd); + return i; + } + } else { + syslog(LOG_ERR, "mraa: sysfs i2cdev failed"); + } + close(fd); + } + } else { + syslog(LOG_WARNING, "mraa: no i2c-dev detected, load i2c-dev"); + } + + return ret; +} diff --git a/src/x86/intel_de3815.c b/src/x86/intel_de3815.c index f197bbc..e06c913 100644 --- a/src/x86/intel_de3815.c +++ b/src/x86/intel_de3815.c @@ -22,7 +22,6 @@ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -#define _GNU_SOURCE #include #include #include @@ -33,7 +32,6 @@ #include "x86/intel_de3815.h" #define PLATFORM_NAME "Intel DE3815" -#define MAX_SIZE 64 #define SYSFS_CLASS_GPIO "/sys/class/gpio" #define I2CNAME "designware" @@ -119,73 +117,25 @@ mraa_intel_de3815() strncpy(b->pins[17].name, "SMB_SDA", 8); b->pins[17].capabilites = (mraa_pincapabilities_t){ 1, 0, 0, 0, 0, 0, 0, 0 }; - // BUS DEFINITIONS - int fd; - if (mraa_file_exist("/dev/i2c-0")) { - b->i2c_bus_count = 2; - int i = 0; - int suc = 0; - for (i = 0; i < 9; i++) { - off_t size, err; - char path[MAX_SIZE]; - char value[MAX_SIZE]; - snprintf(path, MAX_SIZE, "/sys/class/i2c-dev/i2c-%u/name", i); - fd = open(path, O_RDONLY); - if (fd < 0) { - break; - } - size = lseek(fd, 0, SEEK_END); - if (size < 0) { - syslog(LOG_WARNING, "mraa: failed to seek i2c filename file"); - close(fd); - break; - } - err = lseek(fd, 0, SEEK_SET); - if (err < 0) { - syslog(LOG_WARNING, "mraa: failed to seek i2c filename file"); - close(fd); - break; - } - if (size >= MAX_SIZE) { - syslog(LOG_NOTICE, "mraa: i2c filename file too big, skipping"); - close(fd); - break; - } - ssize_t r = read(fd, value, size); - if (r > 0) { - if (strcasestr(value, I2CNAME) != NULL) { - suc = 1; - b->i2c_bus_count = 2; - b->def_i2c_bus = 0; - b->i2c_bus[0].bus_id = i; - b->i2c_bus[0].sda = 12; - b->i2c_bus[0].scl = 13; - - b->i2c_bus[1].bus_id = i + 1; - b->i2c_bus[1].sda = 14; - b->i2c_bus[1].scl = 15; - close(fd); - break; - } - } else { - syslog(LOG_ERR, "mraa: sysfs i2cdev failed"); - close(fd); - break; - } - close(fd); + b->i2c_bus_count = 0; + int i2c_num = -1; + int i; + for (i = 0; i < 2; i++) { + i2c_num = mraa_find_i2c_bus(I2CNAME, i2c_num + 1); + if (i2c_num == -1) { + break; } + b->i2c_bus_count++; + b->i2c_bus[i].bus_id = i2c_num; + b->i2c_bus[i].sda = 12 + i; + b->i2c_bus[i].scl = 13 + i; + } - if (!suc) { - syslog(LOG_WARNING, "mraa: no i2c-dev detected, load i2c-dev"); - b->i2c_bus_count = 0; - b->def_i2c_bus = 0; - } - } else { - syslog(LOG_WARNING, "mraa: no i2c-dev detected, load i2c-dev"); - b->i2c_bus_count = 0; - b->def_i2c_bus = 0; + if (b->i2c_bus_count > 0) { + b->def_i2c_bus = b->i2c_bus[0].bus_id; } + b->spi_bus_count = 1; b->def_spi_bus = 0; b->spi_bus[0].bus_id = 1; diff --git a/src/x86/intel_minnow_max.c b/src/x86/intel_minnow_max.c index 48b30b7..8b4128d 100644 --- a/src/x86/intel_minnow_max.c +++ b/src/x86/intel_minnow_max.c @@ -31,9 +31,9 @@ #include "x86/intel_minnow_max.h" #define PLATFORM_NAME "MinnowBoard MAX" -#define I2C_BUS_COUNT 10 #define I2C_BUS_DEFAULT 7 #define MAX_LENGTH 8 +#define I2CNAME "designware" int arch_nr_gpios_adjust = 0x100; @@ -151,24 +151,22 @@ mraa_intel_minnow_max() mraa_set_pininfo(b, 25, "S5_4", (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 0, 0, 0 }, 84); mraa_set_pininfo(b, 26, "IBL8254", (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 0, 0, 0 }, 208); - // Set number of i2c adaptors - // Got this from running 'i2cdetect -l' - b->i2c_bus_count = I2C_BUS_COUNT; - - // Disable all i2c adaptors - int ici; - for (ici = 0; ici < b->i2c_bus_count; ici++) { - b->i2c_bus[ici].bus_id = -1; - } + // Set number of i2c adaptors usable from userspace + b->i2c_bus_count = 2; // Configure i2c adaptor #7 and make it the default int pin_index_sda, pin_index_scl; if (mraa_get_pin_index(b, "I2C_SDA", &pin_index_sda) == MRAA_SUCCESS && mraa_get_pin_index(b, "I2C_SCL", &pin_index_scl) == MRAA_SUCCESS) { - b->def_i2c_bus = I2C_BUS_DEFAULT; - b->i2c_bus[b->def_i2c_bus].bus_id = b->def_i2c_bus; - b->i2c_bus[b->def_i2c_bus].sda = pin_index_sda; - b->i2c_bus[b->def_i2c_bus].scl = pin_index_scl; + int bus = mraa_find_i2c_bus(I2CNAME, 0); + if (bus == -1) { + b->i2c_bus_count = 0; + } else { + b->def_i2c_bus = bus; + b->i2c_bus[b->def_i2c_bus].bus_id = b->def_i2c_bus; + b->i2c_bus[b->def_i2c_bus].sda = pin_index_sda; + b->i2c_bus[b->def_i2c_bus].scl = pin_index_scl; + } } // Configure PWM -- 2.7.4