From 32e757025939ed4fa7255a632778b261586727bc Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=D0=A8=D0=BB=D1=8F=D0=BA=20=D0=9F=D0=B0=D0=B2=D0=B5=D0=BB?=
=?UTF-8?q?=20=D0=92=D1=8F=D1=87=D0=B5=D1=81=D0=BB=D0=B0=D0=B2=D0=BE=D0=B2?=
=?UTF-8?q?=D0=B8=D1=87?=
Date: Wed, 13 Apr 2022 12:58:15 +0300
Subject: [PATCH] Replace c-periphery with submodule
---
.gitmodules | 3 +
sys/arm-linux/c-periphery | 1 +
sys/arm-linux/drivers | 1 +
sys/arm-linux/drivers/gpio.c | 1444 ----------------------------------
sys/arm-linux/drivers/gpio.h | 121 ---
sys/arm-linux/drivers/i2c.c | 136 ----
sys/arm-linux/drivers/i2c.h | 70 --
sys/arm-linux/drivers/spi.c | 404 ----------
sys/arm-linux/drivers/spi.h | 77 --
9 files changed, 5 insertions(+), 2252 deletions(-)
create mode 100644 .gitmodules
create mode 160000 sys/arm-linux/c-periphery
create mode 120000 sys/arm-linux/drivers
delete mode 100644 sys/arm-linux/drivers/gpio.c
delete mode 100644 sys/arm-linux/drivers/gpio.h
delete mode 100644 sys/arm-linux/drivers/i2c.c
delete mode 100644 sys/arm-linux/drivers/i2c.h
delete mode 100644 sys/arm-linux/drivers/spi.c
delete mode 100644 sys/arm-linux/drivers/spi.h
diff --git a/.gitmodules b/.gitmodules
new file mode 100644
index 00000000..59f7998c
--- /dev/null
+++ b/.gitmodules
@@ -0,0 +1,3 @@
+[submodule "sys/arm-linux/c-periphery"]
+ path = sys/arm-linux/c-periphery
+ url = https://github.com/vsergeev/c-periphery
diff --git a/sys/arm-linux/c-periphery b/sys/arm-linux/c-periphery
new file mode 160000
index 00000000..23795679
--- /dev/null
+++ b/sys/arm-linux/c-periphery
@@ -0,0 +1 @@
+Subproject commit 2379567960b9f72ccfb8f9db7271092612e89bdf
diff --git a/sys/arm-linux/drivers b/sys/arm-linux/drivers
new file mode 120000
index 00000000..3cb7783e
--- /dev/null
+++ b/sys/arm-linux/drivers
@@ -0,0 +1 @@
+./c-periphery/src
\ No newline at end of file
diff --git a/sys/arm-linux/drivers/gpio.c b/sys/arm-linux/drivers/gpio.c
deleted file mode 100644
index a248926f..00000000
--- a/sys/arm-linux/drivers/gpio.c
+++ /dev/null
@@ -1,1444 +0,0 @@
-/*
- * c-periphery
- * https://github.com/vsergeev/c-periphery
- * License: MIT
- */
-
-#define _XOPEN_SOURCE 600 /* for POLLRDNORM */
-
-#include
-#include
-#include
-#include
-#include
-#include
-
-#include
-#include
-#include
-#include
-#include
-
-#include
-
-#if PERIPHERY_GPIO_CDEV_SUPPORT
-#include
-
-/* Disable cdev support when building with older kernel headers that don't yet
- * support line events in the gpio-cdev abi */
-#ifndef GPIO_GET_LINEEVENT_IOCTL
-#undef PERIPHERY_GPIO_CDEV_SUPPORT
-#endif
-#endif
-
-#include "gpio.h"
-
-/*********************************************************************************/
-/* Operations table and handle structure */
-/*********************************************************************************/
-
-struct gpio_ops {
- int (*read)(gpio_t *gpio, bool *value);
- int (*write)(gpio_t *gpio, bool value);
- int (*read_event)(gpio_t *gpio, gpio_edge_t *edge, uint64_t *timestamp);
- int (*poll)(gpio_t *gpio, int timeout_ms);
- int (*close)(gpio_t *gpio);
- int (*get_direction)(gpio_t *gpio, gpio_direction_t *direction);
- int (*get_edge)(gpio_t *gpio, gpio_edge_t *edge);
- int (*get_bias)(gpio_t *gpio, gpio_bias_t *bias);
- int (*get_drive)(gpio_t *gpio, gpio_drive_t *drive);
- int (*get_inverted)(gpio_t *gpio, bool *inverted);
- int (*set_direction)(gpio_t *gpio, gpio_direction_t direction);
- int (*set_edge)(gpio_t *gpio, gpio_edge_t edge);
- int (*set_bias)(gpio_t *gpio, gpio_bias_t bias);
- int (*set_drive)(gpio_t *gpio, gpio_drive_t drive);
- int (*set_inverted)(gpio_t *gpio, bool inverted);
- unsigned int (*line)(gpio_t *gpio);
- int (*fd)(gpio_t *gpio);
- int (*name)(gpio_t *gpio, char *str, size_t len);
- int (*label)(gpio_t *gpio, char *str, size_t len);
- int (*chip_fd)(gpio_t *gpio);
- int (*chip_name)(gpio_t *gpio, char *str, size_t len);
- int (*chip_label)(gpio_t *gpio, char *str, size_t len);
- int (*tostring)(gpio_t *gpio, char *str, size_t len);
-};
-
-struct gpio_handle {
- const struct gpio_ops *ops;
-
- union {
- struct {
- unsigned int line;
- int line_fd;
- int chip_fd;
- gpio_direction_t direction;
- gpio_edge_t edge;
- gpio_bias_t bias;
- gpio_drive_t drive;
- bool inverted;
- char label[32];
- } cdev;
- struct {
- unsigned int line;
- int line_fd;
- bool exported;
- } sysfs;
- } u;
-
- /* error state */
- struct {
- int c_errno;
- char errmsg[96];
- } error;
-};
-
-static const struct gpio_ops gpio_cdev_ops;
-static const struct gpio_ops gpio_sysfs_ops;
-
-/*********************************************************************************/
-/* Public interface, except for open()s */
-/*********************************************************************************/
-
-gpio_t *gpio_new(void) {
- gpio_t *gpio = calloc(1, sizeof(gpio_t));
- if (gpio == NULL)
- return NULL;
-
- gpio->ops = &gpio_cdev_ops;
- gpio->u.cdev.line_fd = -1;
- gpio->u.cdev.chip_fd = -1;
-
- return gpio;
-}
-
-void gpio_free(gpio_t *gpio) {
- free(gpio);
-}
-
-const char *gpio_errmsg(gpio_t *gpio) {
- return gpio->error.errmsg;
-}
-
-int gpio_errno(gpio_t *gpio) {
- return gpio->error.c_errno;
-}
-
-int gpio_read(gpio_t *gpio, bool *value) {
- return gpio->ops->read(gpio, value);
-}
-
-int gpio_write(gpio_t *gpio, bool value) {
- return gpio->ops->write(gpio, value);
-}
-
-int gpio_read_event(gpio_t *gpio, gpio_edge_t *edge, uint64_t *timestamp) {
- return gpio->ops->read_event(gpio, edge, timestamp);
-}
-
-int gpio_poll(gpio_t *gpio, int timeout_ms) {
- return gpio->ops->poll(gpio, timeout_ms);
-}
-
-int gpio_close(gpio_t *gpio) {
- return gpio->ops->close(gpio);
-}
-
-int gpio_get_direction(gpio_t *gpio, gpio_direction_t *direction) {
- return gpio->ops->get_direction(gpio, direction);
-}
-
-int gpio_get_edge(gpio_t *gpio, gpio_edge_t *edge) {
- return gpio->ops->get_edge(gpio, edge);
-}
-
-int gpio_get_bias(gpio_t *gpio, gpio_bias_t *bias) {
- return gpio->ops->get_bias(gpio, bias);
-}
-
-int gpio_get_drive(gpio_t *gpio, gpio_drive_t *drive) {
- return gpio->ops->get_drive(gpio, drive);
-}
-
-int gpio_get_inverted(gpio_t *gpio, bool *inverted) {
- return gpio->ops->get_inverted(gpio, inverted);
-}
-
-int gpio_set_direction(gpio_t *gpio, gpio_direction_t direction) {
- return gpio->ops->set_direction(gpio, direction);
-}
-
-int gpio_set_edge(gpio_t *gpio, gpio_edge_t edge) {
- return gpio->ops->set_edge(gpio, edge);
-}
-
-int gpio_set_bias(gpio_t *gpio, gpio_bias_t bias) {
- return gpio->ops->set_bias(gpio, bias);
-}
-
-int gpio_set_drive(gpio_t *gpio, gpio_drive_t drive) {
- return gpio->ops->set_drive(gpio, drive);
-}
-
-int gpio_set_inverted(gpio_t *gpio, bool inverted) {
- return gpio->ops->set_inverted(gpio, inverted);
-}
-
-unsigned int gpio_line(gpio_t *gpio) {
- return gpio->ops->line(gpio);
-}
-
-int gpio_fd(gpio_t *gpio) {
- return gpio->ops->fd(gpio);
-}
-
-int gpio_name(gpio_t *gpio, char *str, size_t len) {
- return gpio->ops->name(gpio, str, len);
-}
-
-int gpio_label(gpio_t *gpio, char *str, size_t len) {
- return gpio->ops->label(gpio, str, len);
-}
-
-int gpio_chip_fd(gpio_t *gpio) {
- return gpio->ops->chip_fd(gpio);
-}
-
-int gpio_chip_name(gpio_t *gpio, char *str, size_t len) {
- return gpio->ops->chip_name(gpio, str, len);
-}
-
-int gpio_chip_label(gpio_t *gpio, char *str, size_t len) {
- return gpio->ops->chip_label(gpio, str, len);
-}
-
-int gpio_tostring(gpio_t *gpio, char *str, size_t len) {
- return gpio->ops->tostring(gpio, str, len);
-}
-
-/*********************************************************************************/
-/* Common error formatting function */
-/*********************************************************************************/
-
-static int _gpio_error(gpio_t *gpio, int code, int c_errno, const char *fmt, ...) {
- va_list ap;
-
- gpio->error.c_errno = c_errno;
-
- va_start(ap, fmt);
- vsnprintf(gpio->error.errmsg, sizeof(gpio->error.errmsg), fmt, ap);
- va_end(ap);
-
- /* Tack on strerror() and errno */
- if (c_errno) {
- char buf[64];
- strerror_r(c_errno, buf, sizeof(buf));
- snprintf(gpio->error.errmsg+strlen(gpio->error.errmsg), sizeof(gpio->error.errmsg)-strlen(gpio->error.errmsg), ": %s [errno %d]", buf, c_errno);
- }
-
- return code;
-}
-
-/*********************************************************************************/
-/* GPIO Poll Multiple Implementation */
-/*********************************************************************************/
-
-int gpio_poll_multiple(gpio_t **gpios, size_t count, int timeout_ms, bool *gpios_ready) {
- struct pollfd fds[count];
- int ret;
-
- /* Setup pollfd structs */
- for (size_t i = 0; i < count; i++) {
- fds[i].fd = gpio_fd(gpios[i]);
- fds[i].events = (gpios[i]->ops == &gpio_sysfs_ops) ?
- (POLLPRI | POLLERR) : (POLLIN | POLLRDNORM);
- if (gpios_ready)
- gpios_ready[i] = false;
- }
-
- /* Poll */
- if ((ret = poll(fds, count, timeout_ms)) < 0)
- return GPIO_ERROR_IO;
-
- /* Event occurred */
- if (ret) {
- for (size_t i = 0; i < count; i++) {
- /* Set ready GPIOs */
- if (gpios_ready)
- gpios_ready[i] = fds[i].revents != 0;
-
- /* Rewind GPIO if it is a sysfs GPIO */
- if (gpios[i]->ops == &gpio_sysfs_ops) {
- if (lseek(gpios[i]->u.sysfs.line_fd, 0, SEEK_SET) < 0)
- return GPIO_ERROR_IO;
- }
- }
-
- return ret;
- }
-
- /* Timed out */
- return 0;
-}
-
-/*********************************************************************************/
-/* sysfs implementation */
-/*********************************************************************************/
-
-#define P_PATH_MAX 256
-
-/* Delay between checks for successful GPIO export (100ms) */
-#define GPIO_SYSFS_OPEN_DELAY 100000
-/* Number of retries to check for successful GPIO exports */
-#define GPIO_SYSFS_OPEN_RETRIES 10
-
-static int gpio_sysfs_close(gpio_t *gpio) {
- char buf[16];
- int len, fd;
-
- if (gpio->u.sysfs.line_fd < 0)
- return 0;
-
- /* Close fd */
- if (close(gpio->u.sysfs.line_fd) < 0)
- return _gpio_error(gpio, GPIO_ERROR_CLOSE, errno, "Closing GPIO 'value'");
-
- gpio->u.sysfs.line_fd = -1;
-
- /* Unexport the GPIO, if we exported it */
- if (gpio->u.sysfs.exported) {
- len = snprintf(buf, sizeof(buf), "%u\n", gpio->u.sysfs.line);
-
- if ((fd = open("/sys/class/gpio/unexport", O_WRONLY)) < 0)
- return _gpio_error(gpio, GPIO_ERROR_CLOSE, errno, "Closing GPIO: opening 'unexport'");
-
- if (write(fd, buf, len) < 0) {
- int errsv = errno;
- close(fd);
- return _gpio_error(gpio, GPIO_ERROR_CLOSE, errsv, "Closing GPIO: writing 'unexport'");
- }
-
- if (close(fd) < 0)
- return _gpio_error(gpio, GPIO_ERROR_CLOSE, errno, "Closing GPIO: closing 'unexport'");
-
- gpio->u.sysfs.exported = false;
- }
-
- return 0;
-}
-
-static int gpio_sysfs_read(gpio_t *gpio, bool *value) {
- char buf[2];
-
- /* Read fd */
- if (read(gpio->u.sysfs.line_fd, buf, 2) < 0)
- return _gpio_error(gpio, GPIO_ERROR_IO, errno, "Reading GPIO 'value'");
-
- /* Rewind */
- if (lseek(gpio->u.sysfs.line_fd, 0, SEEK_SET) < 0)
- return _gpio_error(gpio, GPIO_ERROR_IO, errno, "Rewinding GPIO 'value'");
-
- if (buf[0] == '0')
- *value = false;
- else if (buf[0] == '1')
- *value = true;
- else
- return _gpio_error(gpio, GPIO_ERROR_IO, 0, "Unknown GPIO value");
-
- return 0;
-}
-
-static int gpio_sysfs_write(gpio_t *gpio, bool value) {
- static const char *value_str[2] = {"0\n", "1\n"};
-
- /* Write fd */
- if (write(gpio->u.sysfs.line_fd, value_str[value], 2) < 0)
- return _gpio_error(gpio, GPIO_ERROR_IO, errno, "Writing GPIO 'value'");
-
- /* Rewind */
- if (lseek(gpio->u.sysfs.line_fd, 0, SEEK_SET) < 0)
- return _gpio_error(gpio, GPIO_ERROR_IO, errno, "Rewinding GPIO 'value'");
-
- return 0;
-}
-
-static int gpio_sysfs_read_event(gpio_t *gpio, gpio_edge_t *edge, uint64_t *timestamp) {
- (void)edge;
- (void)timestamp;
- return _gpio_error(gpio, GPIO_ERROR_UNSUPPORTED, 0, "GPIO of type sysfs does not support read event");
-}
-
-static int gpio_sysfs_poll(gpio_t *gpio, int timeout_ms) {
- struct pollfd fds[1];
- int ret;
-
- /* Poll */
- fds[0].fd = gpio->u.sysfs.line_fd;
- fds[0].events = POLLPRI | POLLERR;
- if ((ret = poll(fds, 1, timeout_ms)) < 0)
- return _gpio_error(gpio, GPIO_ERROR_IO, errno, "Polling GPIO 'value'");
-
- /* GPIO edge interrupt occurred */
- if (ret) {
- /* Rewind */
- if (lseek(gpio->u.sysfs.line_fd, 0, SEEK_SET) < 0)
- return _gpio_error(gpio, GPIO_ERROR_IO, errno, "Rewinding GPIO 'value'");
-
- return 1;
- }
-
- /* Timed out */
- return 0;
-}
-
-static int gpio_sysfs_set_direction(gpio_t *gpio, gpio_direction_t direction) {
- char gpio_path[P_PATH_MAX];
- const char *buf;
- int fd;
-
- if (direction == GPIO_DIR_IN)
- buf = "in\n";
- else if (direction == GPIO_DIR_OUT)
- buf = "out\n";
- else if (direction == GPIO_DIR_OUT_LOW)
- buf = "low\n";
- else if (direction == GPIO_DIR_OUT_HIGH)
- buf = "high\n";
- else
- return _gpio_error(gpio, GPIO_ERROR_ARG, 0, "Invalid GPIO direction (can be in, out, low, high)");
-
- /* Write direction */
- snprintf(gpio_path, sizeof(gpio_path), "/sys/class/gpio/gpio%u/direction", gpio->u.sysfs.line);
-
- if ((fd = open(gpio_path, O_WRONLY)) < 0)
- return _gpio_error(gpio, GPIO_ERROR_CONFIGURE, errno, "Opening GPIO 'direction'");
-
- if (write(fd, buf, strlen(buf)) < 0) {
- int errsv = errno;
- close(fd);
- return _gpio_error(gpio, GPIO_ERROR_CONFIGURE, errsv, "Writing GPIO 'direction'");
- }
-
- if (close(fd) < 0)
- return _gpio_error(gpio, GPIO_ERROR_CONFIGURE, errno, "Closing GPIO 'direction'");
-
- return 0;
-}
-
-static int gpio_sysfs_get_direction(gpio_t *gpio, gpio_direction_t *direction) {
- char gpio_path[P_PATH_MAX];
- char buf[8];
- int fd, ret;
-
- /* Read direction */
- snprintf(gpio_path, sizeof(gpio_path), "/sys/class/gpio/gpio%u/direction", gpio->u.sysfs.line);
-
- if ((fd = open(gpio_path, O_RDONLY)) < 0)
- return _gpio_error(gpio, GPIO_ERROR_QUERY, errno, "Opening GPIO 'direction'");
-
- if ((ret = read(fd, buf, sizeof(buf))) < 0) {
- int errsv = errno;
- close(fd);
- return _gpio_error(gpio, GPIO_ERROR_QUERY, errsv, "Reading GPIO 'direction'");
- }
-
- if (close(fd) < 0)
- return _gpio_error(gpio, GPIO_ERROR_QUERY, errno, "Closing GPIO 'direction'");
-
- buf[ret] = '\0';
-
- if (strcmp(buf, "in\n") == 0)
- *direction = GPIO_DIR_IN;
- else if (strcmp(buf, "out\n") == 0)
- *direction = GPIO_DIR_OUT;
- else
- return _gpio_error(gpio, GPIO_ERROR_QUERY, 0, "Unknown GPIO direction");
-
- return 0;
-}
-
-static int gpio_sysfs_set_edge(gpio_t *gpio, gpio_edge_t edge) {
- char gpio_path[P_PATH_MAX];
- const char *buf;
- int fd;
-
- if (edge == GPIO_EDGE_NONE)
- buf = "none\n";
- else if (edge == GPIO_EDGE_RISING)
- buf = "rising\n";
- else if (edge == GPIO_EDGE_FALLING)
- buf = "falling\n";
- else if (edge == GPIO_EDGE_BOTH)
- buf = "both\n";
- else
- return _gpio_error(gpio, GPIO_ERROR_ARG, 0, "Invalid GPIO interrupt edge (can be none, rising, falling, both)");
-
- /* Write edge */
- snprintf(gpio_path, sizeof(gpio_path), "/sys/class/gpio/gpio%u/edge", gpio->u.sysfs.line);
-
- if ((fd = open(gpio_path, O_WRONLY)) < 0)
- return _gpio_error(gpio, GPIO_ERROR_CONFIGURE, errno, "Opening GPIO 'edge'");
-
- if (write(fd, buf, strlen(buf)) < 0) {
- int errsv = errno;
- close(fd);
- return _gpio_error(gpio, GPIO_ERROR_CONFIGURE, errsv, "Writing GPIO 'edge'");
- }
-
- if (close(fd) < 0)
- return _gpio_error(gpio, GPIO_ERROR_CONFIGURE, errno, "Closing GPIO 'edge'");
-
- return 0;
-}
-
-static int gpio_sysfs_get_edge(gpio_t *gpio, gpio_edge_t *edge) {
- char gpio_path[P_PATH_MAX];
- char buf[16];
- int fd, ret;
-
- /* Read edge */
- snprintf(gpio_path, sizeof(gpio_path), "/sys/class/gpio/gpio%u/edge", gpio->u.sysfs.line);
-
- if ((fd = open(gpio_path, O_RDONLY)) < 0)
- return _gpio_error(gpio, GPIO_ERROR_QUERY, errno, "Opening GPIO 'edge'");
-
- if ((ret = read(fd, buf, sizeof(buf))) < 0) {
- int errsv = errno;
- close(fd);
- return _gpio_error(gpio, GPIO_ERROR_QUERY, errsv, "Reading GPIO 'edge'");
- }
-
- if (close(fd) < 0)
- return _gpio_error(gpio, GPIO_ERROR_QUERY, errno, "Closing GPIO 'edge'");
-
- buf[ret] = '\0';
-
- if (strcmp(buf, "none\n") == 0)
- *edge = GPIO_EDGE_NONE;
- else if (strcmp(buf, "rising\n") == 0)
- *edge = GPIO_EDGE_RISING;
- else if (strcmp(buf, "falling\n") == 0)
- *edge = GPIO_EDGE_FALLING;
- else if (strcmp(buf, "both\n") == 0)
- *edge = GPIO_EDGE_BOTH;
- else
- return _gpio_error(gpio, GPIO_ERROR_QUERY, 0, "Unknown GPIO edge");
-
- return 0;
-}
-
-static int gpio_sysfs_set_bias(gpio_t *gpio, gpio_bias_t bias) {
- (void)bias;
- return _gpio_error(gpio, GPIO_ERROR_UNSUPPORTED, 0, "GPIO of type sysfs does not support line bias attribute");
-}
-
-static int gpio_sysfs_get_bias(gpio_t *gpio, gpio_bias_t *bias) {
- (void)bias;
- return _gpio_error(gpio, GPIO_ERROR_UNSUPPORTED, 0, "GPIO of type sysfs does not support line bias attribute");
-}
-
-static int gpio_sysfs_set_drive(gpio_t *gpio, gpio_drive_t drive) {
- (void)drive;
- return _gpio_error(gpio, GPIO_ERROR_UNSUPPORTED, 0, "GPIO of type sysfs does not support line drive attribute");
-}
-
-static int gpio_sysfs_get_drive(gpio_t *gpio, gpio_drive_t *drive) {
- (void)drive;
- return _gpio_error(gpio, GPIO_ERROR_UNSUPPORTED, 0, "GPIO of type sysfs does not support line drive attribute");
-}
-
-static int gpio_sysfs_set_inverted(gpio_t *gpio, bool inverted) {
- char gpio_path[P_PATH_MAX];
- static const char *inverted_str[2] = {"0\n", "1\n"};
- int fd;
-
- /* Write active_low */
- snprintf(gpio_path, sizeof(gpio_path), "/sys/class/gpio/gpio%u/active_low", gpio->u.sysfs.line);
-
- if ((fd = open(gpio_path, O_WRONLY)) < 0)
- return _gpio_error(gpio, GPIO_ERROR_CONFIGURE, errno, "Opening GPIO 'active_low'");
-
- if (write(fd, inverted_str[inverted], strlen(inverted_str[inverted])) < 0) {
- int errsv = errno;
- close(fd);
- return _gpio_error(gpio, GPIO_ERROR_CONFIGURE, errsv, "Writing GPIO 'active_low'");
- }
-
- if (close(fd) < 0)
- return _gpio_error(gpio, GPIO_ERROR_CONFIGURE, errno, "Closing GPIO 'active_low'");
-
- return 0;
-}
-
-static int gpio_sysfs_get_inverted(gpio_t *gpio, bool *inverted) {
- char gpio_path[P_PATH_MAX];
- char buf[4];
- int fd, ret;
-
- /* Read active_low */
- snprintf(gpio_path, sizeof(gpio_path), "/sys/class/gpio/gpio%u/active_low", gpio->u.sysfs.line);
-
- if ((fd = open(gpio_path, O_RDONLY)) < 0)
- return _gpio_error(gpio, GPIO_ERROR_QUERY, errno, "Opening GPIO 'active_low'");
-
- if ((ret = read(fd, buf, sizeof(buf))) < 0) {
- int errsv = errno;
- close(fd);
- return _gpio_error(gpio, GPIO_ERROR_QUERY, errsv, "Reading GPIO 'active_low'");
- }
-
- if (close(fd) < 0)
- return _gpio_error(gpio, GPIO_ERROR_QUERY, errno, "Closing GPIO 'active_low'");
-
- buf[ret] = '\0';
-
- if (buf[0] == '0')
- *inverted = false;
- else if (buf[0] == '1')
- *inverted = true;
- else
- return _gpio_error(gpio, GPIO_ERROR_QUERY, 0, "Unknown GPIO active_low value");
-
- return 0;
-}
-
-static unsigned int gpio_sysfs_line(gpio_t *gpio) {
- return gpio->u.sysfs.line;
-}
-
-static int gpio_sysfs_fd(gpio_t *gpio) {
- return gpio->u.sysfs.line_fd;
-}
-
-static int gpio_sysfs_name(gpio_t *gpio, char *str, size_t len) {
- (void)gpio;
- if (len)
- str[0] = '\0';
-
- return 0;
-}
-
-static int gpio_sysfs_label(gpio_t *gpio, char *str, size_t len) {
- (void)gpio;
- if (len)
- str[0] = '\0';
-
- return 0;
-}
-
-static int gpio_sysfs_chip_fd(gpio_t *gpio) {
- return _gpio_error(gpio, GPIO_ERROR_UNSUPPORTED, 0, "GPIO of type sysfs has no chip fd");
-}
-
-static int gpio_sysfs_chip_name(gpio_t *gpio, char *str, size_t len) {
- int ret;
- char gpio_path[P_PATH_MAX];
- char gpiochip_path[P_PATH_MAX];
-
- if (!len)
- return 0;
-
- /* Form path to device */
- snprintf(gpio_path, sizeof(gpio_path), "/sys/class/gpio/gpio%u/device", gpio->u.sysfs.line);
-
- /* Resolve symlink to gpiochip */
- if ((ret = readlink(gpio_path, gpiochip_path, sizeof(gpiochip_path))) < 0)
- return _gpio_error(gpio, GPIO_ERROR_QUERY, errno, "Reading GPIO chip symlink");
-
- /* Null-terminate symlink path */
- gpiochip_path[(ret < P_PATH_MAX) ? ret : (P_PATH_MAX - 1)] = '\0';
-
- /* Find last / in symlink path */
- const char *sep = strrchr(gpiochip_path, '/');
- if (!sep)
- return _gpio_error(gpio, GPIO_ERROR_QUERY, 0, "Invalid GPIO chip symlink");
-
- strncpy(str, sep + 1, len - 1);
- str[len - 1] = '\0';
-
- return 0;
-}
-
-static int gpio_sysfs_chip_label(gpio_t *gpio, char *str, size_t len) {
- char gpio_path[P_PATH_MAX];
- char chip_name[32];
- int fd, ret;
-
- if (!len)
- return 0;
-
- if ((ret = gpio_sysfs_chip_name(gpio, chip_name, sizeof(chip_name))) < 0)
- return ret;
-
- /* Read gpiochip label */
- snprintf(gpio_path, sizeof(gpio_path), "/sys/class/gpio/%s/label", chip_name);
-
- if ((fd = open(gpio_path, O_RDONLY)) < 0)
- return _gpio_error(gpio, GPIO_ERROR_QUERY, errno, "Opening GPIO chip 'label'");
-
- if ((ret = read(fd, str, len)) < 0) {
- int errsv = errno;
- close(fd);
- return _gpio_error(gpio, GPIO_ERROR_QUERY, errsv, "Reading GPIO chip 'label'");
- }
-
- if (close(fd) < 0)
- return _gpio_error(gpio, GPIO_ERROR_QUERY, errno, "Closing GPIO 'label'");
-
- str[ret - 1] = '\0';
-
- return 0;
-}
-
-static int gpio_sysfs_tostring(gpio_t *gpio, char *str, size_t len) {
- gpio_direction_t direction;
- const char *direction_str;
- gpio_edge_t edge;
- const char *edge_str;
- bool inverted;
- const char *inverted_str;
- char chip_name[32];
- const char *chip_name_str;
- char chip_label[32];
- const char *chip_label_str;
-
- if (gpio_sysfs_get_direction(gpio, &direction) < 0)
- direction_str = "";
- else
- direction_str = (direction == GPIO_DIR_IN) ? "in" :
- (direction == GPIO_DIR_OUT) ? "out" : "unknown";
-
- if (gpio_sysfs_get_edge(gpio, &edge) < 0)
- edge_str = "";
- else
- edge_str = (edge == GPIO_EDGE_NONE) ? "none" :
- (edge == GPIO_EDGE_RISING) ? "rising" :
- (edge == GPIO_EDGE_FALLING) ? "falling" :
- (edge == GPIO_EDGE_BOTH) ? "both" : "unknown";
-
- if (gpio_sysfs_get_inverted(gpio, &inverted) < 0)
- inverted_str = "";
- else
- inverted_str = inverted ? "true" : "false";
-
- if (gpio_sysfs_chip_name(gpio, chip_name, sizeof(chip_name)) < 0)
- chip_name_str = "";
- else
- chip_name_str = chip_name;
-
- if (gpio_sysfs_chip_label(gpio, chip_label, sizeof(chip_label)) < 0)
- chip_label_str = "";
- else
- chip_label_str = chip_label;
-
- return snprintf(str, len, "GPIO %u (fd=%d, direction=%s, edge=%s, inverted=%s, chip_name=\"%s\", chip_label=\"%s\", type=sysfs)",
- gpio->u.sysfs.line, gpio->u.sysfs.line_fd, direction_str, edge_str, inverted_str, chip_name_str, chip_label_str);
-}
-
-static const struct gpio_ops gpio_sysfs_ops = {
- .read = gpio_sysfs_read,
- .write = gpio_sysfs_write,
- .read_event = gpio_sysfs_read_event,
- .poll = gpio_sysfs_poll,
- .close = gpio_sysfs_close,
- .get_direction = gpio_sysfs_get_direction,
- .get_edge = gpio_sysfs_get_edge,
- .get_bias = gpio_sysfs_get_bias,
- .get_drive = gpio_sysfs_get_drive,
- .get_inverted = gpio_sysfs_get_inverted,
- .set_direction = gpio_sysfs_set_direction,
- .set_edge = gpio_sysfs_set_edge,
- .set_bias = gpio_sysfs_set_bias,
- .set_drive = gpio_sysfs_set_drive,
- .set_inverted = gpio_sysfs_set_inverted,
- .line = gpio_sysfs_line,
- .fd = gpio_sysfs_fd,
- .name = gpio_sysfs_name,
- .label = gpio_sysfs_label,
- .chip_fd = gpio_sysfs_chip_fd,
- .chip_name = gpio_sysfs_chip_name,
- .chip_label = gpio_sysfs_chip_label,
- .tostring = gpio_sysfs_tostring,
-};
-
-int gpio_open_sysfs(gpio_t *gpio, unsigned int line, gpio_direction_t direction) {
- char gpio_path[P_PATH_MAX];
- struct stat stat_buf;
- char buf[16];
- int len, fd, ret;
- bool exported = false;
-
- if (direction != GPIO_DIR_IN && direction != GPIO_DIR_OUT && direction != GPIO_DIR_OUT_LOW && direction != GPIO_DIR_OUT_HIGH)
- return _gpio_error(gpio, GPIO_ERROR_ARG, 0, "Invalid GPIO direction (can be in, out, low, high)");
-
- /* Check if GPIO directory exists */
- snprintf(gpio_path, sizeof(gpio_path), "/sys/class/gpio/gpio%u", line);
- if (stat(gpio_path, &stat_buf) < 0) {
- /* Write line number to export file */
- len = snprintf(buf, sizeof(buf), "%u\n", line);
-
- if ((fd = open("/sys/class/gpio/export", O_WRONLY)) < 0)
- return _gpio_error(gpio, GPIO_ERROR_OPEN, errno, "Opening GPIO: opening 'export'");
-
- if (write(fd, buf, len) < 0) {
- int errsv = errno;
- close(fd);
- return _gpio_error(gpio, GPIO_ERROR_OPEN, errsv, "Opening GPIO: writing 'export'");
- }
-
- if (close(fd) < 0)
- return _gpio_error(gpio, GPIO_ERROR_OPEN, errno, "Opening GPIO: closing 'export'");
-
- /* Wait until GPIO directory appears */
- unsigned int retry_count;
- for (retry_count = 0; retry_count < GPIO_SYSFS_OPEN_RETRIES; retry_count++) {
- int ret = stat(gpio_path, &stat_buf);
- if (ret == 0) {
- exported = true;
- break;
- } else if (ret < 0 && errno != ENOENT) {
- return _gpio_error(gpio, GPIO_ERROR_OPEN, errno, "Opening GPIO: stat 'gpio%u/' after export", line);
- }
-
- usleep(GPIO_SYSFS_OPEN_DELAY);
- }
-
- if (retry_count == GPIO_SYSFS_OPEN_RETRIES)
- return _gpio_error(gpio, GPIO_ERROR_OPEN, 0, "Opening GPIO: waiting for 'gpio%u/' timed out", line);
-
- /* Write direction, looping in case of EACCES errors due to delayed
- * udev permission rule application after export */
- const char *dir = (direction == GPIO_DIR_OUT) ? "out\n" :
- (direction == GPIO_DIR_OUT_HIGH) ? "high\n" :
- (direction == GPIO_DIR_OUT_LOW) ? "low\n" : "in\n";
-
- snprintf(gpio_path, sizeof(gpio_path), "/sys/class/gpio/gpio%u/direction", line);
-
- for (retry_count = 0; retry_count < GPIO_SYSFS_OPEN_RETRIES; retry_count++) {
- if ((fd = open(gpio_path, O_WRONLY)) >= 0) {
- if (write(fd, dir, strlen(dir)) < 0) {
- int errsv = errno;
- close(fd);
- return _gpio_error(gpio, GPIO_ERROR_CONFIGURE, errsv, "Writing GPIO 'direction'");
- }
-
- if (close(fd) < 0)
- return _gpio_error(gpio, GPIO_ERROR_CONFIGURE, errno, "Closing GPIO 'direction'");
-
- break;
- } else if (errno != EACCES) {
- return _gpio_error(gpio, GPIO_ERROR_OPEN, errno, "Opening GPIO: opening 'gpio%u/direction'", line);
- }
-
- usleep(GPIO_SYSFS_OPEN_DELAY);
- }
-
- if (retry_count == GPIO_SYSFS_OPEN_RETRIES)
- return _gpio_error(gpio, GPIO_ERROR_OPEN, errno, "Opening GPIO: opening 'gpio%u/direction'", line);
- }
-
- /* Open value */
- snprintf(gpio_path, sizeof(gpio_path), "/sys/class/gpio/gpio%u/value", line);
- if ((fd = open(gpio_path, O_RDWR)) < 0)
- return _gpio_error(gpio, GPIO_ERROR_OPEN, errno, "Opening GPIO 'gpio%u/value'", line);
-
- memset(gpio, 0, sizeof(gpio_t));
- gpio->ops = &gpio_sysfs_ops;
- gpio->u.sysfs.line = line;
- gpio->u.sysfs.line_fd = fd;
- gpio->u.sysfs.exported = exported;
-
- if (!exported) {
- ret = gpio_sysfs_set_direction(gpio, direction);
- if (ret < 0)
- return ret;
- }
-
- ret = gpio_sysfs_set_inverted(gpio, false);
- if (ret < 0)
- return ret;
-
- return 0;
-}
-
-/*********************************************************************************/
-/* cdev implementation */
-/*********************************************************************************/
-
-#if PERIPHERY_GPIO_CDEV_SUPPORT
-
-static int _gpio_cdev_reopen(gpio_t *gpio, gpio_direction_t direction, gpio_edge_t edge, gpio_bias_t bias, gpio_drive_t drive, bool inverted) {
- uint32_t flags = 0;
-
- #ifdef GPIOHANDLE_REQUEST_BIAS_PULL_UP
- if (bias == GPIO_BIAS_PULL_UP)
- flags |= GPIOHANDLE_REQUEST_BIAS_PULL_UP;
- else if (bias == GPIO_BIAS_PULL_DOWN)
- flags |= GPIOHANDLE_REQUEST_BIAS_PULL_DOWN;
- else if (bias == GPIO_BIAS_DISABLE)
- flags |= GPIOHANDLE_REQUEST_BIAS_DISABLE;
- #else
- if (bias != GPIO_BIAS_DEFAULT)
- return _gpio_error(gpio, GPIO_ERROR_UNSUPPORTED, 0, "Kernel version does not support configuring GPIO line bias");
- #endif
-
- #ifdef GPIOHANDLE_REQUEST_OPEN_DRAIN
- if (drive == GPIO_DRIVE_OPEN_DRAIN)
- flags |= GPIOHANDLE_REQUEST_OPEN_DRAIN;
- else if (drive == GPIO_DRIVE_OPEN_SOURCE)
- flags |= GPIOHANDLE_REQUEST_OPEN_SOURCE;
- #else
- if (drive != GPIO_DRIVE_DEFAULT)
- return _gpio_error(gpio, GPIO_ERROR_UNSUPPORTED, 0, "Kernel version does not support configuring GPIO line drive");
- #endif
-
- if (inverted)
- flags |= GPIOHANDLE_REQUEST_ACTIVE_LOW;
-
- /* FIXME this should really use GPIOHANDLE_SET_CONFIG_IOCTL instead of
- * closing and reopening, especially to preserve output value on
- * configuration changes */
-
- if (gpio->u.cdev.line_fd >= 0) {
- if (close(gpio->u.cdev.line_fd) < 0)
- return _gpio_error(gpio, GPIO_ERROR_CLOSE, errno, "Closing GPIO line");
-
- gpio->u.cdev.line_fd = -1;
- }
-
- if (direction == GPIO_DIR_IN) {
- if (edge == GPIO_EDGE_NONE) {
- struct gpiohandle_request request = {0};
-
- request.lineoffsets[0] = gpio->u.cdev.line;
- request.flags = flags | GPIOHANDLE_REQUEST_INPUT;
- strncpy(request.consumer_label, gpio->u.cdev.label, sizeof(request.consumer_label) - 1);
- request.consumer_label[sizeof(request.consumer_label) - 1] = '\0';
- request.lines = 1;
-
- if (ioctl(gpio->u.cdev.chip_fd, GPIO_GET_LINEHANDLE_IOCTL, &request) < 0)
- return _gpio_error(gpio, GPIO_ERROR_OPEN, errno, "Opening input line handle");
-
- gpio->u.cdev.line_fd = request.fd;
- } else {
- struct gpioevent_request request = {0};
-
- request.lineoffset = gpio->u.cdev.line;
- request.handleflags = flags | GPIOHANDLE_REQUEST_INPUT;
- request.eventflags = (edge == GPIO_EDGE_RISING) ? GPIOEVENT_REQUEST_RISING_EDGE :
- (edge == GPIO_EDGE_FALLING) ? GPIOEVENT_REQUEST_FALLING_EDGE :
- GPIOEVENT_REQUEST_BOTH_EDGES;
- strncpy(request.consumer_label, gpio->u.cdev.label, sizeof(request.consumer_label) - 1);
- request.consumer_label[sizeof(request.consumer_label) - 1] = '\0';
-
- if (ioctl(gpio->u.cdev.chip_fd, GPIO_GET_LINEEVENT_IOCTL, &request) < 0)
- return _gpio_error(gpio, GPIO_ERROR_OPEN, errno, "Opening input event line handle");
-
- gpio->u.cdev.line_fd = request.fd;
- }
- } else {
- struct gpiohandle_request request = {0};
- bool initial_value = (direction == GPIO_DIR_OUT_HIGH) ? true : false;
- initial_value ^= inverted;
-
- request.lineoffsets[0] = gpio->u.cdev.line;
- request.flags = flags | GPIOHANDLE_REQUEST_OUTPUT;
- request.default_values[0] = initial_value;
- strncpy(request.consumer_label, gpio->u.cdev.label, sizeof(request.consumer_label) - 1);
- request.consumer_label[sizeof(request.consumer_label) - 1] = '\0';
- request.lines = 1;
-
- if (ioctl(gpio->u.cdev.chip_fd, GPIO_GET_LINEHANDLE_IOCTL, &request) < 0)
- return _gpio_error(gpio, GPIO_ERROR_OPEN, errno, "Opening output line handle");
-
- gpio->u.cdev.line_fd = request.fd;
- }
-
- gpio->u.cdev.direction = (direction == GPIO_DIR_IN) ? GPIO_DIR_IN : GPIO_DIR_OUT;
- gpio->u.cdev.edge = edge;
- gpio->u.cdev.bias = bias;
- gpio->u.cdev.drive = drive;
- gpio->u.cdev.inverted = inverted;
-
- return 0;
-}
-
-static int gpio_cdev_read(gpio_t *gpio, bool *value) {
- struct gpiohandle_data data = {0};
-
- if (ioctl(gpio->u.cdev.line_fd, GPIOHANDLE_GET_LINE_VALUES_IOCTL, &data) < 0)
- return _gpio_error(gpio, GPIO_ERROR_IO, errno, "Getting line value");
-
- *value = data.values[0];
-
- return 0;
-}
-
-static int gpio_cdev_write(gpio_t *gpio, bool value) {
- struct gpiohandle_data data = {0};
-
- if (gpio->u.cdev.direction != GPIO_DIR_OUT)
- return _gpio_error(gpio, GPIO_ERROR_INVALID_OPERATION, 0, "Invalid operation: cannot write to input GPIO");
-
- data.values[0] = value;
-
- if (ioctl(gpio->u.cdev.line_fd, GPIOHANDLE_SET_LINE_VALUES_IOCTL, &data) < 0)
- return _gpio_error(gpio, GPIO_ERROR_IO, errno, "Setting line value");
-
- return 0;
-}
-
-static int gpio_cdev_read_event(gpio_t *gpio, gpio_edge_t *edge, uint64_t *timestamp) {
- struct gpioevent_data event_data = {0};
-
- if (gpio->u.cdev.direction != GPIO_DIR_IN)
- return _gpio_error(gpio, GPIO_ERROR_INVALID_OPERATION, 0, "Invalid operation: cannot read event of output GPIO");
- else if (gpio->u.cdev.edge == GPIO_EDGE_NONE)
- return _gpio_error(gpio, GPIO_ERROR_INVALID_OPERATION, 0, "Invalid operation: GPIO edge not set");
-
- if (read(gpio->u.cdev.line_fd, &event_data, sizeof(event_data)) < (ssize_t)sizeof(event_data))
- return _gpio_error(gpio, GPIO_ERROR_IO, errno, "Reading GPIO event");
-
- if (edge)
- *edge = (event_data.id == GPIOEVENT_EVENT_RISING_EDGE) ? GPIO_EDGE_RISING :
- (event_data.id == GPIOEVENT_EVENT_FALLING_EDGE) ? GPIO_EDGE_FALLING : GPIO_EDGE_NONE;
- if (timestamp)
- *timestamp = event_data.timestamp;
-
- return 0;
-}
-
-static int gpio_cdev_poll(gpio_t *gpio, int timeout_ms) {
- struct pollfd fds[1];
- int ret;
-
- if (gpio->u.cdev.direction != GPIO_DIR_IN)
- return _gpio_error(gpio, GPIO_ERROR_INVALID_OPERATION, 0, "Invalid operation: cannot poll output GPIO");
-
- fds[0].fd = gpio->u.cdev.line_fd;
- fds[0].events = POLLIN | POLLPRI | POLLERR;
- if ((ret = poll(fds, 1, timeout_ms)) < 0)
- return _gpio_error(gpio, GPIO_ERROR_IO, errno, "Polling GPIO line");
-
- return ret > 0;
-}
-
-static int gpio_cdev_close(gpio_t *gpio) {
- /* Close line fd */
- if (gpio->u.cdev.line_fd >= 0) {
- if (close(gpio->u.cdev.line_fd) < 0)
- return _gpio_error(gpio, GPIO_ERROR_CLOSE, errno, "Closing GPIO line");
-
- gpio->u.cdev.line_fd = -1;
- }
-
- /* Close chip fd */
- if (gpio->u.cdev.chip_fd >= 0) {
- if (close(gpio->u.cdev.chip_fd) < 0)
- return _gpio_error(gpio, GPIO_ERROR_CLOSE, errno, "Closing GPIO chip");
-
- gpio->u.cdev.chip_fd = -1;
- }
-
- gpio->u.cdev.edge = GPIO_EDGE_NONE;
- gpio->u.cdev.direction = GPIO_DIR_IN;
-
- return 0;
-}
-
-static int gpio_cdev_get_direction(gpio_t *gpio, gpio_direction_t *direction) {
- *direction = gpio->u.cdev.direction;
- return 0;
-}
-
-static int gpio_cdev_get_edge(gpio_t *gpio, gpio_edge_t *edge) {
- *edge = gpio->u.cdev.edge;
- return 0;
-}
-
-static int gpio_cdev_get_bias(gpio_t *gpio, gpio_bias_t *bias) {
- *bias = gpio->u.cdev.bias;
- return 0;
-}
-
-static int gpio_cdev_get_drive(gpio_t *gpio, gpio_drive_t *drive) {
- *drive = gpio->u.cdev.drive;
- return 0;
-}
-
-static int gpio_cdev_get_inverted(gpio_t *gpio, bool *inverted) {
- *inverted = gpio->u.cdev.inverted;
- return 0;
-}
-
-static int gpio_cdev_set_direction(gpio_t *gpio, gpio_direction_t direction) {
- if (direction != GPIO_DIR_IN && direction != GPIO_DIR_OUT && direction != GPIO_DIR_OUT_LOW && direction != GPIO_DIR_OUT_HIGH)
- return _gpio_error(gpio, GPIO_ERROR_ARG, 0, "Invalid GPIO direction (can be in, out, low, high)");
-
- if (gpio->u.cdev.direction == direction)
- return 0;
-
- return _gpio_cdev_reopen(gpio, direction, GPIO_EDGE_NONE, gpio->u.cdev.bias, gpio->u.cdev.drive, gpio->u.cdev.inverted);
-}
-
-static int gpio_cdev_set_edge(gpio_t *gpio, gpio_edge_t edge) {
- if (edge != GPIO_EDGE_NONE && edge != GPIO_EDGE_RISING && edge != GPIO_EDGE_FALLING && edge != GPIO_EDGE_BOTH)
- return _gpio_error(gpio, GPIO_ERROR_ARG, 0, "Invalid GPIO interrupt edge (can be none, rising, falling, both)");
-
- if (gpio->u.cdev.direction != GPIO_DIR_IN)
- return _gpio_error(gpio, GPIO_ERROR_INVALID_OPERATION, 0, "Invalid operation: cannot set edge on output GPIO");
-
- if (gpio->u.cdev.edge == edge)
- return 0;
-
- return _gpio_cdev_reopen(gpio, gpio->u.cdev.direction, edge, gpio->u.cdev.bias, gpio->u.cdev.drive, gpio->u.cdev.inverted);
-}
-
-static int gpio_cdev_set_bias(gpio_t *gpio, gpio_bias_t bias) {
- if (bias != GPIO_BIAS_DEFAULT && bias != GPIO_BIAS_PULL_UP && bias != GPIO_BIAS_PULL_DOWN && bias != GPIO_BIAS_DISABLE)
- return _gpio_error(gpio, GPIO_ERROR_ARG, 0, "Invalid GPIO line bias (can be default, pull_up, pull_down, disable)");
-
- if (gpio->u.cdev.bias == bias)
- return 0;
-
- return _gpio_cdev_reopen(gpio, gpio->u.cdev.direction, gpio->u.cdev.edge, bias, gpio->u.cdev.drive, gpio->u.cdev.inverted);
-}
-
-static int gpio_cdev_set_drive(gpio_t *gpio, gpio_drive_t drive) {
- if (drive != GPIO_DRIVE_DEFAULT && drive != GPIO_DRIVE_OPEN_DRAIN && drive != GPIO_DRIVE_OPEN_SOURCE)
- return _gpio_error(gpio, GPIO_ERROR_ARG, 0, "Invalid GPIO line drive (can be default, open_drain, open_source)");
-
- if (gpio->u.cdev.direction != GPIO_DIR_OUT && drive != GPIO_DRIVE_DEFAULT)
- return _gpio_error(gpio, GPIO_ERROR_INVALID_OPERATION, 0, "Invalid operation: cannot set line drive on input GPIO");
-
- if (gpio->u.cdev.drive == drive)
- return 0;
-
- return _gpio_cdev_reopen(gpio, gpio->u.cdev.direction, gpio->u.cdev.edge, gpio->u.cdev.bias, drive, gpio->u.cdev.inverted);
-}
-
-static int gpio_cdev_set_inverted(gpio_t *gpio, bool inverted) {
- if (gpio->u.cdev.inverted == inverted)
- return 0;
-
- return _gpio_cdev_reopen(gpio, gpio->u.cdev.direction, gpio->u.cdev.edge, gpio->u.cdev.bias, gpio->u.cdev.drive, inverted);
-}
-
-static unsigned int gpio_cdev_line(gpio_t *gpio) {
- return gpio->u.cdev.line;
-}
-
-static int gpio_cdev_fd(gpio_t *gpio) {
- return gpio->u.cdev.line_fd;
-}
-
-static int gpio_cdev_name(gpio_t *gpio, char *str, size_t len) {
- struct gpioline_info line_info = {0};
-
- if (!len)
- return 0;
-
- line_info.line_offset = gpio->u.cdev.line;
-
- if (ioctl(gpio->u.cdev.chip_fd, GPIO_GET_LINEINFO_IOCTL, &line_info) < 0)
- return _gpio_error(gpio, GPIO_ERROR_QUERY, errno, "Querying GPIO line info for line %u", gpio->u.cdev.line);
-
- strncpy(str, line_info.name, len - 1);
- str[len - 1] = '\0';
-
- return 0;
-}
-
-static int gpio_cdev_label(gpio_t *gpio, char *str, size_t len) {
- struct gpioline_info line_info = {0};
-
- if (!len)
- return 0;
-
- line_info.line_offset = gpio->u.cdev.line;
-
- if (ioctl(gpio->u.cdev.chip_fd, GPIO_GET_LINEINFO_IOCTL, &line_info) < 0)
- return _gpio_error(gpio, GPIO_ERROR_QUERY, errno, "Querying GPIO line info for line %u", gpio->u.cdev.line);
-
- strncpy(str, line_info.consumer, len - 1);
- str[len - 1] = '\0';
-
- return 0;
-}
-
-static int gpio_cdev_chip_fd(gpio_t *gpio) {
- return gpio->u.cdev.chip_fd;
-}
-
-static int gpio_cdev_chip_name(gpio_t *gpio, char *str, size_t len) {
- struct gpiochip_info chip_info = {0};
-
- if (!len)
- return 0;
-
- if (ioctl(gpio->u.cdev.chip_fd, GPIO_GET_CHIPINFO_IOCTL, &chip_info) < 0)
- return _gpio_error(gpio, GPIO_ERROR_QUERY, errno, "Querying GPIO chip info");
-
- strncpy(str, chip_info.name, len - 1);
- str[len - 1] = '\0';
-
- return 0;
-}
-
-static int gpio_cdev_chip_label(gpio_t *gpio, char *str, size_t len) {
- struct gpiochip_info chip_info = {0};
-
- if (!len)
- return 0;
-
- if (ioctl(gpio->u.cdev.chip_fd, GPIO_GET_CHIPINFO_IOCTL, &chip_info) < 0)
- return _gpio_error(gpio, GPIO_ERROR_QUERY, errno, "Querying GPIO chip info");
-
- strncpy(str, chip_info.label, len - 1);
- str[len - 1] = '\0';
-
- return 0;
-}
-
-static int gpio_cdev_tostring(gpio_t *gpio, char *str, size_t len) {
- gpio_direction_t direction;
- const char *direction_str;
- gpio_edge_t edge;
- const char *edge_str;
- gpio_bias_t bias;
- const char *bias_str;
- gpio_drive_t drive;
- const char *drive_str;
- bool inverted;
- const char *inverted_str;
- char line_name[32];
- const char *line_name_str;
- char line_label[32];
- const char *line_label_str;
- char chip_name[32];
- const char *chip_name_str;
- char chip_label[32];
- const char *chip_label_str;
-
- if (gpio_cdev_get_direction(gpio, &direction) < 0)
- direction_str = "";
- else
- direction_str = (direction == GPIO_DIR_IN) ? "in" :
- (direction == GPIO_DIR_OUT) ? "out" : "unknown";
-
- if (gpio_cdev_get_edge(gpio, &edge) < 0)
- edge_str = "";
- else
- edge_str = (edge == GPIO_EDGE_NONE) ? "none" :
- (edge == GPIO_EDGE_RISING) ? "rising" :
- (edge == GPIO_EDGE_FALLING) ? "falling" :
- (edge == GPIO_EDGE_BOTH) ? "both" : "unknown";
-
- if (gpio_cdev_get_bias(gpio, &bias) < 0)
- bias_str = "";
- else
- bias_str = (bias == GPIO_BIAS_DEFAULT) ? "default" :
- (bias == GPIO_BIAS_PULL_UP) ? "pull_up" :
- (bias == GPIO_BIAS_PULL_DOWN) ? "pull_down" :
- (bias == GPIO_BIAS_DISABLE) ? "disable" : "unknown";
-
- if (gpio_cdev_get_drive(gpio, &drive) < 0)
- drive_str = "";
- else
- drive_str = (drive == GPIO_DRIVE_DEFAULT) ? "default" :
- (drive == GPIO_DRIVE_OPEN_DRAIN) ? "open_drain" :
- (drive == GPIO_DRIVE_OPEN_SOURCE) ? "open_source" : "unknown";
-
- if (gpio_cdev_get_inverted(gpio, &inverted) < 0)
- inverted_str = "";
- else
- inverted_str = inverted ? "true" : "false";
-
- if (gpio_cdev_name(gpio, line_name, sizeof(line_name)) < 0)
- line_name_str = "";
- else
- line_name_str = line_name;
-
- if (gpio_cdev_label(gpio, line_label, sizeof(line_label)) < 0)
- line_label_str = "";
- else
- line_label_str = line_label;
-
- if (gpio_cdev_chip_name(gpio, chip_name, sizeof(chip_name)) < 0)
- chip_name_str = "";
- else
- chip_name_str = chip_name;
-
- if (gpio_cdev_chip_label(gpio, chip_label, sizeof(chip_label)) < 0)
- chip_label_str = "";
- else
- chip_label_str = chip_label;
-
- return snprintf(str, len, "GPIO %u (name=\"%s\", label=\"%s\", line_fd=%d, chip_fd=%d, direction=%s, edge=%s, bias=%s, drive=%s, inverted=%s, chip_name=\"%s\", chip_label=\"%s\", type=cdev)",
- gpio->u.cdev.line, line_name_str, line_label_str, gpio->u.cdev.line_fd, gpio->u.cdev.chip_fd, direction_str, edge_str, bias_str, drive_str, inverted_str, chip_name_str, chip_label_str);
-}
-
-static const struct gpio_ops gpio_cdev_ops = {
- .read = gpio_cdev_read,
- .write = gpio_cdev_write,
- .read_event = gpio_cdev_read_event,
- .poll = gpio_cdev_poll,
- .close = gpio_cdev_close,
- .get_direction = gpio_cdev_get_direction,
- .get_edge = gpio_cdev_get_edge,
- .get_bias = gpio_cdev_get_bias,
- .get_drive = gpio_cdev_get_drive,
- .get_inverted = gpio_cdev_get_inverted,
- .set_direction = gpio_cdev_set_direction,
- .set_edge = gpio_cdev_set_edge,
- .set_bias = gpio_cdev_set_bias,
- .set_drive = gpio_cdev_set_drive,
- .set_inverted = gpio_cdev_set_inverted,
- .line = gpio_cdev_line,
- .fd = gpio_cdev_fd,
- .name = gpio_cdev_name,
- .label = gpio_cdev_label,
- .chip_fd = gpio_cdev_chip_fd,
- .chip_name = gpio_cdev_chip_name,
- .chip_label = gpio_cdev_chip_label,
- .tostring = gpio_cdev_tostring,
-};
-
-int gpio_open_advanced(gpio_t *gpio, const char *path, unsigned int line, const gpio_config_t *config) {
- int ret, fd;
-
- if (config->direction != GPIO_DIR_IN && config->direction != GPIO_DIR_OUT && config->direction != GPIO_DIR_OUT_LOW && config->direction != GPIO_DIR_OUT_HIGH)
- return _gpio_error(gpio, GPIO_ERROR_ARG, 0, "Invalid GPIO direction (can be in, out, low, high)");
-
- if (config->edge != GPIO_EDGE_NONE && config->edge != GPIO_EDGE_RISING && config->edge != GPIO_EDGE_FALLING && config->edge != GPIO_EDGE_BOTH)
- return _gpio_error(gpio, GPIO_ERROR_ARG, 0, "Invalid GPIO interrupt edge (can be none, rising, falling, both)");
-
- if (config->direction != GPIO_DIR_IN && config->edge != GPIO_EDGE_NONE)
- return _gpio_error(gpio, GPIO_ERROR_ARG, 0, "Invalid GPIO edge for output GPIO");
-
- if (config->bias != GPIO_BIAS_DEFAULT && config->bias != GPIO_BIAS_PULL_UP && config->bias != GPIO_BIAS_PULL_DOWN && config->bias != GPIO_BIAS_DISABLE)
- return _gpio_error(gpio, GPIO_ERROR_ARG, 0, "Invalid GPIO line bias (can be default, pull_up, pull_down, disable)");
-
- if (config->drive != GPIO_DRIVE_DEFAULT && config->drive != GPIO_DRIVE_OPEN_DRAIN && config->drive != GPIO_DRIVE_OPEN_SOURCE)
- return _gpio_error(gpio, GPIO_ERROR_ARG, 0, "Invalid GPIO line drive (can be default, open_drain, open_source)");
-
- if (config->direction == GPIO_DIR_IN && config->drive != GPIO_DRIVE_DEFAULT)
- return _gpio_error(gpio, GPIO_ERROR_ARG, 0, "Invalid GPIO line drive for input GPIO");
-
- /* Open GPIO chip */
- if ((fd = open(path, 0)) < 0)
- return _gpio_error(gpio, GPIO_ERROR_OPEN, errno, "Opening GPIO chip");
-
- memset(gpio, 0, sizeof(gpio_t));
- gpio->ops = &gpio_cdev_ops;
- gpio->u.cdev.line = line;
- gpio->u.cdev.line_fd = -1;
- gpio->u.cdev.chip_fd = fd;
- strncpy(gpio->u.cdev.label, config->label ? config->label : "periphery", sizeof(gpio->u.cdev.label) - 1);
- gpio->u.cdev.label[sizeof(gpio->u.cdev.label) - 1] = '\0';
-
- /* Open GPIO line */
- ret = _gpio_cdev_reopen(gpio, config->direction, config->edge, config->bias, config->drive, config->inverted);
- if (ret < 0) {
- close(gpio->u.cdev.chip_fd);
- gpio->u.cdev.chip_fd = -1;
- return ret;
- }
-
- return 0;
-}
-
-int gpio_open_name_advanced(gpio_t *gpio, const char *path, const char *name, const gpio_config_t *config) {
- int fd;
-
- /* Open GPIO chip */
- if ((fd = open(path, 0)) < 0)
- return _gpio_error(gpio, GPIO_ERROR_OPEN, errno, "Opening GPIO chip");
-
- /* Get chip info for number of lines */
- struct gpiochip_info chip_info = {0};
- if (ioctl(fd, GPIO_GET_CHIPINFO_IOCTL, &chip_info) < 0) {
- int errsv = errno;
- close(fd);
- return _gpio_error(gpio, GPIO_ERROR_QUERY, errsv, "Querying GPIO chip info");
- }
-
- /* Loop through every line */
- struct gpioline_info line_info = {0};
- unsigned int line;
- for (line = 0; line < chip_info.lines; line++) {
- line_info.line_offset = line;
-
- /* Get the line info */
- if (ioctl(fd, GPIO_GET_LINEINFO_IOCTL, &line_info) < 0) {
- int errsv = errno;
- close(fd);
- return _gpio_error(gpio, GPIO_ERROR_QUERY, errsv, "Querying GPIO line info for line %u", line);
- }
-
- /* Compare the name */
- if (strcmp(line_info.name, name) == 0)
- break;
- }
-
- /* If no matching line name was found */
- if (line == chip_info.lines) {
- close(fd);
- return _gpio_error(gpio, GPIO_ERROR_NOT_FOUND, 0, "GPIO line \"%s\" not found by name", name);
- }
-
- if (close(fd) < 0)
- return _gpio_error(gpio, GPIO_ERROR_CLOSE, errno, "Closing GPIO chip");
-
- return gpio_open_advanced(gpio, path, line, config);
-}
-
-int gpio_open(gpio_t *gpio, const char *path, unsigned int line, gpio_direction_t direction) {
- gpio_config_t config = {
- .direction = direction,
- .edge = GPIO_EDGE_NONE,
- .bias = GPIO_BIAS_DEFAULT,
- .drive = GPIO_DRIVE_DEFAULT,
- .inverted = false,
- .label = NULL,
- };
-
- return gpio_open_advanced(gpio, path, line, &config);
-}
-
-int gpio_open_name(gpio_t *gpio, const char *path, const char *name, gpio_direction_t direction) {
- gpio_config_t config = {
- .direction = direction,
- .edge = GPIO_EDGE_NONE,
- .bias = GPIO_BIAS_DEFAULT,
- .drive = GPIO_DRIVE_DEFAULT,
- .inverted = false,
- .label = NULL,
- };
-
- return gpio_open_name_advanced(gpio, path, name, &config);
-}
-
-#else /* PERIPHERY_GPIO_CDEV_SUPPORT */
-
-int gpio_open_advanced(gpio_t *gpio, const char *path, unsigned int line, const gpio_config_t *config) {
- (void)path;
- (void)line;
- (void)config;
- return _gpio_error(gpio, GPIO_ERROR_UNSUPPORTED, 0, "c-periphery library built without character device GPIO support.");
-}
-
-int gpio_open_name_advanced(gpio_t *gpio, const char *path, const char *name, const gpio_config_t *config) {
- (void)path;
- (void)name;
- (void)config;
- return _gpio_error(gpio, GPIO_ERROR_UNSUPPORTED, 0, "c-periphery library built without character device GPIO support.");
-}
-
-int gpio_open(gpio_t *gpio, const char *path, unsigned int line, gpio_direction_t direction) {
- (void)path;
- (void)line;
- (void)direction;
- return _gpio_error(gpio, GPIO_ERROR_UNSUPPORTED, 0, "c-periphery library built without character device GPIO support.");
-}
-
-#endif
diff --git a/sys/arm-linux/drivers/gpio.h b/sys/arm-linux/drivers/gpio.h
deleted file mode 100644
index e18e7e52..00000000
--- a/sys/arm-linux/drivers/gpio.h
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * c-periphery
- * https://github.com/vsergeev/c-periphery
- * License: MIT
- */
-
-#ifndef _PERIPHERY_GPIO_H
-#define _PERIPHERY_GPIO_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include
-#include
-#include
-
-enum gpio_error_code {
- GPIO_ERROR_ARG = -1, /* Invalid arguments */
- GPIO_ERROR_OPEN = -2, /* Opening GPIO */
- GPIO_ERROR_NOT_FOUND = -3, /* Line name not found */
- GPIO_ERROR_QUERY = -4, /* Querying GPIO attributes */
- GPIO_ERROR_CONFIGURE = -5, /* Configuring GPIO attributes */
- GPIO_ERROR_UNSUPPORTED = -6, /* Unsupported attribute or operation */
- GPIO_ERROR_INVALID_OPERATION = -7, /* Invalid operation */
- GPIO_ERROR_IO = -8, /* Reading/writing GPIO */
- GPIO_ERROR_CLOSE = -9, /* Closing GPIO */
-};
-
-typedef enum gpio_direction {
- GPIO_DIR_IN, /* Input */
- GPIO_DIR_OUT, /* Output, initialized to low */
- GPIO_DIR_OUT_LOW, /* Output, initialized to low */
- GPIO_DIR_OUT_HIGH, /* Output, initialized to high */
-} gpio_direction_t;
-
-typedef enum gpio_edge {
- GPIO_EDGE_NONE, /* No interrupt edge */
- GPIO_EDGE_RISING, /* Rising edge 0 -> 1 */
- GPIO_EDGE_FALLING, /* Falling edge 1 -> 0 */
- GPIO_EDGE_BOTH /* Both edges X -> !X */
-} gpio_edge_t;
-
-typedef enum gpio_bias {
- GPIO_BIAS_DEFAULT, /* Default line bias */
- GPIO_BIAS_PULL_UP, /* Pull-up */
- GPIO_BIAS_PULL_DOWN, /* Pull-down */
- GPIO_BIAS_DISABLE, /* Disable line bias */
-} gpio_bias_t;
-
-typedef enum gpio_drive {
- GPIO_DRIVE_DEFAULT, /* Default line drive (push-pull) */
- GPIO_DRIVE_OPEN_DRAIN, /* Open drain */
- GPIO_DRIVE_OPEN_SOURCE, /* Open source */
-} gpio_drive_t;
-
-/* Configuration structure for gpio_open_*advanced() functions */
-typedef struct gpio_config {
- gpio_direction_t direction;
- gpio_edge_t edge;
- gpio_bias_t bias;
- gpio_drive_t drive;
- bool inverted;
- const char *label; /* Can be NULL for default consumer label */
-} gpio_config_t;
-
-typedef struct gpio_handle gpio_t;
-
-/* Primary Functions */
-gpio_t *gpio_new(void);
-int gpio_open(gpio_t *gpio, const char *path, unsigned int line, gpio_direction_t direction);
-int gpio_open_name(gpio_t *gpio, const char *path, const char *name, gpio_direction_t direction);
-int gpio_open_advanced(gpio_t *gpio, const char *path, unsigned int line, const gpio_config_t *config);
-int gpio_open_name_advanced(gpio_t *gpio, const char *path, const char *name, const gpio_config_t *config);
-int gpio_open_sysfs(gpio_t *gpio, unsigned int line, gpio_direction_t direction);
-int gpio_read(gpio_t *gpio, bool *value);
-int gpio_write(gpio_t *gpio, bool value);
-int gpio_poll(gpio_t *gpio, int timeout_ms);
-int gpio_close(gpio_t *gpio);
-void gpio_free(gpio_t *gpio);
-
-/* Read Event (for character device GPIOs) */
-int gpio_read_event(gpio_t *gpio, gpio_edge_t *edge, uint64_t *timestamp);
-
-/* Poll Multiple */
-int gpio_poll_multiple(gpio_t **gpios, size_t count, int timeout_ms, bool *gpios_ready);
-
-/* Getters */
-int gpio_get_direction(gpio_t *gpio, gpio_direction_t *direction);
-int gpio_get_edge(gpio_t *gpio, gpio_edge_t *edge);
-int gpio_get_bias(gpio_t *gpio, gpio_bias_t *bias);
-int gpio_get_drive(gpio_t *gpio, gpio_drive_t *drive);
-int gpio_get_inverted(gpio_t *gpio, bool *inverted);
-
-/* Setters */
-int gpio_set_direction(gpio_t *gpio, gpio_direction_t direction);
-int gpio_set_edge(gpio_t *gpio, gpio_edge_t edge);
-int gpio_set_bias(gpio_t *gpio, gpio_bias_t bias);
-int gpio_set_drive(gpio_t *gpio, gpio_drive_t drive);
-int gpio_set_inverted(gpio_t *gpio, bool inverted);
-
-/* Miscellaneous Properties */
-unsigned int gpio_line(gpio_t *gpio);
-int gpio_fd(gpio_t *gpio);
-int gpio_name(gpio_t *gpio, char *str, size_t len);
-int gpio_label(gpio_t *gpio, char *str, size_t len);
-int gpio_chip_fd(gpio_t *gpio);
-int gpio_chip_name(gpio_t *gpio, char *str, size_t len);
-int gpio_chip_label(gpio_t *gpio, char *str, size_t len);
-int gpio_tostring(gpio_t *gpio, char *str, size_t len);
-
-/* Error Handling */
-int gpio_errno(gpio_t *gpio);
-const char *gpio_errmsg(gpio_t *gpio);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
-
diff --git a/sys/arm-linux/drivers/i2c.c b/sys/arm-linux/drivers/i2c.c
deleted file mode 100644
index 53929715..00000000
--- a/sys/arm-linux/drivers/i2c.c
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * c-periphery
- * https://github.com/vsergeev/c-periphery
- * License: MIT
- */
-
-#include
-#include
-#include
-#include
-#include
-#include
-
-#include
-#include
-#include
-#include
-
-#include
-#include
-#include
-
-#include "i2c.h"
-
-struct i2c_handle {
- int fd;
-
- struct {
- int c_errno;
- char errmsg[96];
- } error;
-};
-
-static int _i2c_error(i2c_t *i2c, int code, int c_errno, const char *fmt, ...) {
- va_list ap;
-
- i2c->error.c_errno = c_errno;
-
- va_start(ap, fmt);
- vsnprintf(i2c->error.errmsg, sizeof(i2c->error.errmsg), fmt, ap);
- va_end(ap);
-
- /* Tack on strerror() and errno */
- if (c_errno) {
- char buf[64];
- strerror_r(c_errno, buf, sizeof(buf));
- snprintf(i2c->error.errmsg+strlen(i2c->error.errmsg), sizeof(i2c->error.errmsg)-strlen(i2c->error.errmsg), ": %s [errno %d]", buf, c_errno);
- }
-
- return code;
-}
-
-i2c_t *i2c_new(void) {
- i2c_t *i2c = calloc(1, sizeof(i2c_t));
- if (i2c == NULL)
- return NULL;
-
- i2c->fd = -1;
-
- return i2c;
-}
-
-void i2c_free(i2c_t *i2c) {
- free(i2c);
-}
-
-int i2c_open(i2c_t *i2c, const char *path) {
- unsigned long supported_funcs;
-
- memset(i2c, 0, sizeof(i2c_t));
-
- /* Open device */
- if ((i2c->fd = open(path, O_RDWR)) < 0)
- return _i2c_error(i2c, I2C_ERROR_OPEN, errno, "Opening I2C device \"%s\"", path);
-
- /* Query supported functions */
- if (ioctl(i2c->fd, I2C_FUNCS, &supported_funcs) < 0) {
- int errsv = errno;
- close(i2c->fd);
- i2c->fd = -1;
- return _i2c_error(i2c, I2C_ERROR_QUERY, errsv, "Querying I2C functions");
- }
-
- if (!(supported_funcs & I2C_FUNC_I2C)) {
- close(i2c->fd);
- i2c->fd = -1;
- return _i2c_error(i2c, I2C_ERROR_NOT_SUPPORTED, 0, "I2C not supported on %s", path);
- }
-
- return 0;
-}
-
-int i2c_transfer(i2c_t *i2c, struct i2c_msg *msgs, size_t count) {
- struct i2c_rdwr_ioctl_data i2c_rdwr_data;
-
- /* Prepare I2C transfer structure */
- memset(&i2c_rdwr_data, 0, sizeof(struct i2c_rdwr_ioctl_data));
- i2c_rdwr_data.msgs = msgs;
- i2c_rdwr_data.nmsgs = count;
-
- /* Transfer */
- if (ioctl(i2c->fd, I2C_RDWR, &i2c_rdwr_data) < 0)
- return _i2c_error(i2c, I2C_ERROR_TRANSFER, errno, "I2C transfer");
-
- return 0;
-}
-
-int i2c_close(i2c_t *i2c) {
- if (i2c->fd < 0)
- return 0;
-
- /* Close fd */
- if (close(i2c->fd) < 0)
- return _i2c_error(i2c, I2C_ERROR_CLOSE, errno, "Closing I2C device");
-
- i2c->fd = -1;
-
- return 0;
-}
-
-int i2c_tostring(i2c_t *i2c, char *str, size_t len) {
- return snprintf(str, len, "I2C (fd=%d)", i2c->fd);
-}
-
-const char *i2c_errmsg(i2c_t *i2c) {
- return i2c->error.errmsg;
-}
-
-int i2c_errno(i2c_t *i2c) {
- return i2c->error.c_errno;
-}
-
-int i2c_fd(i2c_t *i2c) {
- return i2c->fd;
-}
-
diff --git a/sys/arm-linux/drivers/i2c.h b/sys/arm-linux/drivers/i2c.h
deleted file mode 100644
index 7383f5ea..00000000
--- a/sys/arm-linux/drivers/i2c.h
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * c-periphery
- * https://github.com/vsergeev/c-periphery
- * License: MIT
- */
-
-#ifndef _PERIPHERY_I2C_H
-#define _PERIPHERY_I2C_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include
-#include
-#include
-
-#include
-#include
-
-enum i2c_error_code {
- I2C_ERROR_ARG = -1, /* Invalid arguments */
- I2C_ERROR_OPEN = -2, /* Opening I2C device */
- I2C_ERROR_QUERY = -3, /* Querying I2C device attributes */
- I2C_ERROR_NOT_SUPPORTED = -4, /* I2C not supported on this device */
- I2C_ERROR_TRANSFER = -5, /* I2C transfer */
- I2C_ERROR_CLOSE = -6, /* Closing I2C device */
-};
-
-typedef struct i2c_handle i2c_t;
-
-/* Primary Functions */
-i2c_t *i2c_new(void);
-int i2c_open(i2c_t *i2c, const char *path);
-int i2c_transfer(i2c_t *i2c, struct i2c_msg *msgs, size_t count);
-int i2c_close(i2c_t *i2c);
-void i2c_free(i2c_t *i2c);
-
-/* Miscellaneous */
-int i2c_fd(i2c_t *i2c);
-int i2c_tostring(i2c_t *i2c, char *str, size_t len);
-
-/* Error Handling */
-int i2c_errno(i2c_t *i2c);
-const char *i2c_errmsg(i2c_t *i2c);
-
-/* struct i2c_msg from :
-
- struct i2c_msg {
- __u16 addr;
- __u16 flags;
- #define I2C_M_TEN 0x0010
- #define I2C_M_RD 0x0001
- #define I2C_M_STOP 0x8000
- #define I2C_M_NOSTART 0x4000
- #define I2C_M_REV_DIR_ADDR 0x2000
- #define I2C_M_IGNORE_NAK 0x1000
- #define I2C_M_NO_RD_ACK 0x0800
- #define I2C_M_RECV_LEN 0x0400
- __u16 len;
- __u8 *buf;
- };
-*/
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
-
diff --git a/sys/arm-linux/drivers/spi.c b/sys/arm-linux/drivers/spi.c
deleted file mode 100644
index d71937eb..00000000
--- a/sys/arm-linux/drivers/spi.c
+++ /dev/null
@@ -1,404 +0,0 @@
-/*
- * c-periphery
- * https://github.com/vsergeev/c-periphery
- * License: MIT
- */
-
-#include
-#include
-#include
-#include
-#include
-#include
-
-#include
-#include
-#include
-
-#include
-#include
-#include
-
-#include "spi.h"
-
-struct spi_handle {
- int fd;
-
- struct {
- int c_errno;
- char errmsg[96];
- } error;
-};
-
-static int _spi_error(spi_t *spi, int code, int c_errno, const char *fmt, ...) {
- va_list ap;
-
- spi->error.c_errno = c_errno;
-
- va_start(ap, fmt);
- vsnprintf(spi->error.errmsg, sizeof(spi->error.errmsg), fmt, ap);
- va_end(ap);
-
- /* Tack on strerror() and errno */
- if (c_errno) {
- char buf[64];
- strerror_r(c_errno, buf, sizeof(buf));
- snprintf(spi->error.errmsg+strlen(spi->error.errmsg), sizeof(spi->error.errmsg)-strlen(spi->error.errmsg), ": %s [errno %d]", buf, c_errno);
- }
-
- return code;
-}
-
-spi_t *spi_new(void) {
- spi_t *spi = calloc(1, sizeof(spi_t));
- if (spi == NULL)
- return NULL;
-
- spi->fd = -1;
-
- return spi;
-}
-
-void spi_free(spi_t *spi) {
- free(spi);
-}
-
-int spi_open(spi_t *spi, const char *path, unsigned int mode, uint32_t max_speed) {
- return spi_open_advanced(spi, path, mode, max_speed, MSB_FIRST, 8, 0);
-}
-
-int spi_open_advanced(spi_t *spi, const char *path, unsigned int mode, uint32_t max_speed, spi_bit_order_t bit_order, uint8_t bits_per_word, uint8_t extra_flags) {
- return spi_open_advanced2(spi, path, mode, max_speed, bit_order, bits_per_word, extra_flags);
-}
-
-int spi_open_advanced2(spi_t *spi, const char *path, unsigned int mode, uint32_t max_speed, spi_bit_order_t bit_order, uint8_t bits_per_word, uint32_t extra_flags) {
- uint32_t data32;
- uint8_t data8;
-
- /* Validate arguments */
- if (mode & ~0x3)
- return _spi_error(spi, SPI_ERROR_ARG, 0, "Invalid mode (can be 0,1,2,3)");
- if (bit_order != MSB_FIRST && bit_order != LSB_FIRST)
- return _spi_error(spi, SPI_ERROR_ARG, 0, "Invalid bit order (can be MSB_FIRST,LSB_FIRST)");
-#ifndef SPI_IOC_WR_MODE32
- if (extra_flags > 0xff)
- return _spi_error(spi, SPI_ERROR_UNSUPPORTED, 0, "Kernel version does not support 32-bit SPI mode flags");
-#endif
-
- memset(spi, 0, sizeof(spi_t));
-
- /* Open device */
- if ((spi->fd = open(path, O_RDWR)) < 0)
- return _spi_error(spi, SPI_ERROR_OPEN, errno, "Opening SPI device \"%s\"", path);
-
- /* Set mode, bit order, extra flags */
-#ifndef SPI_IOC_WR_MODE32
- (void)data32;
-
- data8 = mode | ((bit_order == LSB_FIRST) ? SPI_LSB_FIRST : 0) | extra_flags;
- if (ioctl(spi->fd, SPI_IOC_WR_MODE, &data8) < 0) {
- int errsv = errno;
- close(spi->fd);
- spi->fd = -1;
- return _spi_error(spi, SPI_ERROR_CONFIGURE, errsv, "Setting SPI mode");
- }
-#else
- if (extra_flags > 0xff) {
- /* Use 32-bit mode if extra_flags is wider than 8-bits */
- data32 = mode | ((bit_order == LSB_FIRST) ? SPI_LSB_FIRST : 0) | extra_flags;
- if (ioctl(spi->fd, SPI_IOC_WR_MODE32, &data32) < 0) {
- int errsv = errno;
- close(spi->fd);
- spi->fd = -1;
- return _spi_error(spi, SPI_ERROR_CONFIGURE, errsv, "Setting SPI mode");
- }
- } else {
- /* Prefer 8-bit mode, in case this library is inadvertently used on an
- * older kernel. */
- data8 = mode | ((bit_order == LSB_FIRST) ? SPI_LSB_FIRST : 0) | extra_flags;
- if (ioctl(spi->fd, SPI_IOC_WR_MODE, &data8) < 0) {
- int errsv = errno;
- close(spi->fd);
- spi->fd = -1;
- return _spi_error(spi, SPI_ERROR_CONFIGURE, errsv, "Setting SPI mode");
- }
- }
-#endif
-
- /* Set max speed */
- if (ioctl(spi->fd, SPI_IOC_WR_MAX_SPEED_HZ, &max_speed) < 0) {
- int errsv = errno;
- close(spi->fd);
- spi->fd = -1;
- return _spi_error(spi, SPI_ERROR_CONFIGURE, errsv, "Setting SPI max speed");
- }
-
- /* Set bits per word */
- if (ioctl(spi->fd, SPI_IOC_WR_BITS_PER_WORD, &bits_per_word) < 0) {
- int errsv = errno;
- close(spi->fd);
- spi->fd = -1;
- return _spi_error(spi, SPI_ERROR_CONFIGURE, errsv, "Setting SPI bits per word");
- }
-
- return 0;
-}
-
-int spi_transfer(spi_t *spi, const uint8_t *txbuf, uint8_t *rxbuf, size_t len) {
- struct spi_ioc_transfer spi_xfer;
-
- /* Prepare SPI transfer structure */
- memset(&spi_xfer, 0, sizeof(struct spi_ioc_transfer));
- spi_xfer.tx_buf = (uintptr_t)txbuf;
- spi_xfer.rx_buf = (uintptr_t)rxbuf;
- spi_xfer.len = len;
- spi_xfer.delay_usecs = 0;
- spi_xfer.speed_hz = 0;
- spi_xfer.bits_per_word = 0;
- spi_xfer.cs_change = 0;
-
- /* Transfer */
- if (ioctl(spi->fd, SPI_IOC_MESSAGE(1), &spi_xfer) < 1)
- return _spi_error(spi, SPI_ERROR_TRANSFER, errno, "SPI transfer");
-
- return 0;
-}
-
-int spi_close(spi_t *spi) {
- if (spi->fd < 0)
- return 0;
-
- /* Close fd */
- if (close(spi->fd) < 0)
- return _spi_error(spi, SPI_ERROR_CLOSE, errno, "Closing SPI device");
-
- spi->fd = -1;
-
- return 0;
-}
-
-int spi_get_mode(spi_t *spi, unsigned int *mode) {
- uint8_t data8;
-
- if (ioctl(spi->fd, SPI_IOC_RD_MODE, &data8) < 0)
- return _spi_error(spi, SPI_ERROR_QUERY, errno, "Getting SPI mode");
-
- *mode = data8 & (SPI_CPHA | SPI_CPOL);
-
- return 0;
-}
-
-int spi_get_max_speed(spi_t *spi, uint32_t *max_speed) {
- uint32_t data32;
-
- if (ioctl(spi->fd, SPI_IOC_RD_MAX_SPEED_HZ, &data32) < 0)
- return _spi_error(spi, SPI_ERROR_QUERY, errno, "Getting SPI max speed");
-
- *max_speed = data32;
-
- return 0;
-}
-
-int spi_get_bit_order(spi_t *spi, spi_bit_order_t *bit_order) {
- uint8_t data8;
-
- if (ioctl(spi->fd, SPI_IOC_RD_LSB_FIRST, &data8) < 0)
- return _spi_error(spi, SPI_ERROR_QUERY, errno, "Getting SPI bit order");
-
- if (data8)
- *bit_order = LSB_FIRST;
- else
- *bit_order = MSB_FIRST;
-
- return 0;
-}
-
-int spi_get_bits_per_word(spi_t *spi, uint8_t *bits_per_word) {
- uint8_t data8;
-
- if (ioctl(spi->fd, SPI_IOC_RD_BITS_PER_WORD, &data8) < 0)
- return _spi_error(spi, SPI_ERROR_QUERY, errno, "Getting SPI bits per word");
-
- *bits_per_word = data8;
-
- return 0;
-}
-
-int spi_get_extra_flags(spi_t *spi, uint8_t *extra_flags) {
- uint8_t data8;
-
- if (ioctl(spi->fd, SPI_IOC_RD_MODE, &data8) < 0)
- return _spi_error(spi, SPI_ERROR_QUERY, errno, "Getting SPI mode flags");
-
- /* Extra mode flags without mode 0-3 and bit order */
- *extra_flags = data8 & ~( SPI_CPOL | SPI_CPHA | SPI_LSB_FIRST );
-
- return 0;
-}
-
-int spi_get_extra_flags32(spi_t *spi, uint32_t *extra_flags) {
-#ifdef SPI_IOC_RD_MODE32
- uint32_t mode32;
-
- if (ioctl(spi->fd, SPI_IOC_RD_MODE32, &mode32) < 0)
- return _spi_error(spi, SPI_ERROR_QUERY, errno, "Getting 32-bit SPI mode flags");
-
- /* Extra mode flags without mode 0-3 and bit order */
- *extra_flags = mode32 & ~(SPI_CPOL | SPI_CPHA | SPI_LSB_FIRST);
-
- return 0;
-#else
- (void)extra_flags;
-
- return _spi_error(spi, SPI_ERROR_UNSUPPORTED, 0, "Kernel version does not support 32-bit SPI mode flags");
-#endif
-}
-
-int spi_set_mode(spi_t *spi, unsigned int mode) {
- uint8_t data8;
-
- if (mode & ~0x3)
- return _spi_error(spi, SPI_ERROR_ARG, 0, "Invalid mode (can be 0,1,2,3)");
-
- if (ioctl(spi->fd, SPI_IOC_RD_MODE, &data8) < 0)
- return _spi_error(spi, SPI_ERROR_QUERY, errno, "Getting SPI mode");
-
- data8 &= ~(SPI_CPOL | SPI_CPHA);
- data8 |= mode;
-
- if (ioctl(spi->fd, SPI_IOC_WR_MODE, &data8) < 0)
- return _spi_error(spi, SPI_ERROR_CONFIGURE, errno, "Setting SPI mode");
-
- return 0;
-}
-
-int spi_set_bit_order(spi_t *spi, spi_bit_order_t bit_order) {
- uint8_t data8;
-
- if (bit_order != MSB_FIRST && bit_order != LSB_FIRST)
- return _spi_error(spi, SPI_ERROR_ARG, 0, "Invalid bit order (can be MSB_FIRST,LSB_FIRST)");
-
- if (bit_order == LSB_FIRST)
- data8 = 1;
- else
- data8 = 0;
-
- if (ioctl(spi->fd, SPI_IOC_WR_LSB_FIRST, &data8) < 0)
- return _spi_error(spi, SPI_ERROR_CONFIGURE, errno, "Setting SPI bit order");
-
- return 0;
-}
-
-int spi_set_extra_flags(spi_t *spi, uint8_t extra_flags) {
- uint8_t data8;
-
- if (ioctl(spi->fd, SPI_IOC_RD_MODE, &data8) < 0)
- return _spi_error(spi, SPI_ERROR_QUERY, errno, "Getting SPI mode flags");
-
- /* Keep mode 0-3 and bit order */
- data8 &= (SPI_CPOL | SPI_CPHA | SPI_LSB_FIRST);
- /* Set extra flags */
- data8 |= extra_flags;
-
- if (ioctl(spi->fd, SPI_IOC_WR_MODE, &data8) < 0)
- return _spi_error(spi, SPI_ERROR_CONFIGURE, errno, "Setting SPI mode flags");
-
- return 0;
-}
-
-int spi_set_extra_flags32(spi_t *spi, uint32_t extra_flags) {
-#ifdef SPI_IOC_WR_MODE32
- uint32_t mode32;
-
- if (ioctl(spi->fd, SPI_IOC_RD_MODE32, &mode32) < 0)
- return _spi_error(spi, SPI_ERROR_QUERY, errno, "Getting 32-bit SPI mode flags");
-
- /* Keep mode 0-3 and bit order */
- mode32 &= (SPI_CPOL | SPI_CPHA | SPI_LSB_FIRST);
- /* Set extra flags */
- mode32 |= extra_flags;
-
- if (ioctl(spi->fd, SPI_IOC_WR_MODE32, &mode32) < 0)
- return _spi_error(spi, SPI_ERROR_CONFIGURE, errno, "Setting 32-bit SPI mode flags");
-
- return 0;
-#else
- (void)extra_flags;
-
- return _spi_error(spi, SPI_ERROR_UNSUPPORTED, 0, "Kernel version does not support 32-bit SPI mode flags");
-#endif
-}
-
-int spi_set_max_speed(spi_t *spi, uint32_t max_speed) {
-
- if (ioctl(spi->fd, SPI_IOC_WR_MAX_SPEED_HZ, &max_speed) < 0)
- return _spi_error(spi, SPI_ERROR_CONFIGURE, errno, "Setting SPI max speed");
-
- return 0;
-}
-
-int spi_set_bits_per_word(spi_t *spi, uint8_t bits_per_word) {
-
- if (ioctl(spi->fd, SPI_IOC_WR_BITS_PER_WORD, &bits_per_word) < 0)
- return _spi_error(spi, SPI_ERROR_CONFIGURE, errno, "Setting SPI bits per word");
-
- return 0;
-}
-
-int spi_tostring(spi_t *spi, char *str, size_t len) {
- unsigned int mode;
- char mode_str[2];
- uint32_t max_speed;
- char max_speed_str[16];
- uint8_t bits_per_word;
- char bits_per_word_str[4];
- spi_bit_order_t bit_order;
- const char *bit_order_str;
- uint8_t extra_flags8;
- uint32_t extra_flags32;
- char extra_flags_str[11];
-
- if (spi_get_mode(spi, &mode) < 0)
- strcpy(mode_str, "?");
- else
- snprintf(mode_str, sizeof(mode_str), "%u", mode);
-
- if (spi_get_max_speed(spi, &max_speed) < 0)
- strcpy(max_speed_str, "?");
- else
- snprintf(max_speed_str, sizeof(max_speed_str), "%u", max_speed);
-
- if (spi_get_bit_order(spi, &bit_order) < 0)
- bit_order_str = "?";
- else
- bit_order_str = (bit_order == LSB_FIRST) ? "LSB_FIRST" : "MSB_FIRST";
-
- if (spi_get_bits_per_word(spi, &bits_per_word) < 0)
- strcpy(bits_per_word_str, "?");
- else
- snprintf(bits_per_word_str, sizeof(bits_per_word_str), "%u", bits_per_word);
-
- if (spi_get_extra_flags32(spi, &extra_flags32) < 0) {
- if (spi_get_extra_flags(spi, &extra_flags8) < 0)
- strcpy(extra_flags_str, "?");
- else
- snprintf(extra_flags_str, sizeof(extra_flags_str), "0x%02x", extra_flags8);
- } else {
- snprintf(extra_flags_str, sizeof(extra_flags_str), "0x%08x", extra_flags32);
- }
-
- return snprintf(str, len, "SPI (fd=%d, mode=%s, max_speed=%s, bit_order=%s, bits_per_word=%s, extra_flags=%s)", spi->fd, mode_str, max_speed_str, bit_order_str, bits_per_word_str, extra_flags_str);
-}
-
-const char *spi_errmsg(spi_t *spi) {
- return spi->error.errmsg;
-}
-
-int spi_errno(spi_t *spi) {
- return spi->error.c_errno;
-}
-
-int spi_fd(spi_t *spi) {
- return spi->fd;
-}
-
diff --git a/sys/arm-linux/drivers/spi.h b/sys/arm-linux/drivers/spi.h
deleted file mode 100644
index 5b761c2e..00000000
--- a/sys/arm-linux/drivers/spi.h
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * c-periphery
- * https://github.com/vsergeev/c-periphery
- * License: MIT
- */
-
-#ifndef _PERIPHERY_SPI_H
-#define _PERIPHERY_SPI_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include
-#include
-
-enum spi_error_code {
- SPI_ERROR_ARG = -1, /* Invalid arguments */
- SPI_ERROR_OPEN = -2, /* Opening SPI device */
- SPI_ERROR_QUERY = -3, /* Querying SPI device attributes */
- SPI_ERROR_CONFIGURE = -4, /* Configuring SPI device attributes */
- SPI_ERROR_TRANSFER = -5, /* SPI transfer */
- SPI_ERROR_CLOSE = -6, /* Closing SPI device */
- SPI_ERROR_UNSUPPORTED = -7, /* Unsupported attribute or operation */
-};
-
-typedef enum spi_bit_order {
- MSB_FIRST,
- LSB_FIRST,
-} spi_bit_order_t;
-
-typedef struct spi_handle spi_t;
-
-/* Primary Functions */
-spi_t *spi_new(void);
-int spi_open(spi_t *spi, const char *path, unsigned int mode,
- uint32_t max_speed);
-int spi_open_advanced(spi_t *spi, const char *path, unsigned int mode,
- uint32_t max_speed, spi_bit_order_t bit_order,
- uint8_t bits_per_word, uint8_t extra_flags);
-int spi_open_advanced2(spi_t *spi, const char *path, unsigned int mode,
- uint32_t max_speed, spi_bit_order_t bit_order,
- uint8_t bits_per_word, uint32_t extra_flags);
-int spi_transfer(spi_t *spi, const uint8_t *txbuf, uint8_t *rxbuf, size_t len);
-int spi_close(spi_t *spi);
-void spi_free(spi_t *spi);
-
-/* Getters */
-int spi_get_mode(spi_t *spi, unsigned int *mode);
-int spi_get_max_speed(spi_t *spi, uint32_t *max_speed);
-int spi_get_bit_order(spi_t *spi, spi_bit_order_t *bit_order);
-int spi_get_bits_per_word(spi_t *spi, uint8_t *bits_per_word);
-int spi_get_extra_flags(spi_t *spi, uint8_t *extra_flags);
-int spi_get_extra_flags32(spi_t *spi, uint32_t *extra_flags);
-
-/* Setters */
-int spi_set_mode(spi_t *spi, unsigned int mode);
-int spi_set_max_speed(spi_t *spi, uint32_t max_speed);
-int spi_set_bit_order(spi_t *spi, spi_bit_order_t bit_order);
-int spi_set_bits_per_word(spi_t *spi, uint8_t bits_per_word);
-int spi_set_extra_flags(spi_t *spi, uint8_t extra_flags);
-int spi_set_extra_flags32(spi_t *spi, uint32_t extra_flags);
-
-/* Miscellaneous */
-int spi_fd(spi_t *spi);
-int spi_tostring(spi_t *spi, char *str, size_t len);
-
-/* Error Handling */
-int spi_errno(spi_t *spi);
-const char *spi_errmsg(spi_t *spi);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
-