intel_edison_fab_c.c: Remove dependency on debugfs
[contrib/mraa.git] / 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;
     }