aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gpio.c74
1 files changed, 70 insertions, 4 deletions
diff --git a/gpio.c b/gpio.c
index fc60d00..8e7499d 100644
--- a/gpio.c
+++ b/gpio.c
@@ -33,8 +33,27 @@
#define SYSFS_GPIO "/sys/class/gpio"
+struct gpio_info {
+ bool expanded;
+ int active_low;
+ int value;
+ int direction;
+ int edge;
+} *gpios_info;
+
static struct tree *gpio_tree = NULL;
+static struct gpio_info *gpio_alloc(void)
+{
+ struct gpio_info *gi;
+
+ gi = malloc(sizeof(*gi));
+ if (gi)
+ memset(gi, 0, sizeof(*gi));
+
+ return gi;
+}
+
static int gpio_display(bool refresh)
{
return 0;
@@ -62,24 +81,71 @@ static struct display_ops gpio_ops = {
.selectf = gpio_selectf,
};
+static int gpio_filter_cb(const char *name)
+{
+ /* let's ignore some directories in order to avoid to be
+ * pulled inside the sysfs circular symlinks mess/hell
+ * (choose the word which fit better)
+ */
+ if (!strcmp(name, "device"))
+ return 1;
+
+ if (!strcmp(name, "subsystem"))
+ return 1;
+
+ if (!strcmp(name, "driver"))
+ return 1;
+
+ /* we want to ignore the gpio chips */
+ if (strstr(name, "chip"))
+ return 1;
+
+ /* we are not interested by the power value */
+ if (!strcmp(name, "power"))
+ return 1;
+
+ return 0;
+}
+
static inline int read_gpio_cb(struct tree *t, void *data)
{
+ struct gpio_info *gpio = t->private;
+
+ file_read_value(t->path, "active_low", "%d", &gpio->active_low);
+ file_read_value(t->path, "value", "%d", &gpio->value);
+ file_read_value(t->path, "edge", "%d", &gpio->edge);
+ file_read_value(t->path, "direction", "%d", &gpio->direction);
+
return 0;
}
static int read_gpio_info(struct tree *tree)
{
- return 0;
+ return tree_for_each(tree, read_gpio_cb, NULL);
}
static int fill_gpio_cb(struct tree *t, void *data)
{
- return 0;
+ struct gpio_info *gpio;
+
+ gpio = gpio_alloc();
+ if (!gpio)
+ return -1;
+ t->private = gpio;
+
+ /* we skip the root node but we set it expanded for its children */
+ if (!t->parent) {
+ gpio->expanded = true;
+ return 0;
+ }
+
+ return read_gpio_cb(t, data);
+
}
static int fill_gpio_tree(void)
{
- return 0;
+ return tree_for_each(gpio_tree, fill_gpio_cb, NULL);
}
int gpio_dump(void)
@@ -92,7 +158,7 @@ int gpio_dump(void)
*/
int gpio_init(void)
{
- gpio_tree = tree_load(SYSFS_GPIO, NULL, false);
+ gpio_tree = tree_load(SYSFS_GPIO, gpio_filter_cb, false);
if (!gpio_tree)
return -1;