#
lib_LTLIBRARIES = libgpiod.la
-libgpiod_la_SOURCES = chip.c iter.c line.c misc.c simple.c
+libgpiod_la_SOURCES = chip.c iter.c line.c line.h misc.c simple.c
libgpiod_la_CFLAGS = -Wall -Wextra -g
libgpiod_la_CFLAGS += -fvisibility=hidden -I$(top_srcdir)/include/
libgpiod_la_CFLAGS += -include $(top_builddir)/config.h
* as published by the Free Software Foundation.
*/
-#include "gpiod-internal.h"
+#include "line.h"
#include <stdio.h>
#include <string.h>
struct gpiod_chip {
int fd;
struct gpiochip_info cinfo;
- struct gpiod_line *lines;
+ struct gpiod_line **lines;
};
static bool isuint(const char *str)
return *str == '\0';
}
-int chip_get_fd(struct gpiod_chip *chip)
-{
- return chip->fd;
-}
-
struct gpiod_chip * gpiod_chip_open(const char *path)
{
struct gpiod_chip *chip;
return NULL;
}
- chip->lines = line_array_alloc(chip->cinfo.lines);
+ chip->lines = calloc(chip->cinfo.lines, sizeof(struct gpiod_line *));
if (!chip->lines) {
close(chip->fd);
free(chip);
void gpiod_chip_close(struct gpiod_chip *chip)
{
- struct gpiod_line_bulk bulk;
unsigned int i;
- gpiod_line_bulk_init(&bulk);
- for (i = 0; i < chip->cinfo.lines; i++)
- gpiod_line_bulk_add(&bulk, line_array_member(chip->lines, i));
- gpiod_line_release_bulk(&bulk);
+ for (i = 0; i < chip->cinfo.lines; i++) {
+ if (chip->lines[i]) {
+ gpiod_line_release(chip->lines[i]);
+ line_free(chip->lines[i]);
+ }
+ }
close(chip->fd);
- line_array_free(chip->lines);
+ free(chip->lines);
free(chip);
}
return NULL;
}
- line = line_array_member(chip->lines, offset);
- line_set_offset(line, offset);
- line_set_chip(line, chip);
+ if (!chip->lines[offset]) {
+ line = line_new(offset, chip, chip->fd);
+ if (!line)
+ return NULL;
+
+ chip->lines[offset] = line;
+ } else {
+ line = chip->lines[offset];
+ }
status = gpiod_line_update(line);
if (status < 0)
+++ /dev/null
-/*
- * Internal routines for libgpiod.
- *
- * Copyright (C) 2017 Bartosz Golaszewski <bartekgola@gmail.com>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2.1 of the GNU Lesser General Public License
- * as published by the Free Software Foundation.
- */
-
-#ifndef __GPIOD_INTERNAL_H__
-#define __GPIOD_INTERNAL_H__
-
-#include <gpiod.h>
-
-struct gpiod_line * line_array_alloc(size_t numlines);
-void line_array_free(struct gpiod_line *lines);
-struct gpiod_line * line_array_member(struct gpiod_line *lines, size_t index);
-
-void line_set_chip(struct gpiod_line *line, struct gpiod_chip *chip);
-void line_set_offset(struct gpiod_line *line, unsigned int offset);
-
-int chip_get_fd(struct gpiod_chip *chip);
-
-#endif /* __GPIOD_INTERNAL_H__ */
* as published by the Free Software Foundation.
*/
-#include "gpiod-internal.h"
+#include <gpiod.h>
#include <string.h>
#include <stdint.h>
int state;
bool up_to_date;
struct gpiod_chip *chip;
+ int fd;
struct gpioline_info info;
union {
struct handle_data *handle;
}
}
-void line_set_offset(struct gpiod_line *line, unsigned int offset)
+struct gpiod_line *
+line_new(unsigned int offset, struct gpiod_chip *chip, int info_fd)
{
+ struct gpiod_line *line;
+
+ line = malloc(sizeof(*line));
+ if (!line)
+ return NULL;
+
+ memset(line, 0, sizeof(*line));
+
line->info.line_offset = offset;
-}
+ line->chip = chip;
+ line->fd = info_fd;
-struct gpiod_chip * gpiod_line_get_chip(struct gpiod_line *line)
-{
- return line->chip;
+ return line;
}
-struct gpiod_line * line_array_alloc(size_t numlines)
+void line_free(struct gpiod_line *line)
{
- return calloc(numlines, sizeof(struct gpiod_line));
+ free(line);
}
-void line_array_free(struct gpiod_line *lines)
+void line_set_offset(struct gpiod_line *line, unsigned int offset)
{
- free(lines);
+ line->info.line_offset = offset;
}
-struct gpiod_line * line_array_member(struct gpiod_line *lines, size_t index)
+struct gpiod_chip * gpiod_line_get_chip(struct gpiod_line *line)
{
- return &lines[index];
+ return line->chip;
}
void line_set_chip(struct gpiod_line *line, struct gpiod_chip *chip)
int gpiod_line_update(struct gpiod_line *line)
{
- struct gpiod_chip *chip;
- int status, fd;
+ int status;
memset(line->info.name, 0, sizeof(line->info.name));
memset(line->info.consumer, 0, sizeof(line->info.consumer));
line->info.flags = 0;
- chip = gpiod_line_get_chip(line);
- fd = chip_get_fd(chip);
-
- status = ioctl(fd, GPIO_GET_LINEINFO_IOCTL, &line->info);
+ status = ioctl(line->fd, GPIO_GET_LINEINFO_IOCTL, &line->info);
if (status < 0)
return -1;
{
struct gpiohandle_request *req;
struct handle_data *handle;
- struct gpiod_chip *chip;
struct gpiod_line *line;
int status, fd;
unsigned int i;
strncpy(req->consumer_label, config->consumer,
sizeof(req->consumer_label) - 1);
- chip = gpiod_line_get_chip(bulk->lines[0]);
- fd = chip_get_fd(chip);
+ fd = bulk->lines[0]->fd;
status = ioctl(fd, GPIO_GET_LINEHANDLE_IOCTL, req);
if (status < 0)
struct gpiod_line_evreq_config *config)
{
struct gpioevent_request *req;
- struct gpiod_chip *chip;
- int status, fd;
+ int status;
if (!gpiod_line_is_free(line)) {
errno = EBUSY;
else if (config->event_type == GPIOD_EVENT_BOTH_EDGES)
req->eventflags |= GPIOEVENT_REQUEST_BOTH_EDGES;
- chip = gpiod_line_get_chip(line);
- fd = chip_get_fd(chip);
-
- status = ioctl(fd, GPIO_GET_LINEEVENT_IOCTL, req);
+ status = ioctl(line->fd, GPIO_GET_LINEEVENT_IOCTL, req);
if (status < 0)
return -1;
--- /dev/null
+/*
+ * Internal GPIO line-related prototypes.
+ *
+ * Copyright (C) 2017 Bartosz Golaszewski <bartekgola@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2.1 of the GNU Lesser General Public License
+ * as published by the Free Software Foundation.
+ */
+
+#ifndef __GPIOD_INTERNAL_LINE_H__
+#define __GPIOD_INTERNAL_LINE_H__
+
+#include <gpiod.h>
+
+struct gpiod_line *
+line_new(unsigned int offset, struct gpiod_chip *chip, int info_fd);
+void line_free(struct gpiod_line *line);
+
+#endif /* __GPIOD_INTERNAL_LINE_H__ */