diff --git a/src/x86/intel_edison_fab_c.c b/src/x86/intel_edison_fab_c.c index 3083a95..decf624 100644 --- a/src/x86/intel_edison_fab_c.c +++ b/src/x86/intel_edison_fab_c.c @@ -34,7 +34,7 @@ #define PLATFORM_NAME "Intel Edison" #define SYSFS_CLASS_GPIO "/sys/class/gpio" -#define SYSFS_PINMODE_PATH "/sys/kernel/debug/gpio_debug/gpio" +#define DEBUGFS_PINMODE_PATH "/sys/kernel/debug/gpio_debug/gpio" #define MAX_SIZE 64 #define MAX_MODE_SIZE 8 @@ -105,20 +105,36 @@ mraa_intel_edison_pinmode_change(int sysfs, int mode) } char buffer[MAX_SIZE]; - snprintf(buffer, MAX_SIZE, SYSFS_PINMODE_PATH "%i/current_pinmux", sysfs); + int useDebugFS = 0; + + mraa_gpio_context mode_gpio = mraa_gpio_init_raw(sysfs); + if (mode_gpio == NULL) { + return MRAA_ERROR_NO_RESOURCES; + } + + // first try SYSFS_CLASS_GPIO path + snprintf(buffer, MAX_SIZE, SYSFS_CLASS_GPIO "/gpio%i/pinmux", sysfs); int modef = open(buffer, O_WRONLY); + if (modef == -1) { + snprintf(buffer, MAX_SIZE, DEBUGFS_PINMODE_PATH "%i/current_pinmux", sysfs); + modef = open(buffer, O_WRONLY); + useDebugFS = 1; + } + if (modef == -1) { syslog(LOG_ERR, "edison: Failed to open SoC pinmode for opening"); + mraa_gpio_close(mode_gpio); return MRAA_ERROR_INVALID_RESOURCE; } mraa_result_t ret = MRAA_SUCCESS; char mode_buf[MAX_MODE_SIZE]; - int length = sprintf(mode_buf, "mode%u", mode); + int length = sprintf(mode_buf, "%s%u", useDebugFS ? "mode" : "", mode); if (write(modef, mode_buf, length * sizeof(char)) == -1) { ret = MRAA_ERROR_INVALID_RESOURCE; } close(modef); + mraa_gpio_close(mode_gpio); return ret; } @@ -517,11 +533,24 @@ mraa_intel_edsion_mb_gpio_mode(mraa_gpio_context dev, mraa_gpio_mode_t mode) } char filepath[MAX_SIZE]; - snprintf(filepath, MAX_SIZE, SYSFS_PINMODE_PATH "%d/current_pullmode", dev->pin); + mraa_gpio_context mode_gpio = mraa_gpio_init_raw(dev->pin); + if (mode_gpio == NULL) { + return MRAA_ERROR_NO_RESOURCES; + } + + // first try SYSFS_CLASS_GPIO path + snprintf(filepath, MAX_SIZE, SYSFS_CLASS_GPIO "/gpio%d/pullmode", dev->pin); int drive = open(filepath, O_WRONLY); + + if (drive == -1) { + snprintf(filepath, MAX_SIZE, DEBUGFS_PINMODE_PATH "%d/current_pullmode", dev->pin); + drive = open(filepath, O_WRONLY); + } + if (drive == -1) { syslog(LOG_ERR, "edison: Failed to open drive for writing"); + mraa_gpio_close(mode_gpio); return MRAA_ERROR_INVALID_RESOURCE; } @@ -529,6 +558,7 @@ mraa_intel_edsion_mb_gpio_mode(mraa_gpio_context dev, mraa_gpio_mode_t mode) int length; switch (mode) { case MRAA_GPIO_STRONG: + mraa_gpio_close(mode_gpio); close(drive); return MRAA_SUCCESS; case MRAA_GPIO_PULLUP: @@ -541,15 +571,18 @@ mraa_intel_edsion_mb_gpio_mode(mraa_gpio_context dev, mraa_gpio_mode_t mode) length = snprintf(bu, sizeof(bu), "nopull"); break; default: + mraa_gpio_close(mode_gpio); close(drive); return MRAA_ERROR_FEATURE_NOT_IMPLEMENTED; } if (write(drive, bu, length * sizeof(char)) == -1) { syslog(LOG_ERR, "edison: Failed to write to drive mode"); + mraa_gpio_close(mode_gpio); close(drive); return MRAA_ERROR_INVALID_RESOURCE; } + mraa_gpio_close(mode_gpio); if (close(drive) != 0) { return MRAA_ERROR_INVALID_RESOURCE; }