From: Bartosz Golaszewski Date: Tue, 17 Jan 2017 08:15:47 +0000 (+0100) Subject: core: new set/get value helpers X-Git-Url: http://git.maquefel.me/?a=commitdiff_plain;h=542b908ce5374baae463a3f2eecdfc2fdded4a65;p=qemu-gpiodev%2Flibgpiod.git core: new set/get value helpers Implement simple set/get value routines for multiple lines. Signed-off-by: Bartosz Golaszewski --- diff --git a/include/gpiod.h b/include/gpiod.h index efd5d4c..59f0b22 100644 --- a/include/gpiod.h +++ b/include/gpiod.h @@ -117,16 +117,55 @@ const char * gpiod_last_strerror(void) GPIOD_API; * Simple high-level routines for straightforward GPIO manipulation. */ +/** + * @brief Read current values from a set of GPIO lines. + * @param device Name, path or number of the gpiochip. + * @param offsets An array of offsets of lines whose values should be read. + * @param values A buffer in which the values will be stored. + * @param num_lines Number of lines. + * @param active_low The active state of the lines - true if low. + * @return 0 if the operation succeeds, -1 on error. + */ +int gpiod_simple_get_value_multiple(const char *device, unsigned int *offsets, + int *values, unsigned int num_lines, + bool active_low) GPIOD_API; + /** * @brief Read current value from a single GPIO line. * @param device Name, path or number of the gpiochip. * @param offset GPIO line offset on the chip. * @param active_low The active state of this line - true if low. - * @return 0 or 1 if the operation succeeds. On error this routine returns -1 - * and sets the last error number. + * @return 0 or 1 (GPIO value) if the operation succeeds, -1 on error. */ -int gpiod_simple_get_value(const char *device, - unsigned int offset, bool active_low) GPIOD_API; +static inline int gpiod_simple_get_value(const char *device, + unsigned int offset, bool active_low) +{ + int value, status; + + status = gpiod_simple_get_value_multiple(device, &offset, + &value, 1, active_low); + if (status < 0) + return status; + + return value; +} + +/** + * @brief Set values of a set of a set of GPIO lines. + * @param device Name, path or number of the gpiochip. + * @param offsets An array of offsets of lines whose values should be set. + * @param values An array of integers containing new values. + * @param num_lines Number of lines. + * @param active_low The active state of the lines - true if low. + * @param cb Callback function that will be called right after the values are + * set. + * @param data User data that will be passed to the callback function. + * @return 0 if the operation succeeds, -1 on error. + */ +int gpiod_simple_set_value_multiple(const char *device, unsigned int *offsets, + int *values, unsigned int num_lines, + bool active_low, void (*cb)(void *), + void *data) GPIOD_API; /** * @brief Set value of a single GPIO line. @@ -138,12 +177,16 @@ int gpiod_simple_get_value(const char *device, * set. Users can use this, for example, to pause the execution after * toggling a GPIO. * @param data User data that will be passed to the callback function. - * @return 0 or 1 if the operation succeeds. On error this routine returns -1 - * and sets the last error number. + * @return 0 if the operation succeeds, -1 on error. */ -int gpiod_simple_set_value(const char *device, unsigned int offset, - int value, bool active_low, void (*cb)(void *), - void *data) GPIOD_API; +static inline int gpiod_simple_set_value(const char *device, + unsigned int offset, int value, + bool active_low, void (*cb)(void *), + void *data) +{ + return gpiod_simple_set_value_multiple(device, &offset, &value, 1, + active_low, cb, data); +} /** * @brief Event types that can be passed to the simple event callback. diff --git a/src/lib/core.c b/src/lib/core.c index ae8bc23..9ec925f 100644 --- a/src/lib/core.c +++ b/src/lib/core.c @@ -158,56 +158,77 @@ const char * gpiod_last_strerror(void) return gpiod_strerror(gpiod_errno()); } -int gpiod_simple_get_value(const char *device, - unsigned int offset, bool active_low) +int gpiod_simple_get_value_multiple(const char *device, 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; - int status, value; + unsigned int i; + int status; 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; + 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_input(line, libgpiod_consumer, active_low); + status = gpiod_line_request_bulk_input(&bulk, + libgpiod_consumer, active_low); if (status < 0) { gpiod_chip_close(chip); return -1; } - value = gpiod_line_get_value(line); + memset(values, 0, sizeof(*values) * num_lines); + status = gpiod_line_get_value_bulk(&bulk, values); - gpiod_line_release(line); + gpiod_line_release_bulk(&bulk); gpiod_chip_close(chip); - return value; + return status; } -int gpiod_simple_set_value(const char *device, unsigned int offset, int value, - bool active_low, void (*cb)(void *), void *data) +int gpiod_simple_set_value_multiple(const char *device, unsigned int *offsets, + int *values, unsigned int num_lines, + bool active_low, void (*cb)(void *), + void *data) { + struct gpiod_line_bulk bulk; struct gpiod_chip *chip; struct gpiod_line *line; + unsigned int i; int status; 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; + 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_output(line, libgpiod_consumer, - active_low, value); + status = gpiod_line_request_bulk_output(&bulk, libgpiod_consumer, + active_low, values); if (status < 0) { gpiod_chip_close(chip); return -1; @@ -216,7 +237,7 @@ int gpiod_simple_set_value(const char *device, unsigned int offset, int value, if (cb) cb(data); - gpiod_line_release(line); + gpiod_line_release_bulk(&bulk); gpiod_chip_close(chip); return 0;