From: Bartosz Golaszewski Date: Sat, 24 Jun 2017 10:48:54 +0000 (+0200) Subject: core: move the simple API definitions into a separate file X-Git-Url: http://git.maquefel.me/?a=commitdiff_plain;h=f323eff5b1b4dc8c13e8b9eee80bde780669c4be;p=qemu-gpiodev%2Flibgpiod.git core: move the simple API definitions into a separate file This is the first step in splitting up the core library code. Signed-off-by: Bartosz Golaszewski --- diff --git a/src/lib/Makefile.am b/src/lib/Makefile.am index 622687a..dbcd8a4 100644 --- a/src/lib/Makefile.am +++ b/src/lib/Makefile.am @@ -7,7 +7,7 @@ # lib_LTLIBRARIES = libgpiod.la -libgpiod_la_SOURCES = core.c +libgpiod_la_SOURCES = core.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 diff --git a/src/lib/core.c b/src/lib/core.c index c123028..3864f94 100644 --- a/src/lib/core.c +++ b/src/lib/core.c @@ -74,160 +74,6 @@ static bool is_unsigned_int(const char *str) return *str == '\0'; } -int gpiod_simple_get_value_multiple(const char *consumer, const char *device, - const unsigned int *offsets, int *values, - unsigned int num_lines, bool active_low) -{ - struct gpiod_line_bulk bulk; - struct gpiod_chip *chip; - struct gpiod_line *line; - unsigned int i; - int status; - - if (num_lines > GPIOD_REQUEST_MAX_LINES) { - errno = EINVAL; - return -1; - } - - chip = gpiod_chip_open_lookup(device); - if (!chip) - return -1; - - gpiod_line_bulk_init(&bulk); - - for (i = 0; i < num_lines; i++) { - line = gpiod_chip_get_line(chip, offsets[i]); - if (!line) { - gpiod_chip_close(chip); - return -1; - } - - gpiod_line_bulk_add(&bulk, line); - } - - status = gpiod_line_request_bulk_input(&bulk, consumer, active_low); - if (status < 0) { - gpiod_chip_close(chip); - return -1; - } - - memset(values, 0, sizeof(*values) * num_lines); - status = gpiod_line_get_value_bulk(&bulk, values); - - gpiod_line_release_bulk(&bulk); - gpiod_chip_close(chip); - - return status; -} - -int gpiod_simple_set_value_multiple(const char *consumer, const char *device, - const unsigned int *offsets, - const int *values, unsigned int num_lines, - bool active_low, gpiod_set_value_cb cb, - void *data) -{ - struct gpiod_line_bulk bulk; - struct gpiod_chip *chip; - struct gpiod_line *line; - unsigned int i; - int status; - - if (num_lines > GPIOD_REQUEST_MAX_LINES) { - errno = EINVAL; - return -1; - } - - chip = gpiod_chip_open_lookup(device); - if (!chip) - return -1; - - gpiod_line_bulk_init(&bulk); - - for (i = 0; i < num_lines; i++) { - line = gpiod_chip_get_line(chip, offsets[i]); - if (!line) { - gpiod_chip_close(chip); - return -1; - } - - gpiod_line_bulk_add(&bulk, line); - } - - status = gpiod_line_request_bulk_output(&bulk, consumer, - active_low, values); - if (status < 0) { - gpiod_chip_close(chip); - return -1; - } - - if (cb) - cb(data); - - gpiod_line_release_bulk(&bulk); - gpiod_chip_close(chip); - - return 0; -} - -int gpiod_simple_event_loop(const char *consumer, const char *device, - unsigned int offset, bool active_low, - const struct timespec *timeout, - gpiod_event_cb callback, void *cbdata) -{ - struct gpiod_line_event event; - struct gpiod_chip *chip; - struct gpiod_line *line; - int status, evtype; - - chip = gpiod_chip_open_lookup(device); - if (!chip) - return -1; - - line = gpiod_chip_get_line(chip, offset); - if (!line) { - gpiod_chip_close(chip); - return -1; - } - - status = gpiod_line_event_request_all(line, consumer, active_low); - if (status < 0) { - gpiod_chip_close(chip); - return -1; - } - - for (;;) { - status = gpiod_line_event_wait(line, timeout); - if (status < 0) { - if (errno == EINTR) - return evtype = GPIOD_EVENT_CB_TIMEOUT; - else - goto out; - } else if (status == 0) { - evtype = GPIOD_EVENT_CB_TIMEOUT; - } else { - status = gpiod_line_event_read(line, &event); - if (status < 0) - goto out; - - evtype = event.event_type == GPIOD_EVENT_RISING_EDGE - ? GPIOD_EVENT_CB_RISING_EDGE - : GPIOD_EVENT_CB_FALLING_EDGE; - } - - status = callback(evtype, &event.ts, cbdata); - if (status == GPIOD_EVENT_CB_STOP) { - status = 0; - goto out; - } - } - -out: - gpiod_line_event_release(line); - gpiod_chip_close(chip); - - return status; -} - static void line_set_offset(struct gpiod_line *line, unsigned int offset) { line->info.line_offset = offset; diff --git a/src/lib/simple.c b/src/lib/simple.c new file mode 100644 index 0000000..ff86a3a --- /dev/null +++ b/src/lib/simple.c @@ -0,0 +1,168 @@ +/* + * Simple API for libgpiod. + * + * Copyright (C) 2017 Bartosz Golaszewski + * + * 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. + */ + +#include + +#include +#include + +int gpiod_simple_get_value_multiple(const char *consumer, const char *device, + const unsigned int *offsets, int *values, + unsigned int num_lines, bool active_low) +{ + struct gpiod_line_bulk bulk; + struct gpiod_chip *chip; + struct gpiod_line *line; + unsigned int i; + int status; + + if (num_lines > GPIOD_REQUEST_MAX_LINES) { + errno = EINVAL; + return -1; + } + + chip = gpiod_chip_open_lookup(device); + if (!chip) + return -1; + + gpiod_line_bulk_init(&bulk); + + for (i = 0; i < num_lines; i++) { + line = gpiod_chip_get_line(chip, offsets[i]); + if (!line) { + gpiod_chip_close(chip); + return -1; + } + + gpiod_line_bulk_add(&bulk, line); + } + + status = gpiod_line_request_bulk_input(&bulk, consumer, active_low); + if (status < 0) { + gpiod_chip_close(chip); + return -1; + } + + memset(values, 0, sizeof(*values) * num_lines); + status = gpiod_line_get_value_bulk(&bulk, values); + + gpiod_line_release_bulk(&bulk); + gpiod_chip_close(chip); + + return status; +} + +int gpiod_simple_set_value_multiple(const char *consumer, const char *device, + const unsigned int *offsets, + const int *values, unsigned int num_lines, + bool active_low, gpiod_set_value_cb cb, + void *data) +{ + struct gpiod_line_bulk bulk; + struct gpiod_chip *chip; + struct gpiod_line *line; + unsigned int i; + int status; + + if (num_lines > GPIOD_REQUEST_MAX_LINES) { + errno = EINVAL; + return -1; + } + + chip = gpiod_chip_open_lookup(device); + if (!chip) + return -1; + + gpiod_line_bulk_init(&bulk); + + for (i = 0; i < num_lines; i++) { + line = gpiod_chip_get_line(chip, offsets[i]); + if (!line) { + gpiod_chip_close(chip); + return -1; + } + + gpiod_line_bulk_add(&bulk, line); + } + + status = gpiod_line_request_bulk_output(&bulk, consumer, + active_low, values); + if (status < 0) { + gpiod_chip_close(chip); + return -1; + } + + if (cb) + cb(data); + + gpiod_line_release_bulk(&bulk); + gpiod_chip_close(chip); + + return 0; +} + +int gpiod_simple_event_loop(const char *consumer, const char *device, + unsigned int offset, bool active_low, + const struct timespec *timeout, + gpiod_event_cb callback, void *cbdata) +{ + struct gpiod_line_event event; + struct gpiod_chip *chip; + struct gpiod_line *line; + int status, evtype; + + chip = gpiod_chip_open_lookup(device); + if (!chip) + return -1; + + line = gpiod_chip_get_line(chip, offset); + if (!line) { + gpiod_chip_close(chip); + return -1; + } + + status = gpiod_line_event_request_all(line, consumer, active_low); + if (status < 0) { + gpiod_chip_close(chip); + return -1; + } + + for (;;) { + status = gpiod_line_event_wait(line, timeout); + if (status < 0) { + if (errno == EINTR) + return evtype = GPIOD_EVENT_CB_TIMEOUT; + else + goto out; + } else if (status == 0) { + evtype = GPIOD_EVENT_CB_TIMEOUT; + } else { + status = gpiod_line_event_read(line, &event); + if (status < 0) + goto out; + + evtype = event.event_type == GPIOD_EVENT_RISING_EDGE + ? GPIOD_EVENT_CB_RISING_EDGE + : GPIOD_EVENT_CB_FALLING_EDGE; + } + + status = callback(evtype, &event.ts, cbdata); + if (status == GPIOD_EVENT_CB_STOP) { + status = 0; + goto out; + } + } + +out: + gpiod_line_event_release(line); + gpiod_chip_close(chip); + + return status; +}