intel_edison_fab_c.c: Remove dependency on debugfs
[contrib/mraa.git] / src / x86 / intel_edison_fab_c.c
index 944ab93..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;
 }
@@ -250,39 +266,39 @@ mraa_intel_edison_i2c_init_pre(unsigned int bus)
 static mraa_result_t
 mraa_intel_edison_misc_spi()
 {
-    mraa_gpio_write(tristate, 0);
+    // These arrays must have same length
+    static const int gpio_pin_list[] = {263, 240, 262, 241, 242, 243};
+    static int pin_num = sizeof(gpio_pin_list) / sizeof(int);
+    static const int gpio_val_list[] = {1, 0, 1, 0, 0, 0};
+    static const int gpio_dir_list[] = {MRAA_GPIO_OUT, MRAA_GPIO_OUT,
+                                        MRAA_GPIO_OUT, MRAA_GPIO_OUT,
+                                        MRAA_GPIO_OUT, MRAA_GPIO_OUT};
+    int i;
+    mraa_result_t ret;
+
+    MRAA_RETURN_FOR_ERROR(mraa_gpio_write(tristate, 0));
+
+    for (i = 0; i < pin_num; i++) {
+        mraa_gpio_context io = mraa_gpio_init_raw(gpio_pin_list[i]);
+        if (io != NULL) {
+            ret = mraa_gpio_dir(io, gpio_dir_list[i]);
+            if (ret == MRAA_SUCCESS) {
+                ret = mraa_gpio_write(io, gpio_val_list[i]);
+            }
 
-    mraa_gpio_context io10_p1 = mraa_gpio_init_raw(263);
-    mraa_gpio_context io10_p2 = mraa_gpio_init_raw(240);
-    mraa_gpio_context io11_p1 = mraa_gpio_init_raw(262);
-    mraa_gpio_context io11_p2 = mraa_gpio_init_raw(241);
-    mraa_gpio_context io12_p1 = mraa_gpio_init_raw(242);
-    mraa_gpio_context io13_p1 = mraa_gpio_init_raw(243);
-    mraa_gpio_dir(io10_p1, MRAA_GPIO_OUT);
-    mraa_gpio_dir(io10_p2, MRAA_GPIO_OUT);
-    mraa_gpio_dir(io11_p1, MRAA_GPIO_OUT);
-    mraa_gpio_dir(io11_p2, MRAA_GPIO_OUT);
-    mraa_gpio_dir(io12_p1, MRAA_GPIO_OUT);
-    mraa_gpio_dir(io13_p1, MRAA_GPIO_OUT);
-
-    mraa_gpio_write(io10_p1, 1);
-    mraa_gpio_write(io10_p2, 0);
-    mraa_gpio_write(io11_p1, 1);
-    mraa_gpio_write(io11_p2, 0);
-    mraa_gpio_write(io12_p1, 0);
-    mraa_gpio_write(io13_p1, 0);
-
-    mraa_gpio_close(io10_p1);
-    mraa_gpio_close(io10_p2);
-    mraa_gpio_close(io11_p1);
-    mraa_gpio_close(io11_p2);
-    mraa_gpio_close(io12_p1);
-    mraa_gpio_close(io13_p1);
-
-    mraa_intel_edison_pinmode_change(115, 1);
-    mraa_intel_edison_pinmode_change(114, 1);
-    mraa_intel_edison_pinmode_change(109, 1);
-    mraa_gpio_write(tristate, 1);
+            //Don't care return value of close()
+            mraa_gpio_close(io);
+            MRAA_RETURN_FOR_ERROR(ret);
+        } else {
+          syslog(LOG_ERR, "edison: Failed to init raw gpio %d!",gpio_pin_list[i]);
+          return MRAA_ERROR_NO_RESOURCES;
+        }
+    }
+
+    MRAA_RETURN_FOR_ERROR(mraa_intel_edison_pinmode_change(115, 1));
+    MRAA_RETURN_FOR_ERROR(mraa_intel_edison_pinmode_change(114, 1));
+    MRAA_RETURN_FOR_ERROR(mraa_intel_edison_pinmode_change(109, 1));
+    MRAA_RETURN_FOR_ERROR(mraa_gpio_write(tristate, 1));
 
     return MRAA_SUCCESS;
 }
@@ -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;
     }