intel_edison_fab_c.c: Remove dependency on debugfs
authorMihai Serban <mihai.serban@intel.com>
Mon, 9 Nov 2015 15:59:56 +0000 (17:59 +0200)
committerBrendan Le Foll <brendan.le.foll@intel.com>
Fri, 4 Dec 2015 15:37:20 +0000 (15:37 +0000)
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 <mihai.serban@intel.com>
Signed-off-by: Constantin Musca <constantin.musca@intel.com>
Signed-off-by: Brendan Le Foll <brendan.le.foll@intel.com>
src/x86/intel_edison_fab_c.c

index 3083a95..decf624 100644 (file)
@@ -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;
     }