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>
#define PLATFORM_NAME "Intel Edison"
#define SYSFS_CLASS_GPIO "/sys/class/gpio"
#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
#define MAX_SIZE 64
#define MAX_MODE_SIZE 8
- 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) {
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");
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];
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);
if (write(modef, mode_buf, length * sizeof(char)) == -1) {
ret = MRAA_ERROR_INVALID_RESOURCE;
}
close(modef);
+ mraa_gpio_close(mode_gpio);
}
char filepath[MAX_SIZE];
}
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);
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");
if (drive == -1) {
syslog(LOG_ERR, "edison: Failed to open drive for writing");
+ mraa_gpio_close(mode_gpio);
return MRAA_ERROR_INVALID_RESOURCE;
}
return MRAA_ERROR_INVALID_RESOURCE;
}
int length;
switch (mode) {
case MRAA_GPIO_STRONG:
int length;
switch (mode) {
case MRAA_GPIO_STRONG:
+ mraa_gpio_close(mode_gpio);
close(drive);
return MRAA_SUCCESS;
case MRAA_GPIO_PULLUP:
close(drive);
return MRAA_SUCCESS;
case MRAA_GPIO_PULLUP:
length = snprintf(bu, sizeof(bu), "nopull");
break;
default:
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");
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;
}
close(drive);
return MRAA_ERROR_INVALID_RESOURCE;
}
+ mraa_gpio_close(mode_gpio);
if (close(drive) != 0) {
return MRAA_ERROR_INVALID_RESOURCE;
}
if (close(drive) != 0) {
return MRAA_ERROR_INVALID_RESOURCE;
}