From: Bartosz Golaszewski Date: Thu, 22 Feb 2018 20:15:43 +0000 (+0100) Subject: API: provide new line accessors X-Git-Url: http://git.maquefel.me/?a=commitdiff_plain;h=6b6bed27cc7b31d87c5dfc9792f4f7165d73a1f9;p=qemu-gpiodev%2Flibgpiod.git API: provide new line accessors Add two new public functions that allow to retrieve multiple lines from GPIO chips at once. Include test cases. Signed-off-by: Bartosz Golaszewski --- diff --git a/include/gpiod.h b/include/gpiod.h index eb3f81c..c8ba3e2 100644 --- a/include/gpiod.h +++ b/include/gpiod.h @@ -47,6 +47,7 @@ struct gpiod_chip; struct gpiod_line; struct gpiod_chip_iter; struct gpiod_line_iter; +struct gpiod_line_bulk; /** * @defgroup __common__ Common helper macros @@ -395,6 +396,27 @@ unsigned int gpiod_chip_num_lines(struct gpiod_chip *chip) GPIOD_API; struct gpiod_line * gpiod_chip_get_line(struct gpiod_chip *chip, unsigned int offset) GPIOD_API; +/** + * @brief Retrieve a set of lines and store them in a line bulk object. + * @param chip The GPIO chip object. + * @param offsets Array of offsets of lines to retrieve. + * @param num_offsets Number of lines to retrieve. + * @param bulk Line bulk object in which to store the line handles. + * @return 0 on success, -1 on error. + */ +int gpiod_chip_get_lines(struct gpiod_chip *chip, + unsigned int *offsets, unsigned int num_offsets, + struct gpiod_line_bulk *bulk) GPIOD_API; + +/** + * @brief Retrieve all lines exposed by a chip and store them in a bulk object. + * @param chip The GPIO chip object. + * @param bulk Line bulk object in which to store the line handles. + * @return 0 on success, -1 on error. + */ +int gpiod_chip_get_all_lines(struct gpiod_chip *chip, + struct gpiod_line_bulk *bulk) GPIOD_API; + /** * @brief Find a GPIO line by name among lines associated with given GPIO chip. * @param chip The GPIO chip object. diff --git a/src/lib/helpers.c b/src/lib/helpers.c index 94643fa..f479a42 100644 --- a/src/lib/helpers.c +++ b/src/lib/helpers.c @@ -103,6 +103,45 @@ struct gpiod_chip *gpiod_chip_open_lookup(const char *descr) return chip; } +int gpiod_chip_get_lines(struct gpiod_chip *chip, unsigned int *offsets, + unsigned int num_offsets, struct gpiod_line_bulk *bulk) +{ + struct gpiod_line *line; + unsigned int i; + + gpiod_line_bulk_init(bulk); + + for (i = 0; i < num_offsets; i++) { + line = gpiod_chip_get_line(chip, offsets[i]); + if (!line) + return -1; + + gpiod_line_bulk_add(bulk, line); + } + + return 0; +} + +int gpiod_chip_get_all_lines(struct gpiod_chip *chip, + struct gpiod_line_bulk *bulk) +{ + struct gpiod_line_iter *iter; + struct gpiod_line *line; + + gpiod_line_bulk_init(bulk); + + iter = gpiod_line_iter_new(chip); + if (!iter) + return -1; + + gpiod_foreach_line(iter, line) + gpiod_line_bulk_add(bulk, line); + + gpiod_line_iter_free(iter); + + return 0; +} + struct gpiod_line * gpiod_chip_find_line(struct gpiod_chip *chip, const char *name) { diff --git a/tests/tests-chip.c b/tests/tests-chip.c index 3262dec..3fa1cbd 100644 --- a/tests/tests-chip.c +++ b/tests/tests-chip.c @@ -195,6 +195,66 @@ TEST_DEFINE(chip_num_lines, "gpiod_chip_num_lines()", 0, { 1, 4, 8, 16, 32 }); +static void chip_get_lines(void) +{ + TEST_CLEANUP(test_close_chip) struct gpiod_chip *chip = NULL; + struct gpiod_line_bulk bulk; + unsigned int offsets[4]; + struct gpiod_line *line; + int rv; + + chip = gpiod_chip_open(test_chip_path(0)); + TEST_ASSERT_NOT_NULL(chip); + + offsets[0] = 1; + offsets[1] = 3; + offsets[2] = 4; + offsets[3] = 7; + + rv = gpiod_chip_get_lines(chip, offsets, 4, &bulk); + TEST_ASSERT_RET_OK(rv); + + TEST_ASSERT_EQ(gpiod_line_bulk_num_lines(&bulk), 4); + line = gpiod_line_bulk_get_line(&bulk, 0); + TEST_ASSERT_EQ(gpiod_line_offset(line), 1); + line = gpiod_line_bulk_get_line(&bulk, 1); + TEST_ASSERT_EQ(gpiod_line_offset(line), 3); + line = gpiod_line_bulk_get_line(&bulk, 2); + TEST_ASSERT_EQ(gpiod_line_offset(line), 4); + line = gpiod_line_bulk_get_line(&bulk, 3); + TEST_ASSERT_EQ(gpiod_line_offset(line), 7); +} +TEST_DEFINE(chip_get_lines, + "gpiod_chip_get_lines()", + 0, { 16 }); + +static void chip_get_all_lines(void) +{ + TEST_CLEANUP(test_close_chip) struct gpiod_chip *chip = NULL; + struct gpiod_line_bulk bulk; + struct gpiod_line *line; + int rv; + + chip = gpiod_chip_open(test_chip_path(0)); + TEST_ASSERT_NOT_NULL(chip); + + rv = gpiod_chip_get_all_lines(chip, &bulk); + TEST_ASSERT_RET_OK(rv); + + TEST_ASSERT_EQ(gpiod_line_bulk_num_lines(&bulk), 4); + line = gpiod_line_bulk_get_line(&bulk, 0); + TEST_ASSERT_EQ(gpiod_line_offset(line), 0); + line = gpiod_line_bulk_get_line(&bulk, 1); + TEST_ASSERT_EQ(gpiod_line_offset(line), 1); + line = gpiod_line_bulk_get_line(&bulk, 2); + TEST_ASSERT_EQ(gpiod_line_offset(line), 2); + line = gpiod_line_bulk_get_line(&bulk, 3); + TEST_ASSERT_EQ(gpiod_line_offset(line), 3); +} +TEST_DEFINE(chip_get_all_lines, + "gpiod_chip_get_all_lines()", + 0, { 4 }); + static void chip_find_line_good(void) { TEST_CLEANUP(test_close_chip) struct gpiod_chip *chip = NULL;