@@ -35,6 +35,7 @@ extern "C" {
struct gpiod_chip;
struct gpiod_line;
+struct gpiod_line_info;
struct gpiod_line_bulk;
/**
@@ -110,6 +111,17 @@ const char *gpiod_chip_get_label(struct gpiod_chip *chip);
*/
unsigned int gpiod_chip_get_num_lines(struct gpiod_chip *chip);
+/**
+ * @brief Get the current snapshot of information about the line at given
+ * offset.
+ * @param chip The GPIO chip object.
+ * @param offset The offset of the GPIO line.
+ * @return New GPIO line info object that must be freed using
+ * ::gpiod_line_info_free or NULL if an error occurred.
+ */
+struct gpiod_line_info *gpiod_chip_get_line_info(struct gpiod_chip *chip,
+ unsigned int offset);
+
/**
* @brief Get the handle to the GPIO line at given offset.
* @param chip The GPIO chip object.
@@ -286,6 +298,20 @@ enum {
/**< The internal pull-down bias is enabled. */
};
+/**
+ * @brief Possible edge detection settings.
+ */
+enum {
+ GPIOD_LINE_EDGE_NONE = 1,
+ /**< Line edge detection is disabled. */
+ GPIOD_LINE_EDGE_RISING,
+ /**< Line detects rising edge events. */
+ GPIOD_LINE_EDGE_FALLING,
+ /**< Line detect falling edge events. */
+ GPIOD_LINE_EDGE_BOTH,
+ /**< Line detects both rising and falling edge events. */
+};
+
/**
* @brief Read the GPIO line offset.
* @param line GPIO line object.
@@ -293,64 +319,111 @@ enum {
*/
unsigned int gpiod_line_offset(struct gpiod_line *line);
+/**
+ * @brief Increase the reference count for this line info object.
+ * @param info GPIO line info object.
+ * @return Passed reference to the line info object.
+ */
+struct gpiod_line_info *
+gpiod_line_info_ref(struct gpiod_line_info *info);
+
+/**
+ * @brief Decrease the reference count on this line info object. If it reaches
+ * 0, then free all associated resources.
+ * @param info GPIO line info object.
+ */
+void gpiod_line_info_unref(struct gpiod_line_info *info);
+
+/**
+ * @brief Get the hardware offset of the line.
+ * @param info GPIO line info object.
+ * @return Offset of the line within the parent chip.
+ */
+unsigned int gpiod_line_info_get_offset(struct gpiod_line_info *info);
+
/**
* @brief Read the GPIO line name.
- * @param line GPIO line object.
+ * @param info GPIO line info object.
* @return Name of the GPIO line as it is represented in the kernel. This
* routine returns a pointer to a null-terminated string or NULL if
* the line is unnamed.
*/
-const char *gpiod_line_name(struct gpiod_line *line);
+const char *gpiod_line_get_name(struct gpiod_line_info *info);
+
+/**
+ * @brief Check if the line is currently in use.
+ * @param info GPIO line object.
+ * @return True if the line is in use, false otherwise.
+ *
+ * The user space can't know exactly why a line is busy. It may have been
+ * requested by another process or hogged by the kernel. It only matters that
+ * the line is used and we can't request it.
+ */
+bool gpiod_line_is_used(struct gpiod_line_info *info);
/**
* @brief Read the GPIO line consumer name.
- * @param line GPIO line object.
+ * @param info GPIO line info object.
* @return Name of the GPIO consumer name as it is represented in the
* kernel. This routine returns a pointer to a null-terminated string
* or NULL if the line is not used.
*/
-const char *gpiod_line_consumer(struct gpiod_line *line);
+const char *gpiod_line_get_consumer(struct gpiod_line_info *info);
/**
* @brief Read the GPIO line direction setting.
- * @param line GPIO line object.
+ * @param info GPIO line info object.
* @return Returns GPIOD_LINE_DIRECTION_INPUT or GPIOD_LINE_DIRECTION_OUTPUT.
*/
-int gpiod_line_direction(struct gpiod_line *line);
+int gpiod_line_get_direction(struct gpiod_line_info *info);
/**
* @brief Check if the signal of this line is inverted.
- * @param line GPIO line object.
+ * @param info GPIO line object.
* @return True if this line is "active-low", false otherwise.
*/
-bool gpiod_line_is_active_low(struct gpiod_line *line);
+bool gpiod_line_is_active_low(struct gpiod_line_info *info);
/**
* @brief Read the GPIO line bias setting.
- * @param line GPIO line object.
+ * @param info GPIO line object.
* @return Returns GPIOD_LINE_BIAS_PULL_UP, GPIOD_LINE_BIAS_PULL_DOWN,
* GPIOD_LINE_BIAS_DISABLE or GPIOD_LINE_BIAS_UNKNOWN.
*/
-int gpiod_line_bias(struct gpiod_line *line);
-
-/**
- * @brief Check if the line is currently in use.
- * @param line GPIO line object.
- * @return True if the line is in use, false otherwise.
- *
- * The user space can't know exactly why a line is busy. It may have been
- * requested by another process or hogged by the kernel. It only matters that
- * the line is used and we can't request it.
- */
-bool gpiod_line_is_used(struct gpiod_line *line);
+int gpiod_line_get_bias(struct gpiod_line_info *info);
/**
* @brief Read the GPIO line drive setting.
- * @param line GPIO line object.
+ * @param info GPIO line info object.
* @return Returns GPIOD_LINE_DRIVE_PUSH_PULL, GPIOD_LINE_DRIVE_OPEN_DRAIN or
* GPIOD_LINE_DRIVE_OPEN_SOURCE.
*/
-int gpiod_line_drive(struct gpiod_line *line);
+int gpiod_line_get_drive(struct gpiod_line_info *info);
+
+/**
+ * @brief Read the current edge detection setting of this line.
+ * @param info GPIO line info object.
+ * @return Returns GPIOD_LINE_EDGE_NONE, GPIOD_LINE_EDGE_RISING,
+ * GPIOD_LINE_EDGE_FALLING or GPIOD_LINE_EDGE_BOTH.
+ */
+int gpiod_line_get_edge_detection(struct gpiod_line_info *info);
+
+/**
+ * @brief Check if this line is debounced (either by hardware or by the kernel
+ * software debouncer).
+ * @param info GPIO line info object.
+ * @return True if the line is debounced, false otherwise.
+ */
+bool gpiod_line_is_debounced(struct gpiod_line_info *info);
+
+/**
+ * @brief Read the current debounce period in microseconds.
+ * @param info GPIO line info object.
+ * @return Current debounce period in microseconds, 0 if the line is not
+ * debounced.
+ */
+unsigned long
+gpiod_line_get_debounce_period(struct gpiod_line_info *info);
/**
* @brief Get the handle to the GPIO chip controlling this line.
@@ -2,7 +2,7 @@
# SPDX-FileCopyrightText: 2017-2021 Bartosz Golaszewski <bartekgola@gmail.com>
lib_LTLIBRARIES = libgpiod.la
-libgpiod_la_SOURCES = core.c helpers.c internal.c internal.h misc.c uapi/gpio.h
+libgpiod_la_SOURCES = core.c helpers.c internal.c internal.h info.c misc.c uapi/gpio.h
libgpiod_la_CFLAGS = -Wall -Wextra -g -std=gnu89
libgpiod_la_CFLAGS += -fvisibility=hidden -I$(top_srcdir)/include/
libgpiod_la_CFLAGS += -include $(top_builddir)/config.h
@@ -180,6 +180,22 @@ GPIOD_API void gpiod_line_bulk_foreach_line(struct gpiod_line_bulk *bulk,
(index) < (bulk)->num_lines; \
(index)++, (line) = (bulk)->lines[(index)])
+GPIOD_API struct gpiod_line_info *
+gpiod_chip_get_line_info(struct gpiod_chip *chip, unsigned int offset)
+{
+ struct gpio_v2_line_info infobuf;
+ int ret;
+
+ memset(&infobuf, 0, sizeof(infobuf));
+ infobuf.offset = offset;
+
+ ret = ioctl(chip->fd, GPIO_V2_GET_LINEINFO_IOCTL, &infobuf);
+ if (ret < 0)
+ return NULL;
+
+ return gpiod_line_info_from_kernel(&infobuf);
+}
+
GPIOD_API bool gpiod_is_gpiochip_device(const char *path)
{
char *realname, *sysfsp, devpath[64];
@@ -449,53 +465,6 @@ GPIOD_API unsigned int gpiod_line_offset(struct gpiod_line *line)
return line->offset;
}
-GPIOD_API const char *gpiod_line_name(struct gpiod_line *line)
-{
- return line->name[0] == '\0' ? NULL : line->name;
-}
-
-GPIOD_API const char *gpiod_line_consumer(struct gpiod_line *line)
-{
- return line->consumer[0] == '\0' ? NULL : line->consumer;
-}
-
-GPIOD_API int gpiod_line_direction(struct gpiod_line *line)
-{
- return line->direction;
-}
-
-GPIOD_API bool gpiod_line_is_active_low(struct gpiod_line *line)
-{
- return line->active_low;
-}
-
-GPIOD_API int gpiod_line_bias(struct gpiod_line *line)
-{
- if (line->info_flags & GPIOLINE_FLAG_BIAS_DISABLE)
- return GPIOD_LINE_BIAS_DISABLED;
- if (line->info_flags & GPIOLINE_FLAG_BIAS_PULL_UP)
- return GPIOD_LINE_BIAS_PULL_UP;
- if (line->info_flags & GPIOLINE_FLAG_BIAS_PULL_DOWN)
- return GPIOD_LINE_BIAS_PULL_DOWN;
-
- return GPIOD_LINE_BIAS_UNKNOWN;
-}
-
-GPIOD_API bool gpiod_line_is_used(struct gpiod_line *line)
-{
- return line->info_flags & GPIOLINE_FLAG_KERNEL;
-}
-
-GPIOD_API int gpiod_line_drive(struct gpiod_line *line)
-{
- if (line->info_flags & GPIOLINE_FLAG_OPEN_DRAIN)
- return GPIOD_LINE_DRIVE_OPEN_DRAIN;
- if (line->info_flags & GPIOLINE_FLAG_OPEN_SOURCE)
- return GPIOD_LINE_DRIVE_OPEN_SOURCE;
-
- return GPIOD_LINE_DRIVE_PUSH_PULL;
-}
-
static int line_info_v2_to_info_flags(struct gpio_v2_line_info *info)
{
int iflags = 0;
@@ -65,19 +65,23 @@ gpiod_chip_get_all_lines(struct gpiod_chip *chip)
GPIOD_API int gpiod_chip_find_line(struct gpiod_chip *chip, const char *name)
{
unsigned int offset, num_lines;
- struct gpiod_line *line;
+ struct gpiod_line_info *info;
const char *tmp;
num_lines = gpiod_chip_get_num_lines(chip);
for (offset = 0; offset < num_lines; offset++) {
- line = gpiod_chip_get_line(chip, offset);
- if (!line)
+ info = gpiod_chip_get_line_info(chip, offset);
+ if (!info)
return -1;
- tmp = gpiod_line_name(line);
- if (tmp && strcmp(tmp, name) == 0)
- return gpiod_line_offset(line);
+ tmp = gpiod_line_get_name(info);
+ if (tmp && strcmp(tmp, name) == 0) {
+ gpiod_line_info_unref(info);
+ return offset;
+ }
+
+ gpiod_line_info_unref(info);
}
errno = ENOENT;
new file mode 100644
@@ -0,0 +1,170 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// SPDX-FileCopyrightText: 2021 Bartosz Golaszewski <brgl@bgdev.pl>
+
+#include <gpiod.h>
+#include <string.h>
+
+#include "internal.h"
+#include "uapi/gpio.h"
+
+struct gpiod_line_info {
+ struct gpiod_refcount refcount;
+ unsigned int offset;
+ char name[GPIO_MAX_NAME_SIZE];
+ bool used;
+ char consumer[GPIO_MAX_NAME_SIZE];
+ int direction;
+ bool active_low;
+ int bias;
+ int drive;
+ int edge;
+ bool debounced;
+ unsigned long debounce_period;
+};
+
+GPIOD_API struct gpiod_line_info *
+gpiod_line_info_ref(struct gpiod_line_info *info)
+{
+ gpiod_refcount_ref(&info->refcount);
+ return info;
+}
+
+static void line_info_release(struct gpiod_refcount *refcount)
+{
+ struct gpiod_line_info *info;
+
+ info = gpiod_container_of(refcount, struct gpiod_line_info, refcount);
+
+ free(info);
+}
+
+GPIOD_API void gpiod_line_info_unref(struct gpiod_line_info *info)
+{
+ gpiod_refcount_unref(&info->refcount);
+}
+
+GPIOD_API unsigned int gpiod_line_info_get_offset(struct gpiod_line_info *info)
+{
+ return info->offset;
+}
+
+GPIOD_API const char *gpiod_line_get_name(struct gpiod_line_info *info)
+{
+ return info->name[0] == '\0' ? NULL : info->name;
+}
+
+GPIOD_API bool gpiod_line_is_used(struct gpiod_line_info *info)
+{
+ return info->used;
+}
+
+GPIOD_API const char *gpiod_line_get_consumer(struct gpiod_line_info *info)
+{
+ return info->consumer[0] == '\0' ? NULL : info->consumer;
+}
+
+GPIOD_API int gpiod_line_get_direction(struct gpiod_line_info *info)
+{
+ return info->direction;
+}
+
+GPIOD_API bool gpiod_line_is_active_low(struct gpiod_line_info *info)
+{
+ return info->active_low;
+}
+
+GPIOD_API int gpiod_line_get_bias(struct gpiod_line_info *info)
+{
+ return info->bias;
+}
+
+GPIOD_API int gpiod_line_get_drive(struct gpiod_line_info *info)
+{
+ return info->drive;
+}
+
+GPIOD_API int gpiod_line_get_edge_detection(struct gpiod_line_info *info)
+{
+ return info->edge;
+}
+
+GPIOD_API bool gpiod_line_is_debounced(struct gpiod_line_info *info)
+{
+ return info->debounced;
+}
+
+GPIOD_API unsigned long
+gpiod_line_get_debounce_period(struct gpiod_line_info *info)
+{
+ return info->debounce_period;
+}
+
+struct gpiod_line_info *
+gpiod_line_info_from_kernel(struct gpio_v2_line_info *infobuf)
+{
+ struct gpio_v2_line_attribute *attr;
+ struct gpiod_line_info *info;
+ unsigned int i;
+
+ info = malloc(sizeof(*info));
+ if (!info)
+ return NULL;
+
+ memset(info, 0, sizeof(*info));
+
+ gpiod_refcount_init(&info->refcount, line_info_release);
+ info->offset = infobuf->offset;
+ strncpy(info->name, infobuf->name, GPIO_MAX_NAME_SIZE);
+
+ info->used = !!(infobuf->flags & GPIO_V2_LINE_FLAG_USED);
+ strncpy(info->consumer, infobuf->consumer, GPIO_MAX_NAME_SIZE);
+
+ if (infobuf->flags & GPIO_V2_LINE_FLAG_OUTPUT)
+ info->direction = GPIOD_LINE_DIRECTION_OUTPUT;
+ else
+ info->direction = GPIOD_LINE_DIRECTION_INPUT;
+
+ if (infobuf->flags & GPIO_V2_LINE_FLAG_ACTIVE_LOW)
+ info->active_low = true;
+
+ if (infobuf->flags & GPIO_V2_LINE_FLAG_BIAS_PULL_UP)
+ info->bias = GPIOD_LINE_BIAS_PULL_UP;
+ else if (infobuf->flags & GPIO_V2_LINE_FLAG_BIAS_PULL_DOWN)
+ info->bias = GPIOD_LINE_BIAS_PULL_DOWN;
+ else if (infobuf->flags & GPIO_V2_LINE_FLAG_BIAS_DISABLED)
+ info->bias = GPIOD_LINE_BIAS_DISABLED;
+ else
+ info->bias = GPIOD_LINE_BIAS_UNKNOWN;
+
+ if (infobuf->flags & GPIO_V2_LINE_FLAG_OPEN_DRAIN)
+ info->drive = GPIOD_LINE_DRIVE_OPEN_DRAIN;
+ else if (infobuf->flags & GPIO_V2_LINE_FLAG_OPEN_SOURCE)
+ info->drive = GPIOD_LINE_DRIVE_OPEN_SOURCE;
+ else
+ info->drive = GPIOD_LINE_DRIVE_PUSH_PULL;
+
+ if ((infobuf->flags & GPIO_V2_LINE_FLAG_EDGE_RISING) &&
+ (infobuf->flags & GPIO_V2_LINE_FLAG_EDGE_FALLING))
+ info->edge = GPIOD_LINE_EDGE_BOTH;
+ else if (infobuf->flags & GPIO_V2_LINE_FLAG_EDGE_RISING)
+ info->edge = GPIOD_LINE_EDGE_RISING;
+ else if (infobuf->flags & GPIO_V2_LINE_FLAG_EDGE_FALLING)
+ info->edge = GPIOD_LINE_EDGE_FALLING;
+ else
+ info->edge = GPIOD_LINE_EDGE_NONE;
+
+ /*
+ * We assume that the kernel returns correct configuration and that no
+ * attributes repeat.
+ */
+ for (i = 0; i < infobuf->num_attrs; i++) {
+ attr = &infobuf->attrs[i];
+
+ if (attr->id == GPIO_V2_LINE_ATTR_ID_DEBOUNCE) {
+ info->debounced = true;
+ info->debounce_period = attr->debounce_period_us;
+ }
+ }
+
+ return info;
+}
@@ -4,8 +4,11 @@
#ifndef __LIBGPIOD_GPIOD_INTERNAL_H__
#define __LIBGPIOD_GPIOD_INTERNAL_H__
+#include <gpiod.h>
#include <stddef.h>
+#include "uapi/gpio.h"
+
/* For internal library use only. */
#define GPIOD_API __attribute__((visibility("default")))
@@ -27,4 +30,7 @@ void gpiod_refcount_init(struct gpiod_refcount *refcount,
void gpiod_refcount_ref(struct gpiod_refcount *refcount);
void gpiod_refcount_unref(struct gpiod_refcount *refcount);
+struct gpiod_line_info *
+gpiod_line_info_from_kernel(struct gpio_v2_line_info *infobuf);
+
#endif /* __LIBGPIOD_GPIOD_INTERNAL_H__ */
@@ -21,9 +21,11 @@
*/
typedef struct gpiod_chip gpiod_chip_struct;
typedef struct gpiod_line_bulk gpiod_line_bulk_struct;
+typedef struct gpiod_line_info gpiod_line_info_struct;
G_DEFINE_AUTOPTR_CLEANUP_FUNC(gpiod_chip_struct, gpiod_chip_unref);
G_DEFINE_AUTOPTR_CLEANUP_FUNC(gpiod_line_bulk_struct, gpiod_line_bulk_free);
+G_DEFINE_AUTOPTR_CLEANUP_FUNC(gpiod_line_info_struct, gpiod_line_info_unref);
/* These are private definitions and should not be used directly. */
typedef void (*_gpiod_test_func)(void);
@@ -195,8 +195,8 @@ GPIOD_TEST_CASE(get_all_lines, 0, { 4 })
GPIOD_TEST_CASE(find_line_good, GPIOD_TEST_FLAG_NAMED_LINES, { 8, 8, 8 })
{
+ g_autoptr(gpiod_line_info_struct) info = NULL;
g_autoptr(gpiod_chip_struct) chip = NULL;
- struct gpiod_line *line;
int offset;
chip = gpiod_chip_open(gpiod_test_chip_path(1));
@@ -207,11 +207,11 @@ GPIOD_TEST_CASE(find_line_good, GPIOD_TEST_FLAG_NAMED_LINES, { 8, 8, 8 })
g_assert_cmpint(offset, ==, 4);
gpiod_test_return_if_failed();
- line = gpiod_chip_get_line(chip, 4);
- g_assert_nonnull(line);
+ info = gpiod_chip_get_line_info(chip, 4);
+ g_assert_nonnull(info);
gpiod_test_return_if_failed();
- g_assert_cmpstr(gpiod_line_name(line), ==, "gpio-mockup-B-4");
+ g_assert_cmpstr(gpiod_line_get_name(info), ==, "gpio-mockup-B-4");
}
GPIOD_TEST_CASE(find_line_unique_not_found,
@@ -58,8 +58,43 @@ GPIOD_TEST_CASE(request_already_requested, 0, { 8 })
g_assert_cmpint(errno, ==, EBUSY);
}
+GPIOD_TEST_CASE(line_name, GPIOD_TEST_FLAG_NAMED_LINES, { 8 })
+{
+ g_autoptr(gpiod_line_info_struct) info = NULL;
+ g_autoptr(gpiod_chip_struct) chip = NULL;
+
+ chip = gpiod_chip_open(gpiod_test_chip_path(0));
+ g_assert_nonnull(chip);
+ gpiod_test_return_if_failed();
+
+ info = gpiod_chip_get_line_info(chip, 2);
+ g_assert_nonnull(info);
+ gpiod_test_return_if_failed();
+
+ g_assert_nonnull(gpiod_line_get_name(info));
+ g_assert_cmpstr(gpiod_line_get_name(info), ==, "gpio-mockup-A-2");
+}
+
+GPIOD_TEST_CASE(line_name_unnamed, 0, { 8 })
+{
+ g_autoptr(gpiod_line_info_struct) info = NULL;
+ g_autoptr(gpiod_chip_struct) chip = NULL;
+
+ chip = gpiod_chip_open(gpiod_test_chip_path(0));
+ g_assert_nonnull(chip);
+ gpiod_test_return_if_failed();
+
+ info = gpiod_chip_get_line_info(chip, 2);
+ g_assert_nonnull(info);
+ gpiod_test_return_if_failed();
+
+ g_assert_null(gpiod_line_get_name(info));
+}
+
GPIOD_TEST_CASE(consumer, 0, { 8 })
{
+ g_autoptr(gpiod_line_info_struct) info_before = NULL;
+ g_autoptr(gpiod_line_info_struct) info_after = NULL;
g_autoptr(gpiod_chip_struct) chip = NULL;
struct gpiod_line *line;
gint ret;
@@ -72,15 +107,25 @@ GPIOD_TEST_CASE(consumer, 0, { 8 })
g_assert_nonnull(line);
gpiod_test_return_if_failed();
- g_assert_null(gpiod_line_consumer(line));
+ info_before = gpiod_chip_get_line_info(chip, 0);
+ g_assert_nonnull(info_before);
+ gpiod_test_return_if_failed();
+ g_assert_null(gpiod_line_get_consumer(info_before));
ret = gpiod_line_request_input(line, GPIOD_TEST_CONSUMER);
g_assert_cmpint(ret, ==, 0);
- g_assert_cmpstr(gpiod_line_consumer(line), ==, GPIOD_TEST_CONSUMER);
+
+ info_after = gpiod_chip_get_line_info(chip, 0);
+ g_assert_nonnull(info_after);
+ gpiod_test_return_if_failed();
+ g_assert_cmpstr(gpiod_line_get_consumer(info_after),
+ ==, GPIOD_TEST_CONSUMER);
}
GPIOD_TEST_CASE(consumer_long_string, 0, { 8 })
{
+ g_autoptr(gpiod_line_info_struct) info_before = NULL;
+ g_autoptr(gpiod_line_info_struct) info_after = NULL;
g_autoptr(gpiod_chip_struct) chip = NULL;
struct gpiod_line *line;
gint ret;
@@ -93,15 +138,22 @@ GPIOD_TEST_CASE(consumer_long_string, 0, { 8 })
g_assert_nonnull(line);
gpiod_test_return_if_failed();
- g_assert_null(gpiod_line_consumer(line));
+ info_before = gpiod_chip_get_line_info(chip, 0);
+ g_assert_nonnull(info_before);
+ gpiod_test_return_if_failed();
+ g_assert_null(gpiod_line_get_consumer(info_before));
ret = gpiod_line_request_input(line,
"consumer string over 32 characters long");
g_assert_cmpint(ret, ==, 0);
gpiod_test_return_if_failed();
- g_assert_cmpstr(gpiod_line_consumer(line), ==,
+
+ info_after = gpiod_chip_get_line_info(chip, 0);
+ g_assert_nonnull(info_after);
+ gpiod_test_return_if_failed();
+ g_assert_cmpstr(gpiod_line_get_consumer(info_after), ==,
"consumer string over 32 charact");
- g_assert_cmpuint(strlen(gpiod_line_consumer(line)), ==, 31);
+ g_assert_cmpuint(strlen(gpiod_line_get_consumer(info_after)), ==, 31);
}
GPIOD_TEST_CASE(request_bulk_output, 0, { 8, 8 })
@@ -336,9 +388,6 @@ GPIOD_TEST_CASE(set_config_bulk_null_values, 0, { 8 })
ret = gpiod_line_request_bulk_output(bulk, GPIOD_TEST_CONSUMER, 0);
g_assert_cmpint(ret, ==, 0);
gpiod_test_return_if_failed();
- g_assert_false(gpiod_line_is_active_low(line0));
- g_assert_false(gpiod_line_is_active_low(line1));
- g_assert_false(gpiod_line_is_active_low(line2));
g_assert_cmpint(gpiod_test_chip_get_value(0, 0), ==, 0);
g_assert_cmpint(gpiod_test_chip_get_value(0, 1), ==, 0);
@@ -348,9 +397,7 @@ GPIOD_TEST_CASE(set_config_bulk_null_values, 0, { 8 })
GPIOD_LINE_REQUEST_DIRECTION_OUTPUT,
GPIOD_LINE_REQUEST_FLAG_ACTIVE_LOW, NULL);
g_assert_cmpint(ret, ==, 0);
- g_assert_true(gpiod_line_is_active_low(line0));
- g_assert_true(gpiod_line_is_active_low(line1));
- g_assert_true(gpiod_line_is_active_low(line2));
+
g_assert_cmpint(gpiod_test_chip_get_value(0, 0), ==, 1);
g_assert_cmpint(gpiod_test_chip_get_value(0, 1), ==, 1);
g_assert_cmpint(gpiod_test_chip_get_value(0, 2), ==, 1);
@@ -358,9 +405,7 @@ GPIOD_TEST_CASE(set_config_bulk_null_values, 0, { 8 })
ret = gpiod_line_set_config_bulk(bulk,
GPIOD_LINE_REQUEST_DIRECTION_OUTPUT, 0, NULL);
g_assert_cmpint(ret, ==, 0);
- g_assert_false(gpiod_line_is_active_low(line0));
- g_assert_false(gpiod_line_is_active_low(line1));
- g_assert_false(gpiod_line_is_active_low(line2));
+
g_assert_cmpint(gpiod_test_chip_get_value(0, 0), ==, 0);
g_assert_cmpint(gpiod_test_chip_get_value(0, 1), ==, 0);
g_assert_cmpint(gpiod_test_chip_get_value(0, 2), ==, 0);
@@ -368,6 +413,9 @@ GPIOD_TEST_CASE(set_config_bulk_null_values, 0, { 8 })
GPIOD_TEST_CASE(set_flags_active_state, 0, { 8 })
{
+ g_autoptr(gpiod_line_info_struct) info0 = NULL;
+ g_autoptr(gpiod_line_info_struct) info1 = NULL;
+ g_autoptr(gpiod_line_info_struct) info2 = NULL;
g_autoptr(gpiod_chip_struct) chip = NULL;
struct gpiod_line *line;
gint ret;
@@ -383,22 +431,41 @@ GPIOD_TEST_CASE(set_flags_active_state, 0, { 8 })
ret = gpiod_line_request_output(line, GPIOD_TEST_CONSUMER, 1);
g_assert_cmpint(ret, ==, 0);
gpiod_test_return_if_failed();
- g_assert_false(gpiod_line_is_active_low(line));
+
+ info0 = gpiod_chip_get_line_info(chip, 2);
+ g_assert_nonnull(info0);
+ gpiod_test_return_if_failed();
+ g_assert_false(gpiod_line_is_active_low(info0));
+
g_assert_cmpint(gpiod_test_chip_get_value(0, 2), ==, 1);
ret = gpiod_line_set_flags(line, GPIOD_LINE_REQUEST_FLAG_ACTIVE_LOW);
g_assert_cmpint(ret, ==, 0);
- g_assert_true(gpiod_line_is_active_low(line));
+
+ info1 = gpiod_chip_get_line_info(chip, 2);
+ g_assert_nonnull(info1);
+ gpiod_test_return_if_failed();
+ g_assert_true(gpiod_line_is_active_low(info1));
+
g_assert_cmpint(gpiod_test_chip_get_value(0, 2), ==, 0);
ret = gpiod_line_set_flags(line, 0);
g_assert_cmpint(ret, ==, 0);
- g_assert_false(gpiod_line_is_active_low(line));
+
+ info2 = gpiod_chip_get_line_info(chip, 2);
+ g_assert_nonnull(info2);
+ gpiod_test_return_if_failed();
+ g_assert_false(gpiod_line_is_active_low(info2));
+
g_assert_cmpint(gpiod_test_chip_get_value(0, 2), ==, 1);
}
GPIOD_TEST_CASE(set_flags_bias, 0, { 8 })
{
+ g_autoptr(gpiod_line_info_struct) info0 = NULL;
+ g_autoptr(gpiod_line_info_struct) info1 = NULL;
+ g_autoptr(gpiod_line_info_struct) info2 = NULL;
+ g_autoptr(gpiod_line_info_struct) info3 = NULL;
g_autoptr(gpiod_chip_struct) chip = NULL;
struct gpiod_line *line;
gint ret;
@@ -414,28 +481,50 @@ GPIOD_TEST_CASE(set_flags_bias, 0, { 8 })
ret = gpiod_line_request_input(line, GPIOD_TEST_CONSUMER);
g_assert_cmpint(ret, ==, 0);
gpiod_test_return_if_failed();
- g_assert_cmpint(gpiod_line_bias(line), ==, GPIOD_LINE_BIAS_UNKNOWN);
+
+ info0 = gpiod_chip_get_line_info(chip, 2);
+ g_assert_nonnull(info0);
+ gpiod_test_return_if_failed();
+ g_assert_cmpint(gpiod_line_get_bias(info0), ==,
+ GPIOD_LINE_BIAS_UNKNOWN);
ret = gpiod_line_set_flags(line,
GPIOD_LINE_REQUEST_FLAG_BIAS_DISABLED);
g_assert_cmpint(ret, ==, 0);
- g_assert_cmpint(gpiod_line_bias(line), ==, GPIOD_LINE_BIAS_DISABLED);
+
+ info1 = gpiod_chip_get_line_info(chip, 2);
+ g_assert_nonnull(info1);
+ gpiod_test_return_if_failed();
+ g_assert_cmpint(gpiod_line_get_bias(info1), ==,
+ GPIOD_LINE_BIAS_DISABLED);
ret = gpiod_line_set_flags(line,
GPIOD_LINE_REQUEST_FLAG_BIAS_PULL_UP);
g_assert_cmpint(ret, ==, 0);
- g_assert_cmpint(gpiod_line_bias(line), ==, GPIOD_LINE_BIAS_PULL_UP);
g_assert_cmpint(gpiod_test_chip_get_value(0, 2), ==, 1);
+ info2 = gpiod_chip_get_line_info(chip, 2);
+ g_assert_nonnull(info2);
+ gpiod_test_return_if_failed();
+ g_assert_cmpint(gpiod_line_get_bias(info2), ==,
+ GPIOD_LINE_BIAS_PULL_UP);
+
ret = gpiod_line_set_flags(line,
GPIOD_LINE_REQUEST_FLAG_BIAS_PULL_DOWN);
g_assert_cmpint(ret, ==, 0);
- g_assert_cmpint(gpiod_line_bias(line), ==, GPIOD_LINE_BIAS_PULL_DOWN);
g_assert_cmpint(gpiod_test_chip_get_value(0, 2), ==, 0);
+
+ info3 = gpiod_chip_get_line_info(chip, 2);
+ g_assert_nonnull(info3);
+ gpiod_test_return_if_failed();
+ g_assert_cmpint(gpiod_line_get_bias(info3), ==, GPIOD_LINE_BIAS_PULL_DOWN);
}
GPIOD_TEST_CASE(set_flags_drive, 0, { 8 })
{
+ g_autoptr(gpiod_line_info_struct) info0 = NULL;
+ g_autoptr(gpiod_line_info_struct) info1 = NULL;
+ g_autoptr(gpiod_line_info_struct) info2 = NULL;
g_autoptr(gpiod_chip_struct) chip = NULL;
struct gpiod_line *line;
gint ret;
@@ -451,23 +540,39 @@ GPIOD_TEST_CASE(set_flags_drive, 0, { 8 })
ret = gpiod_line_request_output(line, GPIOD_TEST_CONSUMER, 0);
g_assert_cmpint(ret, ==, 0);
gpiod_test_return_if_failed();
- g_assert_cmpint(gpiod_line_drive(line), ==, GPIOD_LINE_DRIVE_PUSH_PULL);
+
+ info0 = gpiod_chip_get_line_info(chip, 2);
+ g_assert_nonnull(info0);
+ gpiod_test_return_if_failed();
+ g_assert_cmpint(gpiod_line_get_drive(info0), ==,
+ GPIOD_LINE_DRIVE_PUSH_PULL);
ret = gpiod_line_set_flags(line,
GPIOD_LINE_REQUEST_FLAG_OPEN_DRAIN);
g_assert_cmpint(ret, ==, 0);
- g_assert_cmpint(gpiod_line_drive(line), ==,
+
+ info1 = gpiod_chip_get_line_info(chip, 2);
+ g_assert_nonnull(info1);
+ gpiod_test_return_if_failed();
+ g_assert_cmpint(gpiod_line_get_drive(info1), ==,
GPIOD_LINE_DRIVE_OPEN_DRAIN);
ret = gpiod_line_set_flags(line,
GPIOD_LINE_REQUEST_FLAG_OPEN_SOURCE);
g_assert_cmpint(ret, ==, 0);
- g_assert_cmpint(gpiod_line_drive(line), ==,
+
+ info2 = gpiod_chip_get_line_info(chip, 2);
+ g_assert_nonnull(info2);
+ gpiod_test_return_if_failed();
+ g_assert_cmpint(gpiod_line_get_drive(info2), ==,
GPIOD_LINE_DRIVE_OPEN_SOURCE);
}
GPIOD_TEST_CASE(set_direction, 0, { 8 })
{
+ g_autoptr(gpiod_line_info_struct) info0 = NULL;
+ g_autoptr(gpiod_line_info_struct) info1 = NULL;
+ g_autoptr(gpiod_line_info_struct) info2 = NULL;
g_autoptr(gpiod_chip_struct) chip = NULL;
struct gpiod_line *line;
gint ret;
@@ -483,24 +588,49 @@ GPIOD_TEST_CASE(set_direction, 0, { 8 })
ret = gpiod_line_request_output(line, GPIOD_TEST_CONSUMER, 0);
g_assert_cmpint(ret, ==, 0);
gpiod_test_return_if_failed();
- g_assert_cmpint(gpiod_line_direction(line), ==,
- GPIOD_LINE_DIRECTION_OUTPUT);
g_assert_cmpint(gpiod_test_chip_get_value(0, 2), ==, 0);
+ info0 = gpiod_chip_get_line_info(chip, 2);
+ g_assert_nonnull(info0);
+ gpiod_test_return_if_failed();
+ g_assert_cmpint(gpiod_line_get_direction(info0), ==,
+ GPIOD_LINE_DIRECTION_OUTPUT);
+
ret = gpiod_line_set_direction_input(line);
g_assert_cmpint(ret, ==, 0);
- g_assert_cmpint(gpiod_line_direction(line), ==,
+
+ info1 = gpiod_chip_get_line_info(chip, 2);
+ g_assert_nonnull(info1);
+ gpiod_test_return_if_failed();
+ g_assert_cmpint(gpiod_line_get_direction(info1), ==,
GPIOD_LINE_DIRECTION_INPUT);
ret = gpiod_line_set_direction_output(line, 1);
g_assert_cmpint(ret, ==, 0);
- g_assert_cmpint(gpiod_line_direction(line), ==,
+ g_assert_cmpint(gpiod_test_chip_get_value(0, 2), ==, 1);
+
+ info2 = gpiod_chip_get_line_info(chip, 2);
+ g_assert_nonnull(info2);
+ gpiod_test_return_if_failed();
+ g_assert_cmpint(gpiod_line_get_direction(info2), ==,
GPIOD_LINE_DIRECTION_OUTPUT);
g_assert_cmpint(gpiod_test_chip_get_value(0, 2), ==, 1);
}
GPIOD_TEST_CASE(set_direction_bulk, 0, { 8 })
{
+ g_autoptr(gpiod_line_info_struct) info0_0 = NULL;
+ g_autoptr(gpiod_line_info_struct) info0_1 = NULL;
+ g_autoptr(gpiod_line_info_struct) info0_2 = NULL;
+ g_autoptr(gpiod_line_info_struct) info1_0 = NULL;
+ g_autoptr(gpiod_line_info_struct) info1_1 = NULL;
+ g_autoptr(gpiod_line_info_struct) info1_2 = NULL;
+ g_autoptr(gpiod_line_info_struct) info2_0 = NULL;
+ g_autoptr(gpiod_line_info_struct) info2_1 = NULL;
+ g_autoptr(gpiod_line_info_struct) info2_2 = NULL;
+ g_autoptr(gpiod_line_info_struct) info3_0 = NULL;
+ g_autoptr(gpiod_line_info_struct) info3_1 = NULL;
+ g_autoptr(gpiod_line_info_struct) info3_2 = NULL;
g_autoptr(gpiod_line_bulk_struct) bulk = NULL;
g_autoptr(gpiod_chip_struct) chip = NULL;
struct gpiod_line *line0, *line1, *line2;
@@ -536,23 +666,42 @@ GPIOD_TEST_CASE(set_direction_bulk, 0, { 8 })
GPIOD_TEST_CONSUMER, values);
g_assert_cmpint(ret, ==, 0);
gpiod_test_return_if_failed();
- g_assert_cmpint(gpiod_line_direction(line0), ==,
+
+ info0_0 = gpiod_chip_get_line_info(chip, 0);
+ info0_1 = gpiod_chip_get_line_info(chip, 1);
+ info0_2 = gpiod_chip_get_line_info(chip, 2);
+ g_assert_nonnull(info0_0);
+ g_assert_nonnull(info0_1);
+ g_assert_nonnull(info0_2);
+ gpiod_test_return_if_failed();
+
+ g_assert_cmpint(gpiod_line_get_direction(info0_0), ==,
GPIOD_LINE_DIRECTION_OUTPUT);
- g_assert_cmpint(gpiod_line_direction(line1), ==,
+ g_assert_cmpint(gpiod_line_get_direction(info0_1), ==,
GPIOD_LINE_DIRECTION_OUTPUT);
- g_assert_cmpint(gpiod_line_direction(line2), ==,
+ g_assert_cmpint(gpiod_line_get_direction(info0_2), ==,
GPIOD_LINE_DIRECTION_OUTPUT);
+
g_assert_cmpint(gpiod_test_chip_get_value(0, 0), ==, 0);
g_assert_cmpint(gpiod_test_chip_get_value(0, 1), ==, 1);
g_assert_cmpint(gpiod_test_chip_get_value(0, 2), ==, 1);
ret = gpiod_line_set_direction_input_bulk(bulk);
g_assert_cmpint(ret, ==, 0);
- g_assert_cmpint(gpiod_line_direction(line0), ==,
+
+ info1_0 = gpiod_chip_get_line_info(chip, 0);
+ info1_1 = gpiod_chip_get_line_info(chip, 1);
+ info1_2 = gpiod_chip_get_line_info(chip, 2);
+ g_assert_nonnull(info1_0);
+ g_assert_nonnull(info1_1);
+ g_assert_nonnull(info1_2);
+ gpiod_test_return_if_failed();
+
+ g_assert_cmpint(gpiod_line_get_direction(info1_0), ==,
GPIOD_LINE_DIRECTION_INPUT);
- g_assert_cmpint(gpiod_line_direction(line1), ==,
+ g_assert_cmpint(gpiod_line_get_direction(info1_1), ==,
GPIOD_LINE_DIRECTION_INPUT);
- g_assert_cmpint(gpiod_line_direction(line2), ==,
+ g_assert_cmpint(gpiod_line_get_direction(info1_2), ==,
GPIOD_LINE_DIRECTION_INPUT);
values[0] = 2;
@@ -561,24 +710,44 @@ GPIOD_TEST_CASE(set_direction_bulk, 0, { 8 })
ret = gpiod_line_set_direction_output_bulk(bulk, values);
g_assert_cmpint(ret, ==, 0);
- g_assert_cmpint(gpiod_line_direction(line0), ==,
+
+ info2_0 = gpiod_chip_get_line_info(chip, 0);
+ info2_1 = gpiod_chip_get_line_info(chip, 1);
+ info2_2 = gpiod_chip_get_line_info(chip, 2);
+ g_assert_nonnull(info2_0);
+ g_assert_nonnull(info2_1);
+ g_assert_nonnull(info2_2);
+ gpiod_test_return_if_failed();
+
+ g_assert_cmpint(gpiod_line_get_direction(info2_0), ==,
GPIOD_LINE_DIRECTION_OUTPUT);
- g_assert_cmpint(gpiod_line_direction(line1), ==,
+ g_assert_cmpint(gpiod_line_get_direction(info2_1), ==,
GPIOD_LINE_DIRECTION_OUTPUT);
- g_assert_cmpint(gpiod_line_direction(line2), ==,
+ g_assert_cmpint(gpiod_line_get_direction(info2_2), ==,
GPIOD_LINE_DIRECTION_OUTPUT);
+
g_assert_cmpint(gpiod_test_chip_get_value(0, 0), ==, 1);
g_assert_cmpint(gpiod_test_chip_get_value(0, 1), ==, 1);
g_assert_cmpint(gpiod_test_chip_get_value(0, 2), ==, 0);
ret = gpiod_line_set_direction_output_bulk(bulk, NULL);
g_assert_cmpint(ret, ==, 0);
- g_assert_cmpint(gpiod_line_direction(line0), ==,
+
+ info3_0 = gpiod_chip_get_line_info(chip, 0);
+ info3_1 = gpiod_chip_get_line_info(chip, 1);
+ info3_2 = gpiod_chip_get_line_info(chip, 2);
+ g_assert_nonnull(info3_0);
+ g_assert_nonnull(info3_1);
+ g_assert_nonnull(info3_2);
+ gpiod_test_return_if_failed();
+
+ g_assert_cmpint(gpiod_line_get_direction(info3_0), ==,
GPIOD_LINE_DIRECTION_OUTPUT);
- g_assert_cmpint(gpiod_line_direction(line1), ==,
+ g_assert_cmpint(gpiod_line_get_direction(info3_1), ==,
GPIOD_LINE_DIRECTION_OUTPUT);
- g_assert_cmpint(gpiod_line_direction(line2), ==,
+ g_assert_cmpint(gpiod_line_get_direction(info3_2), ==,
GPIOD_LINE_DIRECTION_OUTPUT);
+
g_assert_cmpint(gpiod_test_chip_get_value(0, 0), ==, 0);
g_assert_cmpint(gpiod_test_chip_get_value(0, 1), ==, 0);
g_assert_cmpint(gpiod_test_chip_get_value(0, 2), ==, 0);
@@ -658,6 +827,8 @@ GPIOD_TEST_CASE(output_value_caching, 0, { 8 })
GPIOD_TEST_CASE(direction, 0, { 8 })
{
+ g_autoptr(gpiod_line_info_struct) info0 = NULL;
+ g_autoptr(gpiod_line_info_struct) info1 = NULL;
g_autoptr(gpiod_chip_struct) chip = NULL;
struct gpiod_line *line;
gint ret;
@@ -673,7 +844,12 @@ GPIOD_TEST_CASE(direction, 0, { 8 })
ret = gpiod_line_request_output(line, GPIOD_TEST_CONSUMER, 1);
g_assert_cmpint(ret, ==, 0);
gpiod_test_return_if_failed();
- g_assert_cmpint(gpiod_line_direction(line), ==,
+
+ info0 = gpiod_chip_get_line_info(chip, 5);
+ g_assert_nonnull(info0);
+ gpiod_test_return_if_failed();
+
+ g_assert_cmpint(gpiod_line_get_direction(info0), ==,
GPIOD_LINE_DIRECTION_OUTPUT);
g_assert_cmpint(gpiod_test_chip_get_value(0, 5), ==, 1);
@@ -681,12 +857,21 @@ GPIOD_TEST_CASE(direction, 0, { 8 })
ret = gpiod_line_request_input(line, GPIOD_TEST_CONSUMER);
g_assert_cmpint(ret, ==, 0);
- g_assert_cmpint(gpiod_line_direction(line), ==,
+
+ info1 = gpiod_chip_get_line_info(chip, 5);
+ g_assert_nonnull(info1);
+ gpiod_test_return_if_failed();
+
+ g_assert_cmpint(gpiod_line_get_direction(info1), ==,
GPIOD_LINE_DIRECTION_INPUT);
}
GPIOD_TEST_CASE(active_state, 0, { 8 })
{
+ g_autoptr(gpiod_line_info_struct) info0 = NULL;
+ g_autoptr(gpiod_line_info_struct) info1 = NULL;
+ g_autoptr(gpiod_line_info_struct) info2 = NULL;
+ g_autoptr(gpiod_line_info_struct) info3 = NULL;
g_autoptr(gpiod_chip_struct) chip = NULL;
struct gpiod_line *line;
gint ret;
@@ -703,7 +888,11 @@ GPIOD_TEST_CASE(active_state, 0, { 8 })
g_assert_cmpint(ret, ==, 0);
gpiod_test_return_if_failed();
- g_assert_false(gpiod_line_is_active_low(line));
+ info0 = gpiod_chip_get_line_info(chip, 5);
+ g_assert_nonnull(info0);
+ gpiod_test_return_if_failed();
+
+ g_assert_false(gpiod_line_is_active_low(info0));
gpiod_line_release(line);
@@ -712,7 +901,11 @@ GPIOD_TEST_CASE(active_state, 0, { 8 })
g_assert_cmpint(ret, ==, 0);
gpiod_test_return_if_failed();
- g_assert_cmpint(gpiod_line_direction(line), ==,
+ info1 = gpiod_chip_get_line_info(chip, 5);
+ g_assert_nonnull(info1);
+ gpiod_test_return_if_failed();
+
+ g_assert_cmpint(gpiod_line_get_direction(info1), ==,
GPIOD_LINE_DIRECTION_INPUT);
gpiod_line_release(line);
@@ -722,7 +915,11 @@ GPIOD_TEST_CASE(active_state, 0, { 8 })
g_assert_cmpint(ret, ==, 0);
gpiod_test_return_if_failed();
- g_assert_cmpint(gpiod_line_direction(line), ==,
+ info2 = gpiod_chip_get_line_info(chip, 5);
+ g_assert_nonnull(info2);
+ gpiod_test_return_if_failed();
+
+ g_assert_cmpint(gpiod_line_get_direction(info2), ==,
GPIOD_LINE_DIRECTION_OUTPUT);
g_assert_cmpint(gpiod_test_chip_get_value(0, 5), ==, 1);
@@ -733,7 +930,11 @@ GPIOD_TEST_CASE(active_state, 0, { 8 })
g_assert_cmpint(ret, ==, 0);
gpiod_test_return_if_failed();
- g_assert_cmpint(gpiod_line_direction(line), ==,
+ info3 = gpiod_chip_get_line_info(chip, 5);
+ g_assert_nonnull(info3);
+ gpiod_test_return_if_failed();
+
+ g_assert_cmpint(gpiod_line_get_direction(info3), ==,
GPIOD_LINE_DIRECTION_OUTPUT);
g_assert_cmpint(gpiod_test_chip_get_value(0, 5), ==, 0);
@@ -741,6 +942,9 @@ GPIOD_TEST_CASE(active_state, 0, { 8 })
GPIOD_TEST_CASE(misc_flags, 0, { 8 })
{
+ g_autoptr(gpiod_line_info_struct) info0 = NULL;
+ g_autoptr(gpiod_line_info_struct) info1 = NULL;
+ g_autoptr(gpiod_line_info_struct) info2 = NULL;
g_autoptr(gpiod_chip_struct) chip = NULL;
struct gpiod_line_request_config config;
struct gpiod_line *line;
@@ -754,9 +958,15 @@ GPIOD_TEST_CASE(misc_flags, 0, { 8 })
g_assert_nonnull(line);
gpiod_test_return_if_failed();
- g_assert_false(gpiod_line_is_used(line));
- g_assert_cmpint(gpiod_line_drive(line), ==, GPIOD_LINE_DRIVE_PUSH_PULL);
- g_assert_cmpint(gpiod_line_bias(line), ==, GPIOD_LINE_BIAS_UNKNOWN);
+ info0 = gpiod_chip_get_line_info(chip, 2);
+ g_assert_nonnull(info0);
+ gpiod_test_return_if_failed();
+
+ g_assert_false(gpiod_line_is_used(info0));
+ g_assert_cmpint(gpiod_line_get_drive(info0), ==,
+ GPIOD_LINE_DRIVE_PUSH_PULL);
+ g_assert_cmpint(gpiod_line_get_bias(info0), ==,
+ GPIOD_LINE_BIAS_UNKNOWN);
config.request_type = GPIOD_LINE_REQUEST_DIRECTION_OUTPUT;
config.consumer = GPIOD_TEST_CONSUMER;
@@ -766,11 +976,16 @@ GPIOD_TEST_CASE(misc_flags, 0, { 8 })
g_assert_cmpint(ret, ==, 0);
gpiod_test_return_if_failed();
- g_assert_true(gpiod_line_is_used(line));
- g_assert_cmpint(gpiod_line_drive(line), ==,
+ info1 = gpiod_chip_get_line_info(chip, 2);
+ g_assert_nonnull(info1);
+ gpiod_test_return_if_failed();
+
+ g_assert_true(gpiod_line_is_used(info1));
+ g_assert_cmpint(gpiod_line_get_drive(info1), ==,
GPIOD_LINE_DRIVE_OPEN_DRAIN);
- g_assert_cmpint(gpiod_line_bias(line), ==, GPIOD_LINE_BIAS_UNKNOWN);
- g_assert_cmpint(gpiod_line_direction(line), ==,
+ g_assert_cmpint(gpiod_line_get_bias(info1), ==,
+ GPIOD_LINE_BIAS_UNKNOWN);
+ g_assert_cmpint(gpiod_line_get_direction(info1), ==,
GPIOD_LINE_DIRECTION_OUTPUT);
gpiod_line_release(line);
@@ -781,11 +996,16 @@ GPIOD_TEST_CASE(misc_flags, 0, { 8 })
g_assert_cmpint(ret, ==, 0);
gpiod_test_return_if_failed();
- g_assert_true(gpiod_line_is_used(line));
- g_assert_cmpint(gpiod_line_drive(line), ==,
+ info2 = gpiod_chip_get_line_info(chip, 2);
+ g_assert_nonnull(info2);
+ gpiod_test_return_if_failed();
+
+ g_assert_true(gpiod_line_is_used(info2));
+ g_assert_cmpint(gpiod_line_get_drive(info2), ==,
GPIOD_LINE_DRIVE_OPEN_SOURCE);
- g_assert_cmpint(gpiod_line_bias(line), ==, GPIOD_LINE_BIAS_UNKNOWN);
- g_assert_cmpint(gpiod_line_direction(line), ==,
+ g_assert_cmpint(gpiod_line_get_bias(info2), ==,
+ GPIOD_LINE_BIAS_UNKNOWN);
+ g_assert_cmpint(gpiod_line_get_direction(info2), ==,
GPIOD_LINE_DIRECTION_OUTPUT);
gpiod_line_release(line);
@@ -793,6 +1013,10 @@ GPIOD_TEST_CASE(misc_flags, 0, { 8 })
GPIOD_TEST_CASE(misc_flags_work_together, 0, { 8 })
{
+ g_autoptr(gpiod_line_info_struct) info0 = NULL;
+ g_autoptr(gpiod_line_info_struct) info1 = NULL;
+ g_autoptr(gpiod_line_info_struct) info2 = NULL;
+ g_autoptr(gpiod_line_info_struct) info3 = NULL;
g_autoptr(gpiod_chip_struct) chip = NULL;
struct gpiod_line_request_config config;
struct gpiod_line *line;
@@ -820,12 +1044,16 @@ GPIOD_TEST_CASE(misc_flags_work_together, 0, { 8 })
g_assert_cmpint(ret, ==, 0);
gpiod_test_return_if_failed();
- g_assert_true(gpiod_line_is_used(line));
- g_assert_cmpint(gpiod_line_drive(line), ==,
+ info0 = gpiod_chip_get_line_info(chip, 2);
+ g_assert_nonnull(info0);
+ gpiod_test_return_if_failed();
+
+ g_assert_true(gpiod_line_is_used(info0));
+ g_assert_cmpint(gpiod_line_get_drive(info0), ==,
GPIOD_LINE_DRIVE_OPEN_DRAIN);
- g_assert_cmpint(gpiod_line_bias(line), ==, GPIOD_LINE_BIAS_UNKNOWN);
- g_assert_true(gpiod_line_is_active_low(line));
- g_assert_cmpint(gpiod_line_direction(line), ==,
+ g_assert_cmpint(gpiod_line_get_bias(info0), ==, GPIOD_LINE_BIAS_UNKNOWN);
+ g_assert_true(gpiod_line_is_active_low(info0));
+ g_assert_cmpint(gpiod_line_get_direction(info0), ==,
GPIOD_LINE_DIRECTION_OUTPUT);
gpiod_line_release(line);
@@ -837,11 +1065,16 @@ GPIOD_TEST_CASE(misc_flags_work_together, 0, { 8 })
g_assert_cmpint(ret, ==, 0);
gpiod_test_return_if_failed();
- g_assert_true(gpiod_line_is_used(line));
- g_assert_cmpint(gpiod_line_drive(line), ==,
+ info1 = gpiod_chip_get_line_info(chip, 2);
+ g_assert_nonnull(info1);
+ gpiod_test_return_if_failed();
+
+ g_assert_true(gpiod_line_is_used(info1));
+ g_assert_cmpint(gpiod_line_get_drive(info1), ==,
GPIOD_LINE_DRIVE_OPEN_SOURCE);
- g_assert_cmpint(gpiod_line_bias(line), ==, GPIOD_LINE_BIAS_UNKNOWN);
- g_assert_true(gpiod_line_is_active_low(line));
+ g_assert_cmpint(gpiod_line_get_bias(info1), ==,
+ GPIOD_LINE_BIAS_UNKNOWN);
+ g_assert_true(gpiod_line_is_active_low(info1));
gpiod_line_release(line);
@@ -858,11 +1091,17 @@ GPIOD_TEST_CASE(misc_flags_work_together, 0, { 8 })
g_assert_cmpint(ret, ==, 0);
gpiod_test_return_if_failed();
- g_assert_true(gpiod_line_is_used(line));
- g_assert_cmpint(gpiod_line_drive(line), ==, GPIOD_LINE_DRIVE_PUSH_PULL);
- g_assert_cmpint(gpiod_line_bias(line), ==, GPIOD_LINE_BIAS_PULL_DOWN);
- g_assert_true(gpiod_line_is_active_low(line));
- g_assert_cmpint(gpiod_line_direction(line), ==,
+ info2 = gpiod_chip_get_line_info(chip, 2);
+ g_assert_nonnull(info2);
+ gpiod_test_return_if_failed();
+
+ g_assert_true(gpiod_line_is_used(info2));
+ g_assert_cmpint(gpiod_line_get_drive(info2), ==,
+ GPIOD_LINE_DRIVE_PUSH_PULL);
+ g_assert_cmpint(gpiod_line_get_bias(info2), ==,
+ GPIOD_LINE_BIAS_PULL_DOWN);
+ g_assert_true(gpiod_line_is_active_low(info2));
+ g_assert_cmpint(gpiod_line_get_direction(info2), ==,
GPIOD_LINE_DIRECTION_INPUT);
ret = gpiod_line_get_value(line);
@@ -877,11 +1116,17 @@ GPIOD_TEST_CASE(misc_flags_work_together, 0, { 8 })
g_assert_cmpint(ret, ==, 0);
gpiod_test_return_if_failed();
- g_assert_true(gpiod_line_is_used(line));
- g_assert_cmpint(gpiod_line_drive(line), ==, GPIOD_LINE_DRIVE_PUSH_PULL);
- g_assert_cmpint(gpiod_line_bias(line), ==, GPIOD_LINE_BIAS_PULL_UP);
- g_assert_true(gpiod_line_is_active_low(line));
- g_assert_cmpint(gpiod_line_direction(line), ==,
+ info3 = gpiod_chip_get_line_info(chip, 2);
+ g_assert_nonnull(info3);
+ gpiod_test_return_if_failed();
+
+ g_assert_true(gpiod_line_is_used(info3));
+ g_assert_cmpint(gpiod_line_get_drive(info3), ==,
+ GPIOD_LINE_DRIVE_PUSH_PULL);
+ g_assert_cmpint(gpiod_line_get_bias(info3), ==,
+ GPIOD_LINE_BIAS_PULL_UP);
+ g_assert_true(gpiod_line_is_active_low(info3));
+ g_assert_cmpint(gpiod_line_get_direction(info3), ==,
GPIOD_LINE_DIRECTION_INPUT);
ret = gpiod_line_get_value(line);
@@ -1018,6 +1263,8 @@ GPIOD_TEST_CASE(release_one_use_another, 0, { 8 })
GPIOD_TEST_CASE(null_consumer, 0, { 8 })
{
+ g_autoptr(gpiod_line_info_struct) info0 = NULL;
+ g_autoptr(gpiod_line_info_struct) info1 = NULL;
g_autoptr(gpiod_chip_struct) chip = NULL;
struct gpiod_line_request_config config;
struct gpiod_line *line;
@@ -1038,7 +1285,11 @@ GPIOD_TEST_CASE(null_consumer, 0, { 8 })
ret = gpiod_line_request(line, &config, 0);
g_assert_cmpint(ret, ==, 0);
gpiod_test_return_if_failed();
- g_assert_cmpstr(gpiod_line_consumer(line), ==, "?");
+
+ info0 = gpiod_chip_get_line_info(chip, 2);
+ g_assert_nonnull(info0);
+ gpiod_test_return_if_failed();
+ g_assert_cmpstr(gpiod_line_get_consumer(info0), ==, "?");
gpiod_line_release(line);
@@ -1050,11 +1301,17 @@ GPIOD_TEST_CASE(null_consumer, 0, { 8 })
ret = gpiod_line_request(line, &config, 0);
g_assert_cmpint(ret, ==, 0);
- g_assert_cmpstr(gpiod_line_consumer(line), ==, "?");
+
+ info1 = gpiod_chip_get_line_info(chip, 2);
+ g_assert_nonnull(info1);
+ gpiod_test_return_if_failed();
+ g_assert_cmpstr(gpiod_line_get_consumer(info1), ==, "?");
}
GPIOD_TEST_CASE(empty_consumer, 0, { 8 })
{
+ g_autoptr(gpiod_line_info_struct) info0 = NULL;
+ g_autoptr(gpiod_line_info_struct) info1 = NULL;
g_autoptr(gpiod_chip_struct) chip = NULL;
struct gpiod_line_request_config config;
struct gpiod_line *line;
@@ -1075,7 +1332,11 @@ GPIOD_TEST_CASE(empty_consumer, 0, { 8 })
ret = gpiod_line_request(line, &config, 0);
g_assert_cmpint(ret, ==, 0);
gpiod_test_return_if_failed();
- g_assert_cmpstr(gpiod_line_consumer(line), ==, "?");
+
+ info0 = gpiod_chip_get_line_info(chip, 2);
+ g_assert_nonnull(info0);
+ gpiod_test_return_if_failed();
+ g_assert_cmpstr(gpiod_line_get_consumer(info0), ==, "?");
gpiod_line_release(line);
@@ -1087,5 +1348,9 @@ GPIOD_TEST_CASE(empty_consumer, 0, { 8 })
ret = gpiod_line_request(line, &config, 0);
g_assert_cmpint(ret, ==, 0);
- g_assert_cmpstr(gpiod_line_consumer(line), ==, "?");
+
+ info1 = gpiod_chip_get_line_info(chip, 2);
+ g_assert_nonnull(info1);
+ gpiod_test_return_if_failed();
+ g_assert_cmpstr(gpiod_line_get_consumer(info1), ==, "?");
}
@@ -11,36 +11,36 @@
#include "tools-common.h"
-typedef bool (*is_set_func)(struct gpiod_line *);
+typedef bool (*is_set_func)(struct gpiod_line_info *);
struct flag {
const char *name;
is_set_func is_set;
};
-static bool line_bias_is_pullup(struct gpiod_line *line)
+static bool line_bias_is_pullup(struct gpiod_line_info *info)
{
- return gpiod_line_bias(line) == GPIOD_LINE_BIAS_PULL_UP;
+ return gpiod_line_get_bias(info) == GPIOD_LINE_BIAS_PULL_UP;
}
-static bool line_bias_is_pulldown(struct gpiod_line *line)
+static bool line_bias_is_pulldown(struct gpiod_line_info *info)
{
- return gpiod_line_bias(line) == GPIOD_LINE_BIAS_PULL_DOWN;
+ return gpiod_line_get_bias(info) == GPIOD_LINE_BIAS_PULL_DOWN;
}
-static bool line_bias_is_disabled(struct gpiod_line *line)
+static bool line_bias_is_disabled(struct gpiod_line_info *info)
{
- return gpiod_line_bias(line) == GPIOD_LINE_BIAS_DISABLED;
+ return gpiod_line_get_bias(info) == GPIOD_LINE_BIAS_DISABLED;
}
-static bool line_drive_is_open_drain(struct gpiod_line *line)
+static bool line_drive_is_open_drain(struct gpiod_line_info *info)
{
- return gpiod_line_drive(line) == GPIOD_LINE_DRIVE_OPEN_DRAIN;
+ return gpiod_line_get_drive(info) == GPIOD_LINE_DRIVE_OPEN_DRAIN;
}
-static bool line_drive_is_open_source(struct gpiod_line *line)
+static bool line_drive_is_open_source(struct gpiod_line_info *info)
{
- return gpiod_line_drive(line) == GPIOD_LINE_DRIVE_OPEN_SOURCE;
+ return gpiod_line_get_drive(info) == GPIOD_LINE_DRIVE_OPEN_SOURCE;
}
static const struct flag flags[] = {
@@ -124,8 +124,8 @@ static PRINTF(3, 4) void prinfo(bool *of,
static void list_lines(struct gpiod_chip *chip)
{
bool flag_printed, of, active_low;
+ struct gpiod_line_info *info;
const char *name, *consumer;
- struct gpiod_line *line;
unsigned int i, offset;
int direction;
@@ -133,14 +133,14 @@ static void list_lines(struct gpiod_chip *chip)
gpiod_chip_get_name(chip), gpiod_chip_get_num_lines(chip));
for (offset = 0; offset < gpiod_chip_get_num_lines(chip); offset++) {
- line = gpiod_chip_get_line(chip, offset);
- if (!line)
+ info = gpiod_chip_get_line_info(chip, offset);
+ if (!info)
die_perror("unable to retrieve the line object from chip");
- name = gpiod_line_name(line);
- consumer = gpiod_line_consumer(line);
- direction = gpiod_line_direction(line);
- active_low = gpiod_line_is_active_low(line);
+ name = gpiod_line_get_name(info);
+ consumer = gpiod_line_get_consumer(info);
+ direction = gpiod_line_get_direction(info);
+ active_low = gpiod_line_is_active_low(info);
of = false;
@@ -152,7 +152,7 @@ static void list_lines(struct gpiod_chip *chip)
: prinfo(&of, 12, "unnamed");
printf(" ");
- if (!gpiod_line_is_used(line))
+ if (!gpiod_line_is_used(info))
prinfo(&of, 12, "unused");
else
consumer ? prinfo(&of, 12, "\"%s\"", consumer)
@@ -167,7 +167,7 @@ static void list_lines(struct gpiod_chip *chip)
flag_printed = false;
for (i = 0; i < ARRAY_SIZE(flags); i++) {
- if (flags[i].is_set(line)) {
+ if (flags[i].is_set(info)) {
if (flag_printed)
printf(" ");
else
@@ -180,6 +180,8 @@ static void list_lines(struct gpiod_chip *chip)
printf("]");
printf("\n");
+
+ gpiod_line_info_unref(info);
}
}
Implement an opaque object storing a snapshot of a GPIO line's status info and add functions for accessing its fields. Signed-off-by: Bartosz Golaszewski <brgl@bgdev.pl> --- include/gpiod.h | 119 ++++++++++--- lib/Makefile.am | 2 +- lib/core.c | 63 ++----- lib/helpers.c | 16 +- lib/info.c | 170 ++++++++++++++++++ lib/internal.h | 6 + tests/gpiod-test.h | 2 + tests/tests-chip.c | 8 +- tests/tests-line.c | 425 ++++++++++++++++++++++++++++++++++++--------- tools/gpioinfo.c | 42 ++--- 10 files changed, 672 insertions(+), 181 deletions(-) create mode 100644 lib/info.c