From 5cf54fdbc26be56b9ac19887d0f86223bfe21c8d Mon Sep 17 00:00:00 2001 From: Mihai Serban Date: Mon, 9 Nov 2015 17:59:56 +0200 Subject: [PATCH] intel_edison_fab_c.c: Remove dependency on debugfs The MRAA library needs the debugfs interface in order to access GPIO pin modes attributes. Mounting the debugfs is not always desirable so this patch instructs libmraa to first check for the required attributes in the normal SYSFS CLASS GPIO interface and to use debugfs as a fallback. Signed-off-by: Mihai Serban Signed-off-by: Constantin Musca Signed-off-by: Brendan Le Foll --- src/x86/intel_edison_fab_c.c | 41 +++++++++++++++++++++++++++++++++++++---- 1 file changed, 37 insertions(+), 4 deletions(-) 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; } -- 2.7.4