From patchwork Thu Nov 21 00:35:43 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kent Gibson X-Patchwork-Id: 1198601 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (no SPF record) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=linux-gpio-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="UR4YiWwS"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 47JLGK0xb6z9sPL for ; Thu, 21 Nov 2019 11:36:25 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726548AbfKUAgX (ORCPT ); Wed, 20 Nov 2019 19:36:23 -0500 Received: from mail-pf1-f195.google.com ([209.85.210.195]:39289 "EHLO mail-pf1-f195.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726044AbfKUAgX (ORCPT ); Wed, 20 Nov 2019 19:36:23 -0500 Received: by mail-pf1-f195.google.com with SMTP id x28so682072pfo.6 for ; Wed, 20 Nov 2019 16:36:21 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=g3VIwfDFFneyuMhtYBlS4bEv5/DtQNr4Sh3MR5iqeUw=; b=UR4YiWwSlUbaqrWbfGb/j8YTwUv602+THCd2REO0quYsAHPYMWoPtO2tvXh8y8IF7S RJrHH6F8bhrxuBx7krnI+qeC2P56cy0lKNVC1+d3JF6OqOEzqLxN8yPckv/tmYsZywDd 9W+iZ+DBXCmzyDaowLyzHJIr5DZJ49q24C94GzJcMvYTfbZPfr9hfH3BoYuQen46RdBZ h2T639mZwh78zuGWUQvQvNCR+9U7JHZa+q/TcnzRFdrqxwreuyzl04d7Gwe2IlciPgYp iEL2nYY5kFboMb5sICy7tI+MJL1EMFQ2mpOA02okoWzCqUXTCnePp7LJTM+i3rcoQHUe vPWw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=g3VIwfDFFneyuMhtYBlS4bEv5/DtQNr4Sh3MR5iqeUw=; b=nJA75lXGYZLQ+SyrrkGo/tBTmGsLVL7K/LgEA8PY1QrVNxgPgwH8WH8rnFx6RQtM1a DxdcEAvxZz6Ha/kDRYLQyFVgkRvaSvbUoJOyF3mZK+NUVUb9NllMlVV9KyppUO2K0Aaf BVlIILbV5zNLzQkuyw3bVrb0rzC4NCRcw50/rvrF377u/fH04aHnYGF4qG9ZfWBoWc7l cX7f8iMMe51sb6MlYGbLQcInOaNMHVJGy648SU3R9UaYPgjdMbQXNap1jNzlcLajy52Y X33y6eXf5LnsDPTJo4NF+/jKqosrrl+cgnwHawpTZaJw0wY8DGHC7LHxzFbKh6tHXiwr +R6g== X-Gm-Message-State: APjAAAWK0y3RidUQ8Mk/5ijsgf5USgQfDe6uXyJq1uNWikO2q9ND0EKl IgWNnwaTkh/MpR3YLXycS+41VvirPps= X-Google-Smtp-Source: APXvYqyM0ywzI+0K2STshDo7ZG/ac6gLibUl8xi+C79xpvTaEpYjKIPfrI5ZkocoBApnvHCLirlnQg== X-Received: by 2002:a63:9554:: with SMTP id t20mr621584pgn.369.1574296580206; Wed, 20 Nov 2019 16:36:20 -0800 (PST) Received: from sol.lan (220-235-109-115.dyn.iinet.net.au. [220.235.109.115]) by smtp.gmail.com with ESMTPSA id s1sm420756pgk.9.2019.11.20.16.36.17 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 20 Nov 2019 16:36:19 -0800 (PST) From: Kent Gibson To: linux-gpio@vger.kernel.org, bgolaszewski@baylibre.com Cc: Kent Gibson Subject: [libgpiod] [PATCH v2 01/14] core: add support for bias flags Date: Thu, 21 Nov 2019 08:35:43 +0800 Message-Id: <20191121003556.9020-2-warthog618@gmail.com> X-Mailer: git-send-email 2.24.0 In-Reply-To: <20191121003556.9020-1-warthog618@gmail.com> References: <20191121003556.9020-1-warthog618@gmail.com> MIME-Version: 1.0 Sender: linux-gpio-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-gpio@vger.kernel.org Extend the libgpiod API to support the bias flags recently added to the kernel GPIO uAPI. The core change is the addition of GPIOD_LINE_REQUEST_FLAG_BIAS_DISABLE, GPIOD_LINE_REQUEST_FLAG_BIAS_PULL_UP and GPIOD_LINE_REQUEST_FLAG_BIAS_PULL_DOWN flags to be passed into line_request functions, and the addition of gpiod_line_bias to return the bias state of lines. Variants of the ctxless functions that accept an active_low flag are added to also accept other flags. The variant names add a "_ext" suffix to the name of the original function. Based on initial work by Drew Fustini . Signed-off-by: Kent Gibson --- include/gpiod.h | 183 ++++++++++++++++++++++++++++++++++++++++++++++++ lib/core.c | 32 ++++++--- lib/ctxless.c | 114 +++++++++++++++++++++++++++--- 3 files changed, 311 insertions(+), 18 deletions(-) diff --git a/include/gpiod.h b/include/gpiod.h index 6dfa18a..cdf0435 100644 --- a/include/gpiod.h +++ b/include/gpiod.h @@ -84,6 +84,22 @@ struct gpiod_line_bulk; * the need to use the gpiod_* structures or to keep track of resources. */ +/** + * @brief Miscellaneous GPIO flags. + */ +enum { + GPIOD_CTXLESS_FLAG_OPEN_DRAIN = GPIOD_BIT(0), + /**< The line is an open-drain port. */ + GPIOD_CTXLESS_FLAG_OPEN_SOURCE = GPIOD_BIT(1), + /**< The line is an open-source port. */ + GPIOD_CTXLESS_FLAG_BIAS_DISABLE = GPIOD_BIT(2), + /**< The line has neither either pull-up nor pull-down resistor */ + GPIOD_CTXLESS_FLAG_BIAS_PULL_DOWN = GPIOD_BIT(3), + /**< The line has pull-down resistor enabled */ + GPIOD_CTXLESS_FLAG_BIAS_PULL_UP = GPIOD_BIT(4), + /**< The line has pull-up resistor enabled */ +}; + /** * @brief Read current value from a single GPIO line. * @param device Name, path, number or label of the gpiochip. @@ -95,6 +111,19 @@ struct gpiod_line_bulk; int gpiod_ctxless_get_value(const char *device, unsigned int offset, bool active_low, const char *consumer) GPIOD_API; +/** + * @brief Read current value from a single GPIO line. + * @param device Name, path, number or label of the gpiochip. + * @param offset Offset of the GPIO line. + * @param active_low The active state of this line - true if low. + * @param consumer Name of the consumer. + * @param flags The flags for the line. + * @return 0 or 1 (GPIO value) if the operation succeeds, -1 on error. + */ +int gpiod_ctxless_get_value_ext(const char *device, unsigned int offset, + bool active_low, const char *consumer, + int flags) GPIOD_API; + /** * @brief Read current values from a set of GPIO lines. * @param device Name, path, number or label of the gpiochip. @@ -110,6 +139,23 @@ int gpiod_ctxless_get_value_multiple(const char *device, unsigned int num_lines, bool active_low, const char *consumer) GPIOD_API; +/** + * @brief Read current values from a set of GPIO lines. + * @param device Name, path, number or label of the gpiochip. + * @param offsets Array of offsets of lines whose values should be read. + * @param values Buffer in which the values will be stored. + * @param num_lines Number of lines, must be > 0. + * @param active_low The active state of this line - true if low. + * @param consumer Name of the consumer. + * @param flags The flags for the lines. + * @return 0 if the operation succeeds, -1 on error. + */ +int gpiod_ctxless_get_value_multiple_ext(const char *device, + const unsigned int *offsets, + int *values, unsigned int num_lines, + bool active_low, const char *consumer, + int flags) GPIOD_API; + /** * @brief Simple set value callback signature. */ @@ -133,6 +179,26 @@ int gpiod_ctxless_set_value(const char *device, unsigned int offset, int value, gpiod_ctxless_set_value_cb cb, void *data) GPIOD_API; +/** + * @brief Set value of a single GPIO line. + * @param device Name, path, number or label of the gpiochip. + * @param offset The offset of the GPIO line. + * @param value New value (0 or 1). + * @param active_low The active state of this line - true if low. + * @param consumer Name of the consumer. + * @param cb Optional callback function that will be called right after setting + * the value. Users can use this, for example, to pause the execution + * after toggling a GPIO. + * @param data Optional user data that will be passed to the callback function. + * @param flags The flags for the line. + * @return 0 if the operation succeeds, -1 on error. + */ +int gpiod_ctxless_set_value_ext(const char *device, unsigned int offset, + int value, bool active_low, + const char *consumer, + gpiod_ctxless_set_value_cb cb, + void *data, int flags) GPIOD_API; + /** * @brief Set values of multiple GPIO lines. * @param device Name, path, number or label of the gpiochip. @@ -153,6 +219,29 @@ int gpiod_ctxless_set_value_multiple(const char *device, gpiod_ctxless_set_value_cb cb, void *data) GPIOD_API; +/** + * @brief Set values of multiple GPIO lines. + * @param device Name, path, number or label of the gpiochip. + * @param offsets Array of offsets of lines the values of which should be set. + * @param values Array of integers containing new values. + * @param num_lines Number of lines, must be > 0. + * @param active_low The active state of this line - true if low. + * @param consumer Name of the consumer. + * @param cb Optional callback function that will be called right after setting + * all values. Works the same as in ::gpiod_ctxless_set_value. + * @param data Optional user data that will be passed to the callback function. + * @param flags The flags for the lines. + * @return 0 if the operation succeeds, -1 on error. + */ +int gpiod_ctxless_set_value_multiple_ext(const char *device, + const unsigned int *offsets, + const int *values, + unsigned int num_lines, + bool active_low, + const char *consumer, + gpiod_ctxless_set_value_cb cb, + void *data, int flags) GPIOD_API; + /** * @brief Event types that the ctxless event monitor can wait for. */ @@ -327,6 +416,31 @@ int gpiod_ctxless_event_monitor(const char *device, int event_type, gpiod_ctxless_event_handle_cb event_cb, void *data) GPIOD_API; +/** + * @brief Wait for events on a single GPIO line. + * @param device Name, path, number or label of the gpiochip. + * @param event_type Type of events to listen for. + * @param offset GPIO line offset to monitor. + * @param active_low The active state of this line - true if low. + * @param consumer Name of the consumer. + * @param timeout Maximum wait time for each iteration. + * @param poll_cb Callback function to call when waiting for events. + * @param event_cb Callback function to call for each line event. + * @param data User data passed to the callback. + * @param flags The flags for the line. + * @return 0 if no errors were encountered, -1 if an error occurred. + * @note The way the ctxless event loop works is described in detail in + * ::gpiod_ctxless_event_monitor_multiple - this is just a wrapper aound + * this routine which calls it for a single GPIO line. + */ +int gpiod_ctxless_event_monitor_ext(const char *device, int event_type, + unsigned int offset, bool active_low, + const char *consumer, + const struct timespec *timeout, + gpiod_ctxless_event_poll_cb poll_cb, + gpiod_ctxless_event_handle_cb event_cb, + void *data, int flags) GPIOD_API; + /** * @brief Wait for events on multiple GPIO lines. * @param device Name, path, number or label of the gpiochip. @@ -366,6 +480,47 @@ int gpiod_ctxless_event_monitor_multiple( gpiod_ctxless_event_handle_cb event_cb, void *data) GPIOD_API; +/** + * @brief Wait for events on multiple GPIO lines. + * @param device Name, path, number or label of the gpiochip. + * @param event_type Type of events to listen for. + * @param offsets Array of GPIO line offsets to monitor. + * @param num_lines Number of lines to monitor. + * @param active_low The active state of this line - true if low. + * @param consumer Name of the consumer. + * @param timeout Maximum wait time for each iteration. + * @param poll_cb Callback function to call when waiting for events. Can + * be NULL. + * @param event_cb Callback function to call on event occurrence. + * @param data User data passed to the callback. + * @param flags The flags for the lines. + * @return 0 no errors were encountered, -1 if an error occurred. + * @note The poll callback can be NULL in which case the routine will fall + * back to a basic, ppoll() based callback. + * + * Internally this routine opens the GPIO chip, requests the set of lines for + * the type of events specified in the event_type parameter and calls the + * polling callback in a loop. The role of the polling callback is to detect + * input events on a set of file descriptors and notify the caller about the + * fds ready for reading. + * + * The ctxless event loop then reads each queued event from marked descriptors + * and calls the event callback. Both callbacks can stop the loop at any + * point. + * + * The poll_cb argument can be NULL in which case the function falls back to + * a default, ppoll() based callback. + */ +int gpiod_ctxless_event_monitor_multiple_ext( + const char *device, int event_type, + const unsigned int *offsets, + unsigned int num_lines, bool active_low, + const char *consumer, const struct timespec *timeout, + gpiod_ctxless_event_poll_cb poll_cb, + gpiod_ctxless_event_handle_cb event_cb, + void *data, int flags) GPIOD_API; + + /** * @brief Determine the chip name and line offset of a line with given name. * @param name The name of the GPIO line to lookup. @@ -658,6 +813,20 @@ enum { /**< The active state of a GPIO is active-low. */ }; +/** + * @brief Possible internal bias settings. + */ +enum { + GPIOD_LINE_BIAS_AS_IS = 1, + /**< The internal bias state is unknown. */ + GPIOD_LINE_BIAS_DISABLE, + /**< The internal bias is disabled. */ + GPIOD_LINE_BIAS_PULL_UP, + /**< The internal pull-up bias is enabled. */ + GPIOD_LINE_BIAS_PULL_DOWN, + /**< The internal pull-down bias is enabled. */ +}; + /** * @brief Read the GPIO line offset. * @param line GPIO line object. @@ -697,6 +866,14 @@ int gpiod_line_direction(struct gpiod_line *line) GPIOD_API; */ int gpiod_line_active_state(struct gpiod_line *line) GPIOD_API; +/** + * @brief Read the GPIO line bias setting. + * @param line GPIO line object. + * @return Returns GPIOD_LINE_BIAS_PULL_UP, GPIOD_LINE_BIAS_PULL_DOWN, + * GPIOD_LINE_BIAS_DISABLE or GPIOD_LINE_BIAS_AS_IS. + */ +int gpiod_line_bias(struct gpiod_line *line) GPIOD_API; + /** * @brief Check if the line is currently in use. * @param line GPIO line object. @@ -792,6 +969,12 @@ enum { /**< The line is an open-source port. */ GPIOD_LINE_REQUEST_FLAG_ACTIVE_LOW = GPIOD_BIT(2), /**< The active state of the line is low (high is the default). */ + GPIOD_LINE_REQUEST_FLAG_BIAS_DISABLE = GPIOD_BIT(3), + /**< The line has neither either pull-up nor pull-down resistor */ + GPIOD_LINE_REQUEST_FLAG_BIAS_PULL_DOWN = GPIOD_BIT(4), + /**< The line has pull-down resistor enabled */ + GPIOD_LINE_REQUEST_FLAG_BIAS_PULL_UP = GPIOD_BIT(5), + /**< The line has pull-up resistor enabled */ }; /** diff --git a/lib/core.c b/lib/core.c index d79e52e..ece3b13 100644 --- a/lib/core.c +++ b/lib/core.c @@ -36,9 +36,7 @@ struct gpiod_line { unsigned int offset; int direction; int active_state; - bool used; - bool open_source; - bool open_drain; + __u32 info_flags; int state; bool needs_update; @@ -359,19 +357,31 @@ int gpiod_line_active_state(struct gpiod_line *line) return line->active_state; } +int gpiod_line_bias(struct gpiod_line *line) +{ + if (line->info_flags & GPIOLINE_FLAG_BIAS_DISABLE) + return GPIOD_LINE_BIAS_DISABLE; + 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_AS_IS; +} + bool gpiod_line_is_used(struct gpiod_line *line) { - return line->used; + return line->info_flags & GPIOLINE_FLAG_KERNEL; } bool gpiod_line_is_open_drain(struct gpiod_line *line) { - return line->open_drain; + return line->info_flags & GPIOLINE_FLAG_OPEN_DRAIN; } bool gpiod_line_is_open_source(struct gpiod_line *line) { - return line->open_source; + return line->info_flags & GPIOLINE_FLAG_OPEN_SOURCE; } bool gpiod_line_needs_update(struct gpiod_line *line) @@ -398,9 +408,7 @@ int gpiod_line_update(struct gpiod_line *line) ? GPIOD_LINE_ACTIVE_STATE_LOW : GPIOD_LINE_ACTIVE_STATE_HIGH; - line->used = info.flags & GPIOLINE_FLAG_KERNEL; - line->open_drain = info.flags & GPIOLINE_FLAG_OPEN_DRAIN; - line->open_source = info.flags & GPIOLINE_FLAG_OPEN_SOURCE; + line->info_flags = info.flags; strncpy(line->name, info.name, sizeof(line->name)); strncpy(line->consumer, info.consumer, sizeof(line->consumer)); @@ -473,6 +481,12 @@ static __u32 line_request_flag_to_gpio_handleflag(int flags) hflags |= GPIOHANDLE_REQUEST_OPEN_SOURCE; if (flags & GPIOD_LINE_REQUEST_FLAG_ACTIVE_LOW) hflags |= GPIOHANDLE_REQUEST_ACTIVE_LOW; + if (flags & GPIOD_LINE_REQUEST_FLAG_BIAS_DISABLE) + hflags |= GPIOHANDLE_REQUEST_BIAS_DISABLE; + if (flags & GPIOD_LINE_REQUEST_FLAG_BIAS_PULL_DOWN) + hflags |= GPIOHANDLE_REQUEST_BIAS_PULL_DOWN; + if (flags & GPIOD_LINE_REQUEST_FLAG_BIAS_PULL_UP) + hflags |= GPIOHANDLE_REQUEST_BIAS_PULL_UP; return hflags; } diff --git a/lib/ctxless.c b/lib/ctxless.c index ba85018..014475c 100644 --- a/lib/ctxless.c +++ b/lib/ctxless.c @@ -14,6 +14,26 @@ #include #include +static int ctxless_flags_to_line_request_flags(bool active_low, int flags) +{ + int req_flags = 0; + + if (active_low) + req_flags |= GPIOD_LINE_REQUEST_FLAG_ACTIVE_LOW; + if (flags & GPIOD_CTXLESS_FLAG_OPEN_DRAIN) + req_flags |= GPIOD_LINE_REQUEST_FLAG_OPEN_DRAIN; + if (flags & GPIOD_CTXLESS_FLAG_OPEN_SOURCE) + req_flags |= GPIOD_LINE_REQUEST_FLAG_OPEN_SOURCE; + if (flags & GPIOD_CTXLESS_FLAG_BIAS_DISABLE) + req_flags |= GPIOD_LINE_REQUEST_FLAG_BIAS_DISABLE; + if (flags & GPIOD_CTXLESS_FLAG_BIAS_PULL_UP) + req_flags |= GPIOD_LINE_REQUEST_FLAG_BIAS_PULL_UP; + if (flags & GPIOD_CTXLESS_FLAG_BIAS_PULL_DOWN) + req_flags |= GPIOD_LINE_REQUEST_FLAG_BIAS_PULL_DOWN; + + return req_flags; +} + int gpiod_ctxless_get_value(const char *device, unsigned int offset, bool active_low, const char *consumer) { @@ -27,16 +47,44 @@ int gpiod_ctxless_get_value(const char *device, unsigned int offset, return value; } +int gpiod_ctxless_get_value_ext(const char *device, unsigned int offset, + bool active_low, const char *consumer, + int flags) +{ + int value, rv; + + rv = gpiod_ctxless_get_value_multiple_ext(device, &offset, &value, 1, + active_low, consumer, flags); + if (rv < 0) + return rv; + + return value; +} + int gpiod_ctxless_get_value_multiple(const char *device, const unsigned int *offsets, int *values, unsigned int num_lines, bool active_low, const char *consumer) +{ + int rv; + + rv = gpiod_ctxless_get_value_multiple_ext(device, offsets, values, + num_lines, active_low, + consumer, 0); + return rv; +} + +int gpiod_ctxless_get_value_multiple_ext(const char *device, + const unsigned int *offsets, + int *values, unsigned int num_lines, + bool active_low, + const char *consumer, int flags) { struct gpiod_line_bulk bulk; struct gpiod_chip *chip; struct gpiod_line *line; unsigned int i; - int rv, flags; + int rv, req_flags; if (!num_lines || num_lines > GPIOD_LINE_BULK_MAX_LINES) { errno = EINVAL; @@ -59,9 +107,8 @@ int gpiod_ctxless_get_value_multiple(const char *device, gpiod_line_bulk_add(&bulk, line); } - flags = active_low ? GPIOD_LINE_REQUEST_FLAG_ACTIVE_LOW : 0; - - rv = gpiod_line_request_bulk_input_flags(&bulk, consumer, flags); + req_flags = ctxless_flags_to_line_request_flags(active_low, flags); + rv = gpiod_line_request_bulk_input_flags(&bulk, consumer, req_flags); if (rv < 0) { gpiod_chip_close(chip); return -1; @@ -83,17 +130,39 @@ int gpiod_ctxless_set_value(const char *device, unsigned int offset, int value, active_low, consumer, cb, data); } +int gpiod_ctxless_set_value_ext(const char *device, unsigned int offset, + int value, bool active_low, + const char *consumer, + gpiod_ctxless_set_value_cb cb, + void *data, int flags) +{ + return gpiod_ctxless_set_value_multiple_ext(device, &offset, &value, + 1, active_low, consumer, + cb, data, flags); +} + int gpiod_ctxless_set_value_multiple(const char *device, const unsigned int *offsets, const int *values, unsigned int num_lines, bool active_low, const char *consumer, gpiod_ctxless_set_value_cb cb, void *data) +{ + return gpiod_ctxless_set_value_multiple_ext(device, offsets, values, + num_lines, active_low, + consumer, cb, data, 0); +} + +int gpiod_ctxless_set_value_multiple_ext( + const char *device, const unsigned int *offsets, + const int *values, unsigned int num_lines, + bool active_low, const char *consumer, + gpiod_ctxless_set_value_cb cb, void *data, int flags) { struct gpiod_line_bulk bulk; struct gpiod_chip *chip; struct gpiod_line *line; unsigned int i; - int rv, flags; + int rv, req_flags; if (!num_lines || num_lines > GPIOD_LINE_BULK_MAX_LINES) { errno = EINVAL; @@ -116,10 +185,9 @@ int gpiod_ctxless_set_value_multiple(const char *device, gpiod_line_bulk_add(&bulk, line); } - flags = active_low ? GPIOD_LINE_REQUEST_FLAG_ACTIVE_LOW : 0; - + req_flags = ctxless_flags_to_line_request_flags(active_low, flags); rv = gpiod_line_request_bulk_output_flags(&bulk, consumer, - flags, values); + req_flags, values); if (rv < 0) { gpiod_chip_close(chip); return -1; @@ -216,6 +284,19 @@ int gpiod_ctxless_event_monitor(const char *device, int event_type, poll_cb, event_cb, data); } +int gpiod_ctxless_event_monitor_ext(const char *device, int event_type, + unsigned int offset, bool active_low, + const char *consumer, + const struct timespec *timeout, + gpiod_ctxless_event_poll_cb poll_cb, + gpiod_ctxless_event_handle_cb event_cb, + void *data, int flags) +{ + return gpiod_ctxless_event_monitor_multiple_ext( + device, event_type, &offset, 1, active_low, + consumer, timeout, poll_cb, event_cb, data, flags); +} + int gpiod_ctxless_event_monitor_multiple( const char *device, int event_type, const unsigned int *offsets, @@ -225,6 +306,21 @@ int gpiod_ctxless_event_monitor_multiple( gpiod_ctxless_event_poll_cb poll_cb, gpiod_ctxless_event_handle_cb event_cb, void *data) +{ + return gpiod_ctxless_event_monitor_multiple_ext( + device, event_type, offsets, + num_lines, active_low, consumer, timeout, + poll_cb, event_cb, data, 0); +} + +int gpiod_ctxless_event_monitor_multiple_ext( + const char *device, int event_type, + const unsigned int *offsets, + unsigned int num_lines, bool active_low, + const char *consumer, const struct timespec *timeout, + gpiod_ctxless_event_poll_cb poll_cb, + gpiod_ctxless_event_handle_cb event_cb, + void *data, int flags) { struct gpiod_ctxless_event_poll_fd fds[GPIOD_LINE_BULK_MAX_LINES]; struct gpiod_line_request_config conf; @@ -259,7 +355,7 @@ int gpiod_ctxless_event_monitor_multiple( gpiod_line_bulk_add(&bulk, line); } - conf.flags = active_low ? GPIOD_LINE_REQUEST_FLAG_ACTIVE_LOW : 0; + conf.flags = ctxless_flags_to_line_request_flags(active_low, flags); conf.consumer = consumer; if (event_type == GPIOD_CTXLESS_EVENT_RISING_EDGE) { From patchwork Thu Nov 21 00:35:44 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kent Gibson X-Patchwork-Id: 1198602 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (no SPF record) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=linux-gpio-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="u7MTZhRC"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 47JLGK5zlKz9sNx for ; Thu, 21 Nov 2019 11:36:25 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726568AbfKUAgY (ORCPT ); Wed, 20 Nov 2019 19:36:24 -0500 Received: from mail-pg1-f195.google.com ([209.85.215.195]:37486 "EHLO mail-pg1-f195.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726044AbfKUAgY (ORCPT ); Wed, 20 Nov 2019 19:36:24 -0500 Received: by mail-pg1-f195.google.com with SMTP id b10so629706pgd.4 for ; Wed, 20 Nov 2019 16:36:23 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=fbezLULghY7JmklQ25RnbLNA20g5Ser92Orgxev1FKE=; b=u7MTZhRC75BJOGfTjLqzB9NenT/ET0Hpq8XAAQ2YnniokSk4s5Z8neiru1Iwk8EHij EsCK+enWzJLdcqkGK0u/+jp9wTOx64kYicW0PGMOUkh5Lcjdktq3H6KB7VcZBZA4KhP1 rFgl2sDqbXsriX8oaiHSlMeI/5nxZwLknP3BGPJv319CESGZ5CtqyickzhMuvt6kre2P /JjGlSvUkesOpWuHVKeC3L8nsMEfOnzEVttUgNGBede0j5eP/vy4t4ax/H2HPIhTxEMV XFM+sxQweV4JQTeXti3dfWBZ5dbTzf9ndYU4VA/OiSqSkqJ//2alX+jbM998P0UcqirG PyUA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=fbezLULghY7JmklQ25RnbLNA20g5Ser92Orgxev1FKE=; b=PQfnT0y1B/RVG9hSPUouVoxtHk4Wqyo7yrGQVOc6RoAT6eG9RShOrMisvDGjevHjO8 FZAd5z5wc3fcluDFmaulYmhSOI0V9ejLeQdxS5yNtQWPyF1TPp13NP8NBKtMMD9oipAZ C+ZChaXGefNt5V0Eg1/qC0RPdQQ0He8WvcKqrorL8W+kw0dXeFT2sTP/c49z5DSZZX1C /xDiCspXopX1G/APDZsHJF6N/dx693mzJ8q9JqHJc3rFq4ptawO4l6FxmOs7LL1LxZP6 PX6UL6XgFYHj7+e1cweJDZoEggMN3yKwGpwMWFkM3N3M1dZxr3qwvUdiViYQq1zs5Te5 sO2Q== X-Gm-Message-State: APjAAAUQsdsZo6pXXAcPMCNOjFFdSba1udH2ESikkxJNteJ/0oR2C69B FZpUceu7YqhT3zSKVZp5ZAA0lxiGE08= X-Google-Smtp-Source: APXvYqzYnsyV9cSMjhOV8PVMjYpjRgxNBVaN3YUWlBcVXb41x4RIXRdCuP84AAARUCxs4+ZObg5dtA== X-Received: by 2002:a63:3144:: with SMTP id x65mr6126544pgx.283.1574296582794; Wed, 20 Nov 2019 16:36:22 -0800 (PST) Received: from sol.lan (220-235-109-115.dyn.iinet.net.au. [220.235.109.115]) by smtp.gmail.com with ESMTPSA id s1sm420756pgk.9.2019.11.20.16.36.20 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 20 Nov 2019 16:36:22 -0800 (PST) From: Kent Gibson To: linux-gpio@vger.kernel.org, bgolaszewski@baylibre.com Cc: Kent Gibson Subject: [libgpiod] [PATCH v2 02/14] tests: add tests for bias flags Date: Thu, 21 Nov 2019 08:35:44 +0800 Message-Id: <20191121003556.9020-3-warthog618@gmail.com> X-Mailer: git-send-email 2.24.0 In-Reply-To: <20191121003556.9020-1-warthog618@gmail.com> References: <20191121003556.9020-1-warthog618@gmail.com> MIME-Version: 1.0 Sender: linux-gpio-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-gpio@vger.kernel.org Extend test coverage over the bias flags, gpiod_line_bias and the extended ctxless functions. Also update existing tests to check bias flags where line state is checked. Signed-off-by: Kent Gibson --- tests/tests-ctxless.c | 64 +++++++++++++++++++++- tests/tests-event.c | 120 ++++++++++++++++++++++++++++++++++++++++++ tests/tests-line.c | 98 ++++++++++++++++++++++++++++++++++ 3 files changed, 280 insertions(+), 2 deletions(-) diff --git a/tests/tests-ctxless.c b/tests/tests-ctxless.c index c1e1ca6..76b9a7c 100644 --- a/tests/tests-ctxless.c +++ b/tests/tests-ctxless.c @@ -26,11 +26,41 @@ GPIOD_TEST_CASE(get_value, 0, { 8 }) g_assert_cmpint(ret, ==, 1); } -static void set_value_check(gpointer data G_GNUC_UNUSED) +GPIOD_TEST_CASE(get_value_ext, 0, { 8 }) +{ + gint ret; + + ret = gpiod_ctxless_get_value_ext(gpiod_test_chip_name(0), 3, + false, GPIOD_TEST_CONSUMER, + GPIOD_CTXLESS_FLAG_BIAS_PULL_DOWN); + g_assert_cmpint(ret, ==, 0); + + ret = gpiod_ctxless_get_value_ext(gpiod_test_chip_name(0), 3, + false, GPIOD_TEST_CONSUMER, + GPIOD_CTXLESS_FLAG_BIAS_PULL_UP); + g_assert_cmpint(ret, ==, 1); + + ret = gpiod_ctxless_get_value_ext(gpiod_test_chip_name(0), 3, + true, GPIOD_TEST_CONSUMER + , GPIOD_CTXLESS_FLAG_BIAS_PULL_DOWN); + g_assert_cmpint(ret, ==, 1); + + ret = gpiod_ctxless_get_value_ext(gpiod_test_chip_name(0), 3, + true, GPIOD_TEST_CONSUMER, + GPIOD_CTXLESS_FLAG_BIAS_PULL_UP); + g_assert_cmpint(ret, ==, 0); +} + +static void set_value_check_hi(gpointer data G_GNUC_UNUSED) { g_assert_cmpint(gpiod_test_chip_get_value(0, 3), ==, 1); } +static void set_value_check_lo(gpointer data G_GNUC_UNUSED) +{ + g_assert_cmpint(gpiod_test_chip_get_value(0, 3), ==, 0); +} + GPIOD_TEST_CASE(set_value, 0, { 8 }) { gint ret; @@ -39,13 +69,43 @@ GPIOD_TEST_CASE(set_value, 0, { 8 }) ret = gpiod_ctxless_set_value(gpiod_test_chip_name(0), 3, 1, false, GPIOD_TEST_CONSUMER, - set_value_check, NULL); + set_value_check_hi, NULL); gpiod_test_return_if_failed(); g_assert_cmpint(ret, ==, 0); g_assert_cmpint(gpiod_test_chip_get_value(0, 3), ==, 0); } +GPIOD_TEST_CASE(set_value_ext, 0, { 8 }) +{ + gint ret; + + gpiod_test_chip_set_pull(0, 3, 0); + + ret = gpiod_ctxless_set_value_ext(gpiod_test_chip_name(0), 3, 1, + false, GPIOD_TEST_CONSUMER, + set_value_check_hi, NULL, 0); + gpiod_test_return_if_failed(); + g_assert_cmpint(ret, ==, 0); + g_assert_cmpint(gpiod_test_chip_get_value(0, 3), ==, 0); + + /* test drive flags by checking that sets are caught by emulation */ + ret = gpiod_ctxless_set_value_ext(gpiod_test_chip_name(0), 3, 1, + false, GPIOD_TEST_CONSUMER, set_value_check_lo, + NULL, GPIOD_CTXLESS_FLAG_OPEN_DRAIN); + gpiod_test_return_if_failed(); + g_assert_cmpint(ret, ==, 0); + g_assert_cmpint(gpiod_test_chip_get_value(0, 3), ==, 0); + + gpiod_test_chip_set_pull(0, 3, 1); + ret = gpiod_ctxless_set_value_ext(gpiod_test_chip_name(0), 3, 0, + false, GPIOD_TEST_CONSUMER, set_value_check_hi, + NULL, GPIOD_CTXLESS_FLAG_OPEN_SOURCE); + gpiod_test_return_if_failed(); + g_assert_cmpint(ret, ==, 0); + g_assert_cmpint(gpiod_test_chip_get_value(0, 3), ==, 1); +} + static const guint get_value_multiple_offsets[] = { 1, 3, 4, 5, 6, 7, 8, 9, 13, 14 }; diff --git a/tests/tests-event.c b/tests/tests-event.c index 28b77ec..d425d1a 100644 --- a/tests/tests-event.c +++ b/tests/tests-event.c @@ -196,6 +196,126 @@ GPIOD_TEST_CASE(both_edges_active_low, 0, { 8 }) g_assert_cmpint(ev.event_type, ==, GPIOD_LINE_EVENT_RISING_EDGE); } +GPIOD_TEST_CASE(both_edges_bias_disable, 0, { 8 }) +{ + g_autoptr(GpiodTestEventThread) ev_thread = NULL; + g_autoptr(gpiod_chip_struct) chip = NULL; + struct timespec ts = { 1, 0 }; + struct gpiod_line_event ev; + struct gpiod_line *line; + gint ret; + + chip = gpiod_chip_open(gpiod_test_chip_path(0)); + g_assert_nonnull(chip); + gpiod_test_return_if_failed(); + + line = gpiod_chip_get_line(chip, 7); + g_assert_nonnull(line); + gpiod_test_return_if_failed(); + + ret = gpiod_line_request_both_edges_events_flags(line, + GPIOD_TEST_CONSUMER, GPIOD_LINE_REQUEST_FLAG_BIAS_DISABLE); + g_assert_cmpint(ret, ==, 0); + + ev_thread = gpiod_test_start_event_thread(0, 7, 100); + + ret = gpiod_line_event_wait(line, &ts); + g_assert_cmpint(ret, ==, 1); + + ret = gpiod_line_event_read(line, &ev); + g_assert_cmpint(ret, ==, 0); + + g_assert_cmpint(ev.event_type, ==, GPIOD_LINE_EVENT_RISING_EDGE); + + ret = gpiod_line_event_wait(line, &ts); + g_assert_cmpint(ret, ==, 1); + + ret = gpiod_line_event_read(line, &ev); + g_assert_cmpint(ret, ==, 0); + + g_assert_cmpint(ev.event_type, ==, GPIOD_LINE_EVENT_FALLING_EDGE); +} + +GPIOD_TEST_CASE(both_edges_bias_pull_down, 0, { 8 }) +{ + g_autoptr(GpiodTestEventThread) ev_thread = NULL; + g_autoptr(gpiod_chip_struct) chip = NULL; + struct timespec ts = { 1, 0 }; + struct gpiod_line_event ev; + struct gpiod_line *line; + gint ret; + + chip = gpiod_chip_open(gpiod_test_chip_path(0)); + g_assert_nonnull(chip); + gpiod_test_return_if_failed(); + + line = gpiod_chip_get_line(chip, 7); + g_assert_nonnull(line); + gpiod_test_return_if_failed(); + + ret = gpiod_line_request_both_edges_events_flags(line, + GPIOD_TEST_CONSUMER, GPIOD_LINE_REQUEST_FLAG_BIAS_PULL_DOWN); + g_assert_cmpint(ret, ==, 0); + + ev_thread = gpiod_test_start_event_thread(0, 7, 100); + + ret = gpiod_line_event_wait(line, &ts); + g_assert_cmpint(ret, ==, 1); + + ret = gpiod_line_event_read(line, &ev); + g_assert_cmpint(ret, ==, 0); + + g_assert_cmpint(ev.event_type, ==, GPIOD_LINE_EVENT_RISING_EDGE); + + ret = gpiod_line_event_wait(line, &ts); + g_assert_cmpint(ret, ==, 1); + + ret = gpiod_line_event_read(line, &ev); + g_assert_cmpint(ret, ==, 0); + + g_assert_cmpint(ev.event_type, ==, GPIOD_LINE_EVENT_FALLING_EDGE); +} + +GPIOD_TEST_CASE(both_edges_bias_pull_up, 0, { 8 }) +{ + g_autoptr(GpiodTestEventThread) ev_thread = NULL; + g_autoptr(gpiod_chip_struct) chip = NULL; + struct timespec ts = { 1, 0 }; + struct gpiod_line_event ev; + struct gpiod_line *line; + gint ret; + + chip = gpiod_chip_open(gpiod_test_chip_path(0)); + g_assert_nonnull(chip); + gpiod_test_return_if_failed(); + + line = gpiod_chip_get_line(chip, 7); + g_assert_nonnull(line); + gpiod_test_return_if_failed(); + + ret = gpiod_line_request_both_edges_events_flags(line, + GPIOD_TEST_CONSUMER, GPIOD_LINE_REQUEST_FLAG_BIAS_PULL_UP); + g_assert_cmpint(ret, ==, 0); + + ev_thread = gpiod_test_start_event_thread(0, 7, 100); + + ret = gpiod_line_event_wait(line, &ts); + g_assert_cmpint(ret, ==, 1); + + ret = gpiod_line_event_read(line, &ev); + g_assert_cmpint(ret, ==, 0); + + g_assert_cmpint(ev.event_type, ==, GPIOD_LINE_EVENT_FALLING_EDGE); + + ret = gpiod_line_event_wait(line, &ts); + g_assert_cmpint(ret, ==, 1); + + ret = gpiod_line_event_read(line, &ev); + g_assert_cmpint(ret, ==, 0); + + g_assert_cmpint(ev.event_type, ==, GPIOD_LINE_EVENT_RISING_EDGE); +} + GPIOD_TEST_CASE(falling_edge_active_low, 0, { 8 }) { g_autoptr(GpiodTestEventThread) ev_thread = NULL; diff --git a/tests/tests-line.c b/tests/tests-line.c index 8411132..b453dad 100644 --- a/tests/tests-line.c +++ b/tests/tests-line.c @@ -504,6 +504,7 @@ GPIOD_TEST_CASE(misc_flags, 0, { 8 }) g_assert_false(gpiod_line_is_used(line)); g_assert_false(gpiod_line_is_open_drain(line)); g_assert_false(gpiod_line_is_open_source(line)); + g_assert_cmpint(gpiod_line_bias(line), ==, GPIOD_LINE_BIAS_AS_IS); config.request_type = GPIOD_LINE_REQUEST_DIRECTION_OUTPUT; config.consumer = GPIOD_TEST_CONSUMER; @@ -515,6 +516,7 @@ GPIOD_TEST_CASE(misc_flags, 0, { 8 }) g_assert_true(gpiod_line_is_used(line)); g_assert_true(gpiod_line_is_open_drain(line)); g_assert_false(gpiod_line_is_open_source(line)); + g_assert_cmpint(gpiod_line_bias(line), ==, GPIOD_LINE_BIAS_AS_IS); g_assert_cmpint(gpiod_line_direction(line), ==, GPIOD_LINE_DIRECTION_OUTPUT); @@ -528,8 +530,11 @@ GPIOD_TEST_CASE(misc_flags, 0, { 8 }) g_assert_true(gpiod_line_is_used(line)); g_assert_false(gpiod_line_is_open_drain(line)); g_assert_true(gpiod_line_is_open_source(line)); + g_assert_cmpint(gpiod_line_bias(line), ==, GPIOD_LINE_BIAS_AS_IS); g_assert_cmpint(gpiod_line_direction(line), ==, GPIOD_LINE_DIRECTION_OUTPUT); + + gpiod_line_release(line); } GPIOD_TEST_CASE(misc_flags_work_together, 0, { 8 }) @@ -563,6 +568,7 @@ GPIOD_TEST_CASE(misc_flags_work_together, 0, { 8 }) g_assert_true(gpiod_line_is_used(line)); g_assert_true(gpiod_line_is_open_drain(line)); g_assert_false(gpiod_line_is_open_source(line)); + g_assert_cmpint(gpiod_line_bias(line), ==, GPIOD_LINE_BIAS_AS_IS); g_assert_cmpint(gpiod_line_active_state(line), ==, GPIOD_LINE_ACTIVE_STATE_LOW); g_assert_cmpint(gpiod_line_direction(line), ==, @@ -579,8 +585,59 @@ GPIOD_TEST_CASE(misc_flags_work_together, 0, { 8 }) g_assert_true(gpiod_line_is_used(line)); g_assert_false(gpiod_line_is_open_drain(line)); g_assert_true(gpiod_line_is_open_source(line)); + g_assert_cmpint(gpiod_line_bias(line), ==, GPIOD_LINE_BIAS_AS_IS); g_assert_cmpint(gpiod_line_active_state(line), ==, GPIOD_LINE_ACTIVE_STATE_LOW); + + gpiod_line_release(line); + + /* + * Verify that pull-up/down flags work together + * with active_low. + */ + + config.request_type = GPIOD_LINE_REQUEST_DIRECTION_INPUT; + config.flags = GPIOD_LINE_REQUEST_FLAG_BIAS_PULL_DOWN | + GPIOD_LINE_REQUEST_FLAG_ACTIVE_LOW; + + ret = gpiod_line_request(line, &config, 0); + g_assert_cmpint(ret, ==, 0); + + g_assert_true(gpiod_line_is_used(line)); + g_assert_false(gpiod_line_is_open_drain(line)); + g_assert_false(gpiod_line_is_open_source(line)); + g_assert_cmpint(gpiod_line_bias(line), ==, GPIOD_LINE_BIAS_PULL_DOWN); + g_assert_cmpint(gpiod_line_active_state(line), ==, + GPIOD_LINE_ACTIVE_STATE_LOW); + g_assert_cmpint(gpiod_line_direction(line), ==, + GPIOD_LINE_DIRECTION_INPUT); + + ret = gpiod_line_get_value(line); + g_assert_cmpint(ret, ==, 1); + g_assert_cmpint(errno, ==, 0); + + gpiod_line_release(line); + + config.flags = GPIOD_LINE_REQUEST_FLAG_BIAS_PULL_UP | + GPIOD_LINE_REQUEST_FLAG_ACTIVE_LOW; + + ret = gpiod_line_request(line, &config, 0); + g_assert_cmpint(ret, ==, 0); + + g_assert_true(gpiod_line_is_used(line)); + g_assert_false(gpiod_line_is_open_drain(line)); + g_assert_false(gpiod_line_is_open_source(line)); + g_assert_cmpint(gpiod_line_bias(line), ==, GPIOD_LINE_BIAS_PULL_UP); + g_assert_cmpint(gpiod_line_active_state(line), ==, + GPIOD_LINE_ACTIVE_STATE_LOW); + g_assert_cmpint(gpiod_line_direction(line), ==, + GPIOD_LINE_DIRECTION_INPUT); + + ret = gpiod_line_get_value(line); + g_assert_cmpint(ret, ==, 0); + g_assert_cmpint(errno, ==, 0); + + gpiod_line_release(line); } GPIOD_TEST_CASE(open_source_open_drain_input_mode, 0, { 8 }) @@ -629,6 +686,47 @@ GPIOD_TEST_CASE(open_source_open_drain_simultaneously, 0, { 8 }) g_assert_cmpint(errno, ==, EINVAL); } +GPIOD_TEST_CASE(multiple_bias_flags, 0, { 8 }) +{ + g_autoptr(gpiod_chip_struct) chip = NULL; + struct gpiod_line *line; + gint ret; + + chip = gpiod_chip_open(gpiod_test_chip_path(0)); + g_assert_nonnull(chip); + gpiod_test_return_if_failed(); + + line = gpiod_chip_get_line(chip, 2); + g_assert_nonnull(line); + gpiod_test_return_if_failed(); + + ret = gpiod_line_request_input_flags(line, GPIOD_TEST_CONSUMER, + GPIOD_LINE_REQUEST_FLAG_BIAS_DISABLE | + GPIOD_LINE_REQUEST_FLAG_BIAS_PULL_DOWN); + g_assert_cmpint(ret, ==, -1); + g_assert_cmpint(errno, ==, EINVAL); + + ret = gpiod_line_request_input_flags(line, GPIOD_TEST_CONSUMER, + GPIOD_LINE_REQUEST_FLAG_BIAS_DISABLE | + GPIOD_LINE_REQUEST_FLAG_BIAS_PULL_UP); + g_assert_cmpint(ret, ==, -1); + g_assert_cmpint(errno, ==, EINVAL); + + ret = gpiod_line_request_input_flags(line, GPIOD_TEST_CONSUMER, + GPIOD_LINE_REQUEST_FLAG_BIAS_PULL_DOWN | + GPIOD_LINE_REQUEST_FLAG_BIAS_PULL_UP); + g_assert_cmpint(ret, ==, -1); + g_assert_cmpint(errno, ==, EINVAL); + + ret = gpiod_line_request_input_flags(line, GPIOD_TEST_CONSUMER, + GPIOD_LINE_REQUEST_FLAG_BIAS_DISABLE | + GPIOD_LINE_REQUEST_FLAG_BIAS_PULL_DOWN | + GPIOD_LINE_REQUEST_FLAG_BIAS_PULL_UP); + g_assert_cmpint(ret, ==, -1); + g_assert_cmpint(errno, ==, EINVAL); +} + + /* Verify that the reference counting of the line fd handle works correctly. */ GPIOD_TEST_CASE(release_one_use_another, 0, { 8 }) { From patchwork Thu Nov 21 00:35:45 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kent Gibson X-Patchwork-Id: 1198603 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (no SPF record) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=linux-gpio-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="AXSfz0jc"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 47JLGN37stz9sNx for ; Thu, 21 Nov 2019 11:36:28 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726540AbfKUAg1 (ORCPT ); Wed, 20 Nov 2019 19:36:27 -0500 Received: from mail-pg1-f177.google.com ([209.85.215.177]:44880 "EHLO mail-pg1-f177.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726044AbfKUAg1 (ORCPT ); Wed, 20 Nov 2019 19:36:27 -0500 Received: by mail-pg1-f177.google.com with SMTP id e6so607674pgi.11 for ; Wed, 20 Nov 2019 16:36:26 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=uXrx5y2WL4cxWSJZuzUd3RqNYH2UrGCBMAG2mC95Yp4=; b=AXSfz0jcjjTyHMhI3GIEyMVeryqNiuvUAbYf+7Bv0Sth8B79LvBxgJzQiJ6lQwsxK1 Zok8MIUDM1QJSYZ61Wmq+uhggJy1sDlNCA2RdTppDBTGm0tx4/PYvqb4BmmxgQV7JFkF /dEJHcJROCeOxmen9nTd2rR141rQrjduf1zqhC8H8K1xt4iJ2gWwTINWVHBPWoCRxaSq mVgdomx1XUMdf8LdRzcA2n/X17QjcGRWMh8kN5CCB1RCsfQJ1G+3+iNUvdV97vOoA/Ed qynQKrzfqO490MkgTYpdul+JRb0dpVff8xPb4Vu1EEesrrZEQxgTKR2TPrwBAsfarBmu G3UA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=uXrx5y2WL4cxWSJZuzUd3RqNYH2UrGCBMAG2mC95Yp4=; b=PoP6e9r7w535PI3SZrV2gFtAAJYJkGpgrlnHCQKxi7cLQEOVYIx4i+W5oruxrfPvmS 8oWWw+RzrwgmtchbSBFPxnRCiA+hyc8Ol0cghn4R3xSq265VIgD3rBaYpPWMKXoILdKU fic9M78ZBewl69OAPKHmD8h5A+FFDulfxc03voqVpWEpMfDxYSt5Rx4jnOuOHMQ0hR0z qH9A4EmkDBdFXRqWSSosB6WDId166I18gJ8M8ue2O0L/si1gtecBXjICY0h2UuZYQeC6 I83LDQeOcIloP0RzfDbeCboLH0t40KCY93QpemSxdFzaPGVtvW3m7yeTwt4l9AJa4Wpj sCtg== X-Gm-Message-State: APjAAAUheVZkojz8ALjmoAXl4+ER8Ylq1m9r+uabaFIToJBRHKRSU+Xu eav6iSISPb4v44jsezswCRPN6fawHf4= X-Google-Smtp-Source: APXvYqyalKmijVbSPTv8DXSE3WQy9tqTxa+BNrGAkFk2nmJPeCtZdRw2ldF1ghTkNkaq48xnb5BHPw== X-Received: by 2002:a62:2942:: with SMTP id p63mr7614497pfp.110.1574296585266; Wed, 20 Nov 2019 16:36:25 -0800 (PST) Received: from sol.lan (220-235-109-115.dyn.iinet.net.au. [220.235.109.115]) by smtp.gmail.com with ESMTPSA id s1sm420756pgk.9.2019.11.20.16.36.23 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 20 Nov 2019 16:36:24 -0800 (PST) From: Kent Gibson To: linux-gpio@vger.kernel.org, bgolaszewski@baylibre.com Cc: Kent Gibson Subject: [libgpiod] [PATCH v2 03/14] bindings: cxx: add support for bias flags Date: Thu, 21 Nov 2019 08:35:45 +0800 Message-Id: <20191121003556.9020-4-warthog618@gmail.com> X-Mailer: git-send-email 2.24.0 In-Reply-To: <20191121003556.9020-1-warthog618@gmail.com> References: <20191121003556.9020-1-warthog618@gmail.com> MIME-Version: 1.0 Sender: linux-gpio-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-gpio@vger.kernel.org Add support for bias flags in line requests and returning the line bias setting via a bias accessor. Based on initial work by Drew Fustini . Signed-off-by: Kent Gibson --- bindings/cxx/gpiod.hpp | 26 ++++++++++++++++++++++++++ bindings/cxx/line.cpp | 19 +++++++++++++++++++ bindings/cxx/line_bulk.cpp | 6 ++++++ 3 files changed, 51 insertions(+) diff --git a/bindings/cxx/gpiod.hpp b/bindings/cxx/gpiod.hpp index b5a9401..2b1a6ab 100644 --- a/bindings/cxx/gpiod.hpp +++ b/bindings/cxx/gpiod.hpp @@ -233,6 +233,12 @@ struct line_request /**< The line is an open-source port. */ GPIOD_API static const ::std::bitset<32> FLAG_OPEN_DRAIN; /**< The line is an open-drain port. */ + GPIOD_API static const ::std::bitset<32> FLAG_BIAS_DISABLE; + /**< The line has neither pull-up nor pull-down resistor enabled */ + GPIOD_API static const ::std::bitset<32> FLAG_BIAS_PULL_DOWN; + /**< The line has a configurable pull-down resistor enabled */ + GPIOD_API static const ::std::bitset<32> FLAG_BIAS_PULL_UP; + /**< The line has a configurable pull-up resistor enabled */ ::std::string consumer; /**< Consumer name to pass to the request. */ @@ -320,6 +326,12 @@ public: */ GPIOD_API int active_state(void) const; + /** + * @brief Get current bias of this line. + * @return Current bias setting. + */ + GPIOD_API int bias(void) const; + /** * @brief Check if this line is used by the kernel or other user space * process. @@ -456,6 +468,20 @@ public: /**< Line's active state is high. */ }; + /** + * @brief Possible bias settings. + */ + enum : int { + BIAS_AS_IS = 1, + /**< Line's bias state is unknown. */ + BIAS_DISABLE, + /**< Line's internal bias is disabled. */ + BIAS_PULL_UP, + /**< Line's internal pull-up bias is enabled. */ + BIAS_PULL_DOWN, + /**< Line's internal pull-down bias is enabled. */ + }; + private: line(::gpiod_line* line, const chip& owner); diff --git a/bindings/cxx/line.cpp b/bindings/cxx/line.cpp index df6eada..dd6bb6a 100644 --- a/bindings/cxx/line.cpp +++ b/bindings/cxx/line.cpp @@ -67,6 +67,25 @@ int line::active_state(void) const return active == GPIOD_LINE_ACTIVE_STATE_HIGH ? ACTIVE_HIGH : ACTIVE_LOW; } +int line::bias(void) const +{ + this->throw_if_null(); + + int bias = ::gpiod_line_bias(this->_m_line); + + switch (bias) { + case GPIOD_LINE_BIAS_PULL_UP: + return BIAS_PULL_UP; + case GPIOD_LINE_BIAS_PULL_DOWN: + return BIAS_PULL_DOWN; + case GPIOD_LINE_BIAS_DISABLE: + return BIAS_DISABLE; + case GPIOD_LINE_BIAS_AS_IS: + default: + return BIAS_AS_IS; + } +} + bool line::is_used(void) const { this->throw_if_null(); diff --git a/bindings/cxx/line_bulk.cpp b/bindings/cxx/line_bulk.cpp index c708c8b..5f1cac4 100644 --- a/bindings/cxx/line_bulk.cpp +++ b/bindings/cxx/line_bulk.cpp @@ -14,6 +14,9 @@ namespace gpiod { const ::std::bitset<32> line_request::FLAG_ACTIVE_LOW(GPIOD_BIT(0)); const ::std::bitset<32> line_request::FLAG_OPEN_SOURCE(GPIOD_BIT(1)); const ::std::bitset<32> line_request::FLAG_OPEN_DRAIN(GPIOD_BIT(2)); +const ::std::bitset<32> line_request::FLAG_BIAS_DISABLE(GPIOD_BIT(3)); +const ::std::bitset<32> line_request::FLAG_BIAS_PULL_DOWN(GPIOD_BIT(4)); +const ::std::bitset<32> line_request::FLAG_BIAS_PULL_UP(GPIOD_BIT(5)); namespace { @@ -38,6 +41,9 @@ const ::std::map<::std::bitset<32>, int, bitset_cmp> reqflag_mapping = { { line_request::FLAG_ACTIVE_LOW, GPIOD_LINE_REQUEST_FLAG_ACTIVE_LOW, }, { line_request::FLAG_OPEN_DRAIN, GPIOD_LINE_REQUEST_FLAG_OPEN_DRAIN, }, { line_request::FLAG_OPEN_SOURCE, GPIOD_LINE_REQUEST_FLAG_OPEN_SOURCE, }, + { line_request::FLAG_BIAS_DISABLE, GPIOD_LINE_REQUEST_FLAG_BIAS_DISABLE, }, + { line_request::FLAG_BIAS_PULL_DOWN, GPIOD_LINE_REQUEST_FLAG_BIAS_PULL_DOWN, }, + { line_request::FLAG_BIAS_PULL_UP, GPIOD_LINE_REQUEST_FLAG_BIAS_PULL_UP, }, }; } /* namespace */ From patchwork Thu Nov 21 00:35:46 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kent Gibson X-Patchwork-Id: 1198604 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (no SPF record) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=linux-gpio-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="hUYGGEYZ"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 47JLGQ1Rpjz9sNx for ; Thu, 21 Nov 2019 11:36:30 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726333AbfKUAg3 (ORCPT ); Wed, 20 Nov 2019 19:36:29 -0500 Received: from mail-pf1-f194.google.com ([209.85.210.194]:36111 "EHLO mail-pf1-f194.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726044AbfKUAg3 (ORCPT ); Wed, 20 Nov 2019 19:36:29 -0500 Received: by mail-pf1-f194.google.com with SMTP id b19so690697pfd.3 for ; Wed, 20 Nov 2019 16:36:28 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=1QMIzQdivMNr/urrFibb1d3I1FoG0wJ7ERlY8y923yU=; b=hUYGGEYZlYp1TzZioBErw74Toqmh9G+chNd+2cZPBpuaSCd0/8cJP9olbPNhbl766C 3aw63c+ohGZq8sbzONCUz+9fkho0q8f9zKvFTHRezEZetvEGESELAX+snl+gOTHW1BJS Y40Zdjj1RxItSGlou4NmrgA6dSaMa+UEHePz1RO39ICnAPmopXxfyZnARNPoknZG21H2 mq9xeyxrVxHnDKZDME99o/ijZzSpF19SBbPSMEr5EIo5YkRcWZok6GdiHQtHNmaN/d0V fKAbI2P9bLDx/p0yOxepiM+Efvri85/M2tx6iB3D2TSlX6/6+wEEpeypfEEYAvZUPcZG xyAg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=1QMIzQdivMNr/urrFibb1d3I1FoG0wJ7ERlY8y923yU=; b=EPUED2LYw1jx2QSqFVC8LKJJWBC1KMuqo6rAxe8cKCBMX9K2tCcwp9+z1+NzClFtsM FPNXY0nHQBDt3oBysnc522HeB9aXPMaizdV1REi6brTZicodjjubmuuu7uggzaDBQRnQ q5H0TcQ85XkwFAVKV2J8p7QudyyhCrM4VaJugUaZRPlNJXmjVCIfdmYFeQD+JphaWkKK GtH59L3qBMmK8J+VxxBtSW5MQVLG9Hyf7rGWco6fuiwHiz54F5XyNScZjD0jGDMOadrG 7wXK6GSdcjQFPwd0uoicQgpcGF3ny9svCJ25i/m+hDssB9rFpJhs0mVk/CtbpVByBxyL FOMQ== X-Gm-Message-State: APjAAAXPoYTcDbD2R0vvd7sjdV1D8PLhtiTNwZm1NZu5prpi44lT+X2E yniG1Uvf73LTzG3nhp/6NWDdhz0SVLo= X-Google-Smtp-Source: APXvYqzWjwXq/ODzOslAzdApUwNgBS31rFnlg1RDdgWmEg4PXZ8Y7qDjZt/rDtTL0lXu+ogJeZ9+Jw== X-Received: by 2002:a63:5c42:: with SMTP id n2mr6126195pgm.229.1574296587780; Wed, 20 Nov 2019 16:36:27 -0800 (PST) Received: from sol.lan (220-235-109-115.dyn.iinet.net.au. [220.235.109.115]) by smtp.gmail.com with ESMTPSA id s1sm420756pgk.9.2019.11.20.16.36.25 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 20 Nov 2019 16:36:27 -0800 (PST) From: Kent Gibson To: linux-gpio@vger.kernel.org, bgolaszewski@baylibre.com Cc: Kent Gibson Subject: [libgpiod] [PATCH v2 04/14] bindings: cxx: tests: add tests for bias flags Date: Thu, 21 Nov 2019 08:35:46 +0800 Message-Id: <20191121003556.9020-5-warthog618@gmail.com> X-Mailer: git-send-email 2.24.0 In-Reply-To: <20191121003556.9020-1-warthog618@gmail.com> References: <20191121003556.9020-1-warthog618@gmail.com> MIME-Version: 1.0 Sender: linux-gpio-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-gpio@vger.kernel.org Extend test coverage over the bias flags in requests and the bias setting returned by line.bias(). Signed-off-by: Kent Gibson --- bindings/cxx/tests/tests-line.cpp | 87 +++++++++++++++++++++++++++++++ 1 file changed, 87 insertions(+) diff --git a/bindings/cxx/tests/tests-line.cpp b/bindings/cxx/tests/tests-line.cpp index fedaa05..9a0b488 100644 --- a/bindings/cxx/tests/tests-line.cpp +++ b/bindings/cxx/tests/tests-line.cpp @@ -52,6 +52,9 @@ TEST_CASE("Line information can be correctly retrieved", "[line]") REQUIRE(line.consumer().empty()); REQUIRE_FALSE(line.is_requested()); REQUIRE_FALSE(line.is_used()); + REQUIRE_FALSE(line.is_open_drain()); + REQUIRE_FALSE(line.is_open_source()); + REQUIRE(line.bias() == ::gpiod::line::BIAS_AS_IS); } SECTION("exported line") @@ -68,6 +71,9 @@ TEST_CASE("Line information can be correctly retrieved", "[line]") REQUIRE(line.active_state() == ::gpiod::line::ACTIVE_HIGH); REQUIRE(line.is_requested()); REQUIRE(line.is_used()); + REQUIRE_FALSE(line.is_open_drain()); + REQUIRE_FALSE(line.is_open_source()); + REQUIRE(line.bias() == ::gpiod::line::BIAS_AS_IS); } SECTION("exported line with flags") @@ -88,6 +94,87 @@ TEST_CASE("Line information can be correctly retrieved", "[line]") REQUIRE(line.is_used()); REQUIRE(line.is_open_drain()); REQUIRE_FALSE(line.is_open_source()); + REQUIRE(line.bias() == ::gpiod::line::BIAS_AS_IS); + } + + SECTION("exported open source line") + { + ::gpiod::line_request config; + + config.consumer = consumer.c_str(); + config.request_type = ::gpiod::line_request::DIRECTION_OUTPUT; + config.flags = ::gpiod::line_request::FLAG_OPEN_SOURCE; + line.request(config); + + REQUIRE(line.offset() == 4); + REQUIRE(line.name() == "gpio-mockup-A-4"); + REQUIRE(line.direction() == ::gpiod::line::DIRECTION_OUTPUT); + REQUIRE(line.active_state() == ::gpiod::line::ACTIVE_HIGH); + REQUIRE(line.is_requested()); + REQUIRE(line.is_used()); + REQUIRE_FALSE(line.is_open_drain()); + REQUIRE(line.is_open_source()); + REQUIRE(line.bias() == ::gpiod::line::BIAS_AS_IS); + } + + SECTION("exported bias disable line") + { + ::gpiod::line_request config; + + config.consumer = consumer.c_str(); + config.request_type = ::gpiod::line_request::DIRECTION_OUTPUT; + config.flags = ::gpiod::line_request::FLAG_BIAS_DISABLE; + line.request(config); + + REQUIRE(line.offset() == 4); + REQUIRE(line.name() == "gpio-mockup-A-4"); + REQUIRE(line.direction() == ::gpiod::line::DIRECTION_OUTPUT); + REQUIRE(line.active_state() == ::gpiod::line::ACTIVE_HIGH); + REQUIRE(line.is_requested()); + REQUIRE(line.is_used()); + REQUIRE_FALSE(line.is_open_drain()); + REQUIRE_FALSE(line.is_open_source()); + REQUIRE(line.bias() == ::gpiod::line::BIAS_DISABLE); + } + + SECTION("exported pull-down line") + { + ::gpiod::line_request config; + + config.consumer = consumer.c_str(); + config.request_type = ::gpiod::line_request::DIRECTION_OUTPUT; + config.flags = ::gpiod::line_request::FLAG_BIAS_PULL_DOWN; + line.request(config); + + REQUIRE(line.offset() == 4); + REQUIRE(line.name() == "gpio-mockup-A-4"); + REQUIRE(line.direction() == ::gpiod::line::DIRECTION_OUTPUT); + REQUIRE(line.active_state() == ::gpiod::line::ACTIVE_HIGH); + REQUIRE(line.is_requested()); + REQUIRE(line.is_used()); + REQUIRE_FALSE(line.is_open_drain()); + REQUIRE_FALSE(line.is_open_source()); + REQUIRE(line.bias() == ::gpiod::line::BIAS_PULL_DOWN); + } + + SECTION("exported pull-up line") + { + ::gpiod::line_request config; + + config.consumer = consumer.c_str(); + config.request_type = ::gpiod::line_request::DIRECTION_OUTPUT; + config.flags = ::gpiod::line_request::FLAG_BIAS_PULL_UP; + line.request(config); + + REQUIRE(line.offset() == 4); + REQUIRE(line.name() == "gpio-mockup-A-4"); + REQUIRE(line.direction() == ::gpiod::line::DIRECTION_OUTPUT); + REQUIRE(line.active_state() == ::gpiod::line::ACTIVE_HIGH); + REQUIRE(line.is_requested()); + REQUIRE(line.is_used()); + REQUIRE_FALSE(line.is_open_drain()); + REQUIRE_FALSE(line.is_open_source()); + REQUIRE(line.bias() == ::gpiod::line::BIAS_PULL_UP); } SECTION("update line info") From patchwork Thu Nov 21 00:35:47 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kent Gibson X-Patchwork-Id: 1198605 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (no SPF record) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=linux-gpio-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="b3c4UJf9"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 47JLGS4Szyz9sNx for ; Thu, 21 Nov 2019 11:36:32 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726351AbfKUAgc (ORCPT ); Wed, 20 Nov 2019 19:36:32 -0500 Received: from mail-pj1-f68.google.com ([209.85.216.68]:36379 "EHLO mail-pj1-f68.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726044AbfKUAgc (ORCPT ); Wed, 20 Nov 2019 19:36:32 -0500 Received: by mail-pj1-f68.google.com with SMTP id cq11so617969pjb.3 for ; Wed, 20 Nov 2019 16:36:31 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=Ji4XS3PkDfmdwlRr49EB6DYi3k4STZ5B6ixXS4OLMWw=; b=b3c4UJf9jhKYpEAqkCPLVCYbxF+dNtyplHsW74SrZMgzsW1yusQV/jOiPRkhQfpemg 3MT38dUQvxVu91fP8iqyqboHKFoGj9xqLWUVCyvxPIKW7LOgGYv1yt4b9r2PPm1l+xSZ 56dle4lXrlUiVTm8frGMtek5YCEqcVuqcgi2u/dSJrCFCQPI7yd6WvGSAi3heJhmJK/C GeWh7rKty84iB404EfLPPDVN7b24zs5L8hXeDPN5CtUOGU5E2/8MXScTFR8CvD/lPWjd bXngMCeMy4jrx7EzKoSKHVnsWzqSBIfcf/xMosZ3r7Z14OimAn2bxBwo3SxlM2Lu2s0R t8iA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=Ji4XS3PkDfmdwlRr49EB6DYi3k4STZ5B6ixXS4OLMWw=; b=YRvKwmnq8vk8wC5QkPS6qVl9axde64gpX6z7YOAuh7kCBElaJcMVjpS2S3v+vJX0RU 7m64Onb70nmnY/D6rZpR+aLB+rkwOCUL3OAU4fE5zbAXWiuPVP6VX5tFlcBIawHVR5p+ YevqaQoHR1KoxmAIFIYIj2pSVOcc3RKNI1+dRLHxNnIlUDIaSYTUM+f9Fv2WpFrzerbE vT6oAFfa5v+D7Md+lSmPVioD2ild20uXCVjTupl0ldp9fJ1DoN4fJAnUpX6L89+hheuR he38uByp4RQkDzHl2NNbagyDkz13dKVARF1g8GD+Nz1bXoEExK9lM3rwHE4AIQy7f5Aw Ftgg== X-Gm-Message-State: APjAAAXAM4nj4Wf0gSG/OEOu24aOnxtQqdQNJuWnmvZarpEUFxt/E+Q+ lGI2VO36ZCz887Oemxyd5tN+hzxMyfc= X-Google-Smtp-Source: APXvYqwpflVHTxGFL37hUNn9sruenCDcXW3IO68elrsYicZqwvJblilUHFgjkHZjnfHT8hxvb6n4WQ== X-Received: by 2002:a17:90a:2a44:: with SMTP id d4mr7521190pjg.91.1574296590387; Wed, 20 Nov 2019 16:36:30 -0800 (PST) Received: from sol.lan (220-235-109-115.dyn.iinet.net.au. [220.235.109.115]) by smtp.gmail.com with ESMTPSA id s1sm420756pgk.9.2019.11.20.16.36.28 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 20 Nov 2019 16:36:29 -0800 (PST) From: Kent Gibson To: linux-gpio@vger.kernel.org, bgolaszewski@baylibre.com Cc: Kent Gibson Subject: [libgpiod] [PATCH v2 05/14] bindings: python: add support for bias flags Date: Thu, 21 Nov 2019 08:35:47 +0800 Message-Id: <20191121003556.9020-6-warthog618@gmail.com> X-Mailer: git-send-email 2.24.0 In-Reply-To: <20191121003556.9020-1-warthog618@gmail.com> References: <20191121003556.9020-1-warthog618@gmail.com> MIME-Version: 1.0 Sender: linux-gpio-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-gpio@vger.kernel.org Add support for bias flags in line requests and returning the line bias setting via a bias accessor. Based on initial work by Drew Fustini . Signed-off-by: Kent Gibson --- bindings/python/gpiodmodule.c | 82 +++++++++++++++++++++++++++++++++++ 1 file changed, 82 insertions(+) diff --git a/bindings/python/gpiodmodule.c b/bindings/python/gpiodmodule.c index 2f6ef51..4723771 100644 --- a/bindings/python/gpiodmodule.c +++ b/bindings/python/gpiodmodule.c @@ -60,6 +60,9 @@ enum { gpiod_LINE_REQ_FLAG_OPEN_DRAIN = GPIOD_BIT(0), gpiod_LINE_REQ_FLAG_OPEN_SOURCE = GPIOD_BIT(1), gpiod_LINE_REQ_FLAG_ACTIVE_LOW = GPIOD_BIT(2), + gpiod_LINE_REQ_FLAG_BIAS_DISABLE = GPIOD_BIT(3), + gpiod_LINE_REQ_FLAG_BIAS_PULL_DOWN = GPIOD_BIT(4), + gpiod_LINE_REQ_FLAG_BIAS_PULL_UP = GPIOD_BIT(5), }; enum { @@ -72,6 +75,13 @@ enum { gpiod_ACTIVE_LOW, }; +enum { + gpiod_BIAS_AS_IS = 1, + gpiod_BIAS_DISABLE, + gpiod_BIAS_PULL_UP, + gpiod_BIAS_PULL_DOWN, +}; + enum { gpiod_RISING_EDGE = 1, gpiod_FALLING_EDGE, @@ -358,6 +368,34 @@ static PyObject *gpiod_Line_active_state(gpiod_LineObject *self, return ret; } +PyDoc_STRVAR(gpiod_Line_bias_doc, +"bias() -> integer\n" +"\n" +"Get the bias setting of this GPIO line."); + +static PyObject *gpiod_Line_bias(gpiod_LineObject *self, + PyObject *Py_UNUSED(ignored)) +{ + int bias; + + if (gpiod_ChipIsClosed(self->owner)) + return NULL; + + bias = gpiod_line_bias(self->line); + + switch (bias) { + case GPIOD_LINE_BIAS_PULL_UP: + return Py_BuildValue("I", gpiod_BIAS_PULL_UP); + case GPIOD_LINE_BIAS_PULL_DOWN: + return Py_BuildValue("I", gpiod_BIAS_PULL_DOWN); + case GPIOD_LINE_BIAS_DISABLE: + return Py_BuildValue("I", gpiod_BIAS_DISABLE); + case GPIOD_LINE_BIAS_AS_IS: + default: + return Py_BuildValue("I", gpiod_BIAS_AS_IS); + } +} + PyDoc_STRVAR(gpiod_Line_is_used_doc, "is_used() -> boolean\n" "\n" @@ -752,6 +790,12 @@ static PyMethodDef gpiod_Line_methods[] = { .ml_flags = METH_NOARGS, .ml_doc = gpiod_Line_active_state_doc, }, + { + .ml_name = "bias", + .ml_meth = (PyCFunction)gpiod_Line_bias, + .ml_flags = METH_NOARGS, + .ml_doc = gpiod_Line_bias_doc, + }, { .ml_name = "is_used", .ml_meth = (PyCFunction)gpiod_Line_is_used, @@ -1030,6 +1074,12 @@ static void gpiod_MakeRequestConfig(struct gpiod_line_request_config *conf, conf->flags |= GPIOD_LINE_REQUEST_FLAG_OPEN_SOURCE; if (flags & gpiod_LINE_REQ_FLAG_ACTIVE_LOW) conf->flags |= GPIOD_LINE_REQUEST_FLAG_ACTIVE_LOW; + if (flags & gpiod_LINE_REQ_FLAG_BIAS_DISABLE) + conf->flags |= GPIOD_LINE_REQUEST_FLAG_BIAS_DISABLE; + if (flags & gpiod_LINE_REQ_FLAG_BIAS_PULL_DOWN) + conf->flags |= GPIOD_LINE_REQUEST_FLAG_BIAS_PULL_DOWN; + if (flags & gpiod_LINE_REQ_FLAG_BIAS_PULL_UP) + conf->flags |= GPIOD_LINE_REQUEST_FLAG_BIAS_PULL_UP; } PyDoc_STRVAR(gpiod_LineBulk_request_doc, @@ -2313,6 +2363,26 @@ static gpiod_ConstDescr gpiod_ConstList[] = { .name = "ACTIVE_LOW", .val = gpiod_ACTIVE_LOW, }, + { + .typeobj = &gpiod_LineType, + .name = "BIAS_AS_IS", + .val = gpiod_BIAS_AS_IS, + }, + { + .typeobj = &gpiod_LineType, + .name = "BIAS_DISABLE", + .val = gpiod_BIAS_DISABLE, + }, + { + .typeobj = &gpiod_LineType, + .name = "BIAS_PULL_UP", + .val = gpiod_BIAS_PULL_UP, + }, + { + .typeobj = &gpiod_LineType, + .name = "BIAS_PULL_DOWN", + .val = gpiod_BIAS_PULL_DOWN, + }, { .typeobj = &gpiod_LineEventType, .name = "RISING_EDGE", @@ -2381,6 +2451,18 @@ static gpiod_ModuleConst gpiod_ModuleConsts[] = { .name = "LINE_REQ_FLAG_ACTIVE_LOW", .value = gpiod_LINE_REQ_FLAG_ACTIVE_LOW, }, + { + .name = "LINE_REQ_FLAG_BIAS_DISABLE", + .value = gpiod_LINE_REQ_FLAG_BIAS_DISABLE, + }, + { + .name = "LINE_REQ_FLAG_BIAS_PULL_DOWN", + .value = gpiod_LINE_REQ_FLAG_BIAS_PULL_DOWN, + }, + { + .name = "LINE_REQ_FLAG_BIAS_PULL_UP", + .value = gpiod_LINE_REQ_FLAG_BIAS_PULL_UP, + }, { } }; From patchwork Thu Nov 21 00:35:48 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kent Gibson X-Patchwork-Id: 1198606 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (no SPF record) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=linux-gpio-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="RJUuH1UC"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 47JLGf6NFsz9sNx for ; Thu, 21 Nov 2019 11:36:42 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726202AbfKUAge (ORCPT ); Wed, 20 Nov 2019 19:36:34 -0500 Received: from mail-pj1-f65.google.com ([209.85.216.65]:46068 "EHLO mail-pj1-f65.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726044AbfKUAge (ORCPT ); Wed, 20 Nov 2019 19:36:34 -0500 Received: by mail-pj1-f65.google.com with SMTP id m71so600405pjb.12 for ; Wed, 20 Nov 2019 16:36:33 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=S/HBD8d8BDWiXdFnRjwHb/de2FlPpTYAQz1J8zQ/lgw=; b=RJUuH1UCh9uk8oeKJsa+1MIEVaFa35x2VyL6Zoh0At3FP+kUFAREwGQdwTP4oX6AJh XJB26BIOGS7ClMGH/UP+CvjzXk1E9ljp9yuMs7iJ5oZArx0VzU1HVLSkfxUJLd3BlwQI eUGOWw8qGWZHExFiYGYczKgEK2r+dkOZlG0SreQ7TNj/av7h1mRMFH/tOs/a11QlWEvh rAqdnaITpvXUxVfDhp5zF4Lg4PWcYH941w18kUH9NZqSNvOqQ/GiGMHiik737j04XCYw ir0tTCAk+F5bjTAHuiLIJRWN6cs54QUog4/4MXTDS3hsLMLZViiUy+A6jxJdPx6cqSLM o4XQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=S/HBD8d8BDWiXdFnRjwHb/de2FlPpTYAQz1J8zQ/lgw=; b=cC31QCyIIUx0ybBIweF/6ug63eQGyZbVtpb21JodI0MCykAFOam8XweaupngyXFjEG sIFiC4kb+MLI+BxHk/yZtcihNGNeJ82WZk4ZCbF8+BmjRcS5eviP2DLDL7Pttdq21iiO Nl1exWbkwhMuB/xazljfaXMIKwRMNxNVuala6hY0LZmNxYp88F2nZgrJoWKFg4u/Puxv ePYQWr6Fjr2l8Xmx3ndpNkFVwd7q6ZfE9WwHmSvbBqdtmaVESSVAvTaJeklPpaqtB7bw 7Xwtxb1/PV1nG0hA4DXDvOHVEtsQyPIJzKT71SVyhtZ9Mi8cdgNsoZ/qD9u2BgC1SaJd 116Q== X-Gm-Message-State: APjAAAWR90845/LYtJofwElKSRibAJm1qThQamBBIcHRTg/h7bXLXJ/H pxLi9NRI5/oOKHRRnISy4Q+9x2HJWRQ= X-Google-Smtp-Source: APXvYqw/4lz5iNaKDhWeZvW8/Fb350WtjW8zyjIp1ukcyt0EOABMkxun+2ciH36N6+uRdprlvSaamQ== X-Received: by 2002:a17:902:6b85:: with SMTP id p5mr5789874plk.32.1574296592842; Wed, 20 Nov 2019 16:36:32 -0800 (PST) Received: from sol.lan (220-235-109-115.dyn.iinet.net.au. [220.235.109.115]) by smtp.gmail.com with ESMTPSA id s1sm420756pgk.9.2019.11.20.16.36.30 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 20 Nov 2019 16:36:32 -0800 (PST) From: Kent Gibson To: linux-gpio@vger.kernel.org, bgolaszewski@baylibre.com Cc: Kent Gibson Subject: [libgpiod] [PATCH v2 06/14] bindings: python: tests: add tests for bias flags Date: Thu, 21 Nov 2019 08:35:48 +0800 Message-Id: <20191121003556.9020-7-warthog618@gmail.com> X-Mailer: git-send-email 2.24.0 In-Reply-To: <20191121003556.9020-1-warthog618@gmail.com> References: <20191121003556.9020-1-warthog618@gmail.com> MIME-Version: 1.0 Sender: linux-gpio-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-gpio@vger.kernel.org Extend test coverage to cover the bias flags in requests and the bias setting returned by line.bias(). Signed-off-by: Kent Gibson --- bindings/python/tests/gpiod_py_test.py | 91 ++++++++++++++++++++++++++ 1 file changed, 91 insertions(+) diff --git a/bindings/python/tests/gpiod_py_test.py b/bindings/python/tests/gpiod_py_test.py index ed31c8e..9330b43 100755 --- a/bindings/python/tests/gpiod_py_test.py +++ b/bindings/python/tests/gpiod_py_test.py @@ -306,6 +306,97 @@ class LineInfo(MockupTestCase): self.assertTrue(line.is_requested()) self.assertTrue(line.is_open_drain()) self.assertFalse(line.is_open_source()) + self.assertEqual(line.bias(), gpiod.Line.BIAS_AS_IS) + + def test_exported_open_drain_line(self): + with gpiod.Chip(mockup.chip_name(0)) as chip: + line = chip.get_line(4) + flags = gpiod.LINE_REQ_FLAG_OPEN_DRAIN + line.request(consumer=default_consumer, + type=gpiod.LINE_REQ_DIR_OUT, + flags=flags) + self.assertEqual(line.offset(), 4) + self.assertEqual(line.name(), 'gpio-mockup-A-4') + self.assertEqual(line.direction(), gpiod.Line.DIRECTION_OUTPUT) + self.assertEqual(line.active_state(), gpiod.Line.ACTIVE_HIGH) + self.assertEqual(line.consumer(), default_consumer) + self.assertTrue(line.is_used()) + self.assertTrue(line.is_requested()) + self.assertTrue(line.is_open_drain()) + self.assertFalse(line.is_open_source()) + self.assertEqual(line.bias(), gpiod.Line.BIAS_AS_IS) + + def test_exported_open_source_line(self): + with gpiod.Chip(mockup.chip_name(0)) as chip: + line = chip.get_line(4) + flags = gpiod.LINE_REQ_FLAG_OPEN_SOURCE + line.request(consumer=default_consumer, + type=gpiod.LINE_REQ_DIR_OUT, + flags=flags) + self.assertEqual(line.offset(), 4) + self.assertEqual(line.name(), 'gpio-mockup-A-4') + self.assertEqual(line.direction(), gpiod.Line.DIRECTION_OUTPUT) + self.assertEqual(line.active_state(), gpiod.Line.ACTIVE_HIGH) + self.assertEqual(line.consumer(), default_consumer) + self.assertTrue(line.is_used()) + self.assertTrue(line.is_requested()) + self.assertFalse(line.is_open_drain()) + self.assertTrue(line.is_open_source()) + self.assertEqual(line.bias(), gpiod.Line.BIAS_AS_IS) + + def test_exported_bias_disable_line(self): + with gpiod.Chip(mockup.chip_name(0)) as chip: + line = chip.get_line(4) + flags = gpiod.LINE_REQ_FLAG_BIAS_DISABLE + line.request(consumer=default_consumer, + type=gpiod.LINE_REQ_DIR_OUT, + flags=flags) + self.assertEqual(line.offset(), 4) + self.assertEqual(line.name(), 'gpio-mockup-A-4') + self.assertEqual(line.direction(), gpiod.Line.DIRECTION_OUTPUT) + self.assertEqual(line.active_state(), gpiod.Line.ACTIVE_HIGH) + self.assertEqual(line.consumer(), default_consumer) + self.assertTrue(line.is_used()) + self.assertTrue(line.is_requested()) + self.assertFalse(line.is_open_drain()) + self.assertFalse(line.is_open_source()) + self.assertEqual(line.bias(), gpiod.Line.BIAS_DISABLE) + + def test_exported_bias_pull_down_line(self): + with gpiod.Chip(mockup.chip_name(0)) as chip: + line = chip.get_line(4) + flags = gpiod.LINE_REQ_FLAG_BIAS_PULL_DOWN + line.request(consumer=default_consumer, + type=gpiod.LINE_REQ_DIR_OUT, + flags=flags) + self.assertEqual(line.offset(), 4) + self.assertEqual(line.name(), 'gpio-mockup-A-4') + self.assertEqual(line.direction(), gpiod.Line.DIRECTION_OUTPUT) + self.assertEqual(line.active_state(), gpiod.Line.ACTIVE_HIGH) + self.assertEqual(line.consumer(), default_consumer) + self.assertTrue(line.is_used()) + self.assertTrue(line.is_requested()) + self.assertFalse(line.is_open_drain()) + self.assertFalse(line.is_open_source()) + self.assertEqual(line.bias(), gpiod.Line.BIAS_PULL_DOWN) + + def test_exported_bias_pull_up_line(self): + with gpiod.Chip(mockup.chip_name(0)) as chip: + line = chip.get_line(4) + flags = gpiod.LINE_REQ_FLAG_BIAS_PULL_UP + line.request(consumer=default_consumer, + type=gpiod.LINE_REQ_DIR_OUT, + flags=flags) + self.assertEqual(line.offset(), 4) + self.assertEqual(line.name(), 'gpio-mockup-A-4') + self.assertEqual(line.direction(), gpiod.Line.DIRECTION_OUTPUT) + self.assertEqual(line.active_state(), gpiod.Line.ACTIVE_HIGH) + self.assertEqual(line.consumer(), default_consumer) + self.assertTrue(line.is_used()) + self.assertTrue(line.is_requested()) + self.assertFalse(line.is_open_drain()) + self.assertFalse(line.is_open_source()) + self.assertEqual(line.bias(), gpiod.Line.BIAS_PULL_UP) def test_update_line_info(self): with gpiod.Chip(mockup.chip_name(0)) as chip: From patchwork Thu Nov 21 00:35:49 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kent Gibson X-Patchwork-Id: 1198607 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (no SPF record) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=linux-gpio-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="eHBp0uvW"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 47JLGg4tq5z9sPL for ; Thu, 21 Nov 2019 11:36:43 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726704AbfKUAgh (ORCPT ); Wed, 20 Nov 2019 19:36:37 -0500 Received: from mail-pg1-f194.google.com ([209.85.215.194]:43778 "EHLO mail-pg1-f194.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726573AbfKUAgg (ORCPT ); Wed, 20 Nov 2019 19:36:36 -0500 Received: by mail-pg1-f194.google.com with SMTP id b1so610225pgq.10 for ; Wed, 20 Nov 2019 16:36:36 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=RP7X0RojUFvuKrRD9e7EPNN8SLHYfigr/JUjG05aRds=; b=eHBp0uvWsPYvgOLidPa09HbP41DhIzFS9QUErD5yqVgqp0bB32ick6I2boXC0974o1 VYcfUE60OuO44ewDwRpDt0mzJRy6Ac/bGsQ/jMfKPWcP5H8KMEbczfunqAhPYgPXbJ37 7AzX9EewiUNFJjaSXGygHo3Vw2dinZweyalFmXwTu30cgfCF324rnVPmp0j8brPQqUqQ fUEf38J5fQ9Ns2rCAYVp6pQqcp0EOOmV2/Rp+wLHSEG4d0s/stY4dXYJh+5/scJ3DbwM gSSEa1wGRY/1IZJuQHjbNo5G5QTjYRtTGFh6KJShGWQjASsC6n2VS3I5r0EZkp4OS1Sh 2+CQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=RP7X0RojUFvuKrRD9e7EPNN8SLHYfigr/JUjG05aRds=; b=X7vQYW4yiuBoHjxtfgFx5FZRrdyvYR52GalX7qcTpnO5Ke/jwnFhde293Bl0KwoLqy iW5lX/CBPmJWsRC385/79oQQTVdUGclx/EOhGPKv8VjOtrJblM/RBd6mdagp4QD+A7WO CRmN+93OsH+PVIZQPPA6Mj5K2xUsdIjW5ocuDqjlAoabu/EN8B1DOu8xs+YlaVxLTnz0 gnBNhpS5BEcpKl5kPmQBg0gXhrryiwxP20qMEsUDjj9OJkndNe20nr7L0c5rguNOK0rU dWh4vAqO8XOZLVjgfJlBpWCmLnGCmP0+edrz1zJJRUWGNeVLzj5kqQU4RiCnqdyT3dOA R6oA== X-Gm-Message-State: APjAAAUXS1puV0PrcTUJeN5uCbjpXReZ5P17zJwN9KBEz3kOAz4yeXs1 mlBeFepuciS8CRvF1Z0Bv4s+cVIvcjw= X-Google-Smtp-Source: APXvYqwJonOmA8mzE+hMND/lmnG7AsNhF17WzJDyTZeV2ovDAYel+c3D8yakmWWJ1RKLhOhIv+1Yhg== X-Received: by 2002:a63:2341:: with SMTP id u1mr6214601pgm.231.1574296595336; Wed, 20 Nov 2019 16:36:35 -0800 (PST) Received: from sol.lan (220-235-109-115.dyn.iinet.net.au. [220.235.109.115]) by smtp.gmail.com with ESMTPSA id s1sm420756pgk.9.2019.11.20.16.36.33 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 20 Nov 2019 16:36:34 -0800 (PST) From: Kent Gibson To: linux-gpio@vger.kernel.org, bgolaszewski@baylibre.com Cc: Kent Gibson Subject: [libgpiod][PATCH v2 07/14] core: add support for SET_CONFIG Date: Thu, 21 Nov 2019 08:35:49 +0800 Message-Id: <20191121003556.9020-8-warthog618@gmail.com> X-Mailer: git-send-email 2.24.0 In-Reply-To: <20191121003556.9020-1-warthog618@gmail.com> References: <20191121003556.9020-1-warthog618@gmail.com> MIME-Version: 1.0 Sender: linux-gpio-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-gpio@vger.kernel.org Extend the libgpiod API to support the setting line configuration using the GPIO GPIOHANDLE_SET_CONFIG_IOCTL uAPI ioctl. The core change is the addition of gpiod_line_set_config, which provides a low level wrapper around the ioctl. Additionally, higher level helper functions, gpiod_line_set_flags, gpiod_line_set_direction_input, and gpiod_line_set_direction_output provide slightly simplified APIs for common use cases. Bulk forms of all functions are also provided. Signed-off-by: Kent Gibson --- include/gpiod.h | 123 +++++++++++++++++++++++++++++++ lib/core.c | 188 +++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 308 insertions(+), 3 deletions(-) diff --git a/include/gpiod.h b/include/gpiod.h index cdf0435..f86c70e 100644 --- a/include/gpiod.h +++ b/include/gpiod.h @@ -1251,6 +1251,15 @@ void gpiod_line_release_bulk(struct gpiod_line_bulk *bulk) GPIOD_API; */ bool gpiod_line_is_requested(struct gpiod_line *line) GPIOD_API; +/** + * @brief Check if the calling user has ownership of this line for values, + * not events. + * @param line GPIO line object. + * @return True if given line was requested for reading/setting values, + * false otherwise. + */ +bool gpiod_line_is_requested_values(struct gpiod_line *line) GPIOD_API; + /** * @brief Check if the calling user has neither requested ownership of this * line nor configured any event notifications. @@ -1301,6 +1310,7 @@ int gpiod_line_set_value(struct gpiod_line *line, int value) GPIOD_API; * @brief Set the values of a set of GPIO lines. * @param bulk Set of GPIO lines to reserve. * @param values An array holding line_bulk->num_lines new values for lines. + * A NULL pointer is interpreted as a logical low for all lines. * @return 0 is the operation succeeds. In case of an error this routine * returns -1 and sets the last error number. * @@ -1310,6 +1320,119 @@ int gpiod_line_set_value(struct gpiod_line *line, int value) GPIOD_API; int gpiod_line_set_value_bulk(struct gpiod_line_bulk *bulk, const int *values) GPIOD_API; +/** + * @} + * + * @defgroup __line_config__ Setting line configuration + * @{ + */ + +/** + * @brief Update the configuration of a single GPIO line. + * @param line GPIO line object. + * @param direction Updated direction which may be one of + * GPIOD_LINE_REQUEST_DIRECTION_AS_IS, + * GPIOD_LINE_REQUEST_DIRECTION_INPUT, or + * GPIOD_LINE_REQUEST_DIRECTION_OUTPUT. + * @param flags Replacement flags. + * @param value The new output value for the line when direction is + * GPIOD_LINE_REQUEST_DIRECTION_OUTPUT. + * @return 0 is the operation succeeds. In case of an error this routine + * returns -1 and sets the last error number. + */ +int gpiod_line_set_config(struct gpiod_line *line, int direction, + int flags, int value) GPIOD_API; + +/** + * @brief Update the configuration of a set of GPIO lines. + * @param bulk Set of GPIO lines. + * @param direction Updated direction which may be one of + * GPIOD_LINE_REQUEST_DIRECTION_AS_IS, + * GPIOD_LINE_REQUEST_DIRECTION_INPUT, or + * GPIOD_LINE_REQUEST_DIRECTION_OUTPUT. + * @param flags Replacement flags. + * @param values An array holding line_bulk->num_lines new logical values + * for lines when direction is + * GPIOD_LINE_REQUEST_DIRECTION_OUTPUT. + * A NULL pointer is interpreted as a logical low for all lines. + * @return 0 is the operation succeeds. In case of an error this routine + * returns -1 and sets the last error number. + * + * If the lines were not previously requested together, the behavior is + * undefined. + */ +int gpiod_line_set_config_bulk(struct gpiod_line_bulk *bulk, + int direction, int flags, + const int *values) GPIOD_API; + + +/** + * @brief Update the configuration flags of a single GPIO line. + * @param line GPIO line object. + * @param flags Replacement flags. + * @return 0 is the operation succeeds. In case of an error this routine + * returns -1 and sets the last error number. + */ +int gpiod_line_set_flags(struct gpiod_line *line, int flags) GPIOD_API; + +/** + * @brief Update the configuration flags of a set of GPIO lines. + * @param bulk Set of GPIO lines. + * @param flags Replacement flags. + * @return 0 is the operation succeeds. In case of an error this routine + * returns -1 and sets the last error number. + * + * If the lines were not previously requested together, the behavior is + * undefined. + */ +int gpiod_line_set_flags_bulk(struct gpiod_line_bulk *bulk, + int flags) GPIOD_API; + +/** + * @brief Set the direction of a single GPIO line to input. + * @param line GPIO line object. + * @return 0 is the operation succeeds. In case of an error this routine + * returns -1 and sets the last error number. + */ +int gpiod_line_set_direction_input(struct gpiod_line *line) GPIOD_API; + +/** + * @brief Set the direction of a set of GPIO lines to input. + * @param bulk Set of GPIO lines. + * @return 0 is the operation succeeds. In case of an error this routine + * returns -1 and sets the last error number. + * + * If the lines were not previously requested together, the behavior is + * undefined. + */ +int gpiod_line_set_direction_input_bulk(struct gpiod_line_bulk *bulk + ) GPIOD_API; + +/** + * @brief Set the direction of a single GPIO line to output. + * @param line GPIO line object. + * @param value The logical value output on the line. + * @return 0 is the operation succeeds. In case of an error this routine + * returns -1 and sets the last error number. + */ +int gpiod_line_set_direction_output(struct gpiod_line *line, + int value) GPIOD_API; + +/** + * @brief Set the direction of a set of GPIO lines to output. + * @param bulk Set of GPIO lines. + * @param values An array holding line_bulk->num_lines new logical values + * for lines. A NULL pointer is interpreted as a logical low + * for all lines. + * @return 0 is the operation succeeds. In case of an error this routine + * returns -1 and sets the last error number. + * + * If the lines were not previously requested together, the behavior is + * undefined. + */ +int gpiod_line_set_direction_output_bulk(struct gpiod_line_bulk *bulk, + const int *values) GPIOD_API; + /** * @} * diff --git a/lib/core.c b/lib/core.c index ece3b13..9511a22 100644 --- a/lib/core.c +++ b/lib/core.c @@ -34,10 +34,26 @@ struct line_fd_handle { struct gpiod_line { unsigned int offset; + + /* The GPIOD_LINE_DIRECTION */ int direction; + + /* The GPIOD_LINE_ACTIVE_STATE */ int active_state; + + /* The logical value last written to the line. */ + int output_value; + + /* The GPIOLINE_FLAGs returned by GPIO_GET_LINEINFO_IOCTL */ __u32 info_flags; + /* The GPIOD_LINE_REQUEST_FLAGs provided to request the line. */ + __u32 req_flags; + + /* + * Indicator of LINE_FREE, LINE_REQUESTED_VALUES or + * LINE_REQUESTED_EVENTS + */ int state; bool needs_update; @@ -457,6 +473,20 @@ static bool line_bulk_all_requested(struct gpiod_line_bulk *bulk) return true; } +static bool line_bulk_all_requested_values(struct gpiod_line_bulk *bulk) +{ + struct gpiod_line *line, **lineptr; + + gpiod_line_bulk_foreach_line(bulk, line, lineptr) { + if (!gpiod_line_is_requested_values(line)) { + errno = EPERM; + return false; + } + } + + return true; +} + static bool line_bulk_all_free(struct gpiod_line_bulk *bulk) { struct gpiod_line *line, **lineptr; @@ -471,6 +501,27 @@ static bool line_bulk_all_free(struct gpiod_line_bulk *bulk) return true; } +static bool line_request_direction_is_valid(int direction) +{ + if ((direction == GPIOD_LINE_REQUEST_DIRECTION_AS_IS) || + (direction == GPIOD_LINE_REQUEST_DIRECTION_INPUT) || + (direction == GPIOD_LINE_REQUEST_DIRECTION_OUTPUT)) + return true; + + errno = EINVAL; + return false; +} + +static __u32 line_request_direction_to_gpio_handleflag(int direction) +{ + if (direction == GPIOD_LINE_REQUEST_DIRECTION_INPUT) + return GPIOHANDLE_REQUEST_INPUT; + if (direction == GPIOD_LINE_REQUEST_DIRECTION_OUTPUT) + return GPIOHANDLE_REQUEST_OUTPUT; + + return 0; +} + static __u32 line_request_flag_to_gpio_handleflag(int flags) { int hflags = 0; @@ -495,7 +546,7 @@ static int line_request_values(struct gpiod_line_bulk *bulk, const struct gpiod_line_request_config *config, const int *default_vals) { - struct gpiod_line *line, **lineptr; + struct gpiod_line *line; struct line_fd_handle *line_fd; struct gpiohandle_request req; unsigned int i; @@ -524,7 +575,6 @@ static int line_request_values(struct gpiod_line_bulk *bulk, else if (config->request_type == GPIOD_LINE_REQUEST_DIRECTION_OUTPUT) req.flags |= GPIOHANDLE_REQUEST_OUTPUT; - gpiod_line_bulk_foreach_line_off(bulk, line, i) { req.lineoffsets[i] = gpiod_line_offset(line); if (config->request_type == @@ -548,8 +598,12 @@ static int line_request_values(struct gpiod_line_bulk *bulk, if (!line_fd) return -1; - gpiod_line_bulk_foreach_line(bulk, line, lineptr) { + gpiod_line_bulk_foreach_line_off(bulk, line, i) { line->state = LINE_REQUESTED_VALUES; + line->req_flags = config->flags; + if (config->request_type == + GPIOD_LINE_REQUEST_DIRECTION_OUTPUT) + line->output_value = req.default_values[i]; line_set_fd(line, line_fd); line_maybe_update(line); } @@ -590,6 +644,7 @@ static int line_request_event_single(struct gpiod_line *line, return -1; line->state = LINE_REQUESTED_EVENTS; + line->req_flags = config->flags; line_set_fd(line, line_fd); line_maybe_update(line); @@ -688,6 +743,11 @@ bool gpiod_line_is_requested(struct gpiod_line *line) line->state == LINE_REQUESTED_EVENTS); } +bool gpiod_line_is_requested_values(struct gpiod_line *line) +{ + return (line->state == LINE_REQUESTED_VALUES); +} + bool gpiod_line_is_free(struct gpiod_line *line) { return line->state == LINE_FREE; @@ -768,9 +828,131 @@ int gpiod_line_set_value_bulk(struct gpiod_line_bulk *bulk, const int *values) if (rv < 0) return -1; + gpiod_line_bulk_foreach_line_off(bulk, line, i) + line->output_value = data.values[i]; + + return 0; +} + +int gpiod_line_set_config(struct gpiod_line *line, int direction, + int flags, int value) +{ + struct gpiod_line_bulk bulk; + + gpiod_line_bulk_init(&bulk); + gpiod_line_bulk_add(&bulk, line); + + return gpiod_line_set_config_bulk(&bulk, direction, flags, &value); +} + +int gpiod_line_set_config_bulk(struct gpiod_line_bulk *bulk, + int direction, int flags, + const int *values) +{ + struct gpiohandle_config hcfg; + struct gpiod_line *line; + unsigned int i; + int rv, fd; + + if (!line_bulk_same_chip(bulk) || + !line_bulk_all_requested_values(bulk)) + return -1; + + if (!line_request_direction_is_valid(direction)) + return -1; + + memset(&hcfg, 0, sizeof(hcfg)); + + hcfg.flags = line_request_flag_to_gpio_handleflag(flags); + hcfg.flags |= line_request_direction_to_gpio_handleflag(direction); + if (direction == GPIOD_LINE_REQUEST_DIRECTION_OUTPUT && values) { + for (i = 0; i < gpiod_line_bulk_num_lines(bulk); i++) + hcfg.default_values[i] = (uint8_t)!!values[i]; + } + + line = gpiod_line_bulk_get_line(bulk, 0); + fd = line_get_fd(line); + + rv = ioctl(fd, GPIOHANDLE_SET_CONFIG_IOCTL, &hcfg); + if (rv < 0) + return -1; + + gpiod_line_bulk_foreach_line_off(bulk, line, i) { + line->req_flags = flags; + if (direction == GPIOD_LINE_REQUEST_DIRECTION_OUTPUT) + line->output_value = hcfg.default_values[i]; + line_maybe_update(line); + } return 0; } +int gpiod_line_set_flags(struct gpiod_line *line, int flags) +{ + struct gpiod_line_bulk bulk; + + gpiod_line_bulk_init(&bulk); + gpiod_line_bulk_add(&bulk, line); + + return gpiod_line_set_flags_bulk(&bulk, flags); +} + +int gpiod_line_set_flags_bulk(struct gpiod_line_bulk *bulk, int flags) +{ + struct gpiod_line *line; + int values[GPIOD_LINE_BULK_MAX_LINES]; + unsigned int i; + int direction; + + line = gpiod_line_bulk_get_line(bulk, 0); + if (line->needs_update) { + errno = EPERM; + return -1; + } + if (line->direction == GPIOD_LINE_DIRECTION_OUTPUT) { + gpiod_line_bulk_foreach_line_off(bulk, line, i) { + values[i] = line->output_value; + } + direction = GPIOD_LINE_REQUEST_DIRECTION_OUTPUT; + } else + direction = GPIOD_LINE_REQUEST_DIRECTION_INPUT; + + return gpiod_line_set_config_bulk(bulk, direction, + flags, values); +} + +int gpiod_line_set_direction_input(struct gpiod_line *line) +{ + return gpiod_line_set_config(line, GPIOD_LINE_REQUEST_DIRECTION_INPUT, + line->req_flags, 0); +} + +int gpiod_line_set_direction_input_bulk(struct gpiod_line_bulk *bulk) +{ + struct gpiod_line *line; + + line = gpiod_line_bulk_get_line(bulk, 0); + return gpiod_line_set_config_bulk(bulk, + GPIOD_LINE_REQUEST_DIRECTION_INPUT, + line->req_flags, NULL); +} + +int gpiod_line_set_direction_output(struct gpiod_line *line, int value) +{ + return gpiod_line_set_config(line, GPIOD_LINE_REQUEST_DIRECTION_OUTPUT, + line->req_flags, value); +} + +int gpiod_line_set_direction_output_bulk(struct gpiod_line_bulk *bulk, + const int *values) +{ + struct gpiod_line *line; + + line = gpiod_line_bulk_get_line(bulk, 0); + return gpiod_line_set_config_bulk(bulk, + GPIOD_LINE_REQUEST_DIRECTION_OUTPUT, + line->req_flags, values); +} + int gpiod_line_event_wait(struct gpiod_line *line, const struct timespec *timeout) { From patchwork Thu Nov 21 00:35:50 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kent Gibson X-Patchwork-Id: 1198608 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (no SPF record) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=linux-gpio-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="Y6ljofZ/"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 47JLGj0jDYz9sPL for ; Thu, 21 Nov 2019 11:36:45 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726573AbfKUAgk (ORCPT ); Wed, 20 Nov 2019 19:36:40 -0500 Received: from mail-pj1-f68.google.com ([209.85.216.68]:43416 "EHLO mail-pj1-f68.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726705AbfKUAgk (ORCPT ); Wed, 20 Nov 2019 19:36:40 -0500 Received: by mail-pj1-f68.google.com with SMTP id a10so604036pju.10 for ; Wed, 20 Nov 2019 16:36:38 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=2pAz6eMeJITc9sbIWBHWbXUDXwONZa8aHcBLP/Zicyk=; b=Y6ljofZ/JC54aKWq7o7JMuwO170LMBeIeSmztcf5+A3rZi4bKWJApP1iK0+wMmXVVc 2sAdSob12AUUwxuHsMYSpx6PTpJYX0jZc46J2u7vILmv1txBDJaiOqiUAlwX/cmGV8um IUoGwygZWMhCOfuU1e7Bn3qYA56R9daQOEXXunzcBo6I2Hh1KkZ85ELFDZMenajIwORy TyIUUc4rBJ5njCujG0uBVqwo6SBWUrzctJtiMBStGJHjStOPu6+V/TNpRFal385WmoFQ 10O7ZDxjw1zaZb31aooaa9HYFkzdOe8/Gi/SE04Qrp5UAVcI04IzltK/0rMTWMrrHk5+ FRyQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=2pAz6eMeJITc9sbIWBHWbXUDXwONZa8aHcBLP/Zicyk=; b=XZB/kIc4vczUh4SG4oM9wChFzL27pDZGMEs8+PtDdSiI7AuuAdK0VrV3i4lsavwxsj IGkbBs3NY++sTVA9IG9LG1aRILqAkCaSZpE0S1WqJ36wo88WsFeJbPywn2mUG1uUsu3X 8CADgKUP40BtvAw/RcYNp+CXN8G4OUaYMiKCf0n+iPD9ZpZKZ4lnlUDABE9BgQ1pVVXr mczoa53YjhbWzOfiwujnD0vlK2PHkkupitNbra/bxHuJaptGF7brMeWwKnRADJb2Amo1 Eg6i400K3pkUMBWIqggWREUOLxtZ3v+eW3NqLGmy8cLBqHNvifEsyfcmFcuui0BAJTbR 8IyA== X-Gm-Message-State: APjAAAXOxXz2wqnN7lhwpgns6P2majw7KKfFm0Xmzira1UWxn5MfKY+n 0uFL6EBAv/BSzWGPefv+V4P1ycuDh20= X-Google-Smtp-Source: APXvYqw0dicO135Ri9WPUvh1m8aZuz4U/rKdwFgALq0Mw+pp/sdPflfiL+INubiZft26yZucTuouqw== X-Received: by 2002:a17:90a:b385:: with SMTP id e5mr7734388pjr.115.1574296597904; Wed, 20 Nov 2019 16:36:37 -0800 (PST) Received: from sol.lan (220-235-109-115.dyn.iinet.net.au. [220.235.109.115]) by smtp.gmail.com with ESMTPSA id s1sm420756pgk.9.2019.11.20.16.36.35 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 20 Nov 2019 16:36:37 -0800 (PST) From: Kent Gibson To: linux-gpio@vger.kernel.org, bgolaszewski@baylibre.com Cc: Kent Gibson Subject: [libgpiod] [PATCH v2 08/14] tests: add tests for SET_CONFIG Date: Thu, 21 Nov 2019 08:35:50 +0800 Message-Id: <20191121003556.9020-9-warthog618@gmail.com> X-Mailer: git-send-email 2.24.0 In-Reply-To: <20191121003556.9020-1-warthog618@gmail.com> References: <20191121003556.9020-1-warthog618@gmail.com> MIME-Version: 1.0 Sender: linux-gpio-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-gpio@vger.kernel.org Extend test coverage over the SET_CONFIG functions. Signed-off-by: Kent Gibson --- tests/tests-line.c | 370 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 369 insertions(+), 1 deletion(-) diff --git a/tests/tests-line.c b/tests/tests-line.c index b453dad..251904c 100644 --- a/tests/tests-line.c +++ b/tests/tests-line.c @@ -267,6 +267,7 @@ GPIOD_TEST_CASE(set_value, 0, { 8 }) ret = gpiod_line_request_output(line, GPIOD_TEST_CONSUMER, 0); g_assert_cmpint(ret, ==, 0); + g_assert_cmpint(gpiod_test_chip_get_value(0, 2), ==, 0); ret = gpiod_line_set_value(line, 1); g_assert_cmpint(ret, ==, 0); @@ -329,6 +330,351 @@ GPIOD_TEST_CASE(set_value_bulk, 0, { 8 }) g_assert_cmpint(gpiod_test_chip_get_value(0, 2), ==, 0); } +GPIOD_TEST_CASE(set_config_bulk_null_values, 0, { 8 }) +{ + g_autoptr(gpiod_chip_struct) chip = NULL; + struct gpiod_line_bulk bulk = GPIOD_LINE_BULK_INITIALIZER; + struct gpiod_line *line0, *line1, *line2; + gint ret; + + chip = gpiod_chip_open(gpiod_test_chip_path(0)); + g_assert_nonnull(chip); + gpiod_test_return_if_failed(); + + line0 = gpiod_chip_get_line(chip, 0); + line1 = gpiod_chip_get_line(chip, 1); + line2 = gpiod_chip_get_line(chip, 2); + + g_assert_nonnull(line0); + g_assert_nonnull(line1); + g_assert_nonnull(line2); + gpiod_test_return_if_failed(); + + gpiod_line_bulk_add(&bulk, line0); + gpiod_line_bulk_add(&bulk, line1); + gpiod_line_bulk_add(&bulk, line2); + + ret = gpiod_line_request_bulk_output(&bulk, GPIOD_TEST_CONSUMER, 0); + g_assert_cmpint(ret, ==, 0); + g_assert_cmpint(gpiod_line_active_state(line0), ==, + GPIOD_LINE_ACTIVE_STATE_HIGH); + g_assert_cmpint(gpiod_line_active_state(line1), ==, + GPIOD_LINE_ACTIVE_STATE_HIGH); + g_assert_cmpint(gpiod_line_active_state(line2), ==, + GPIOD_LINE_ACTIVE_STATE_HIGH); + 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); + + ret = gpiod_line_set_config_bulk(&bulk, + GPIOD_LINE_REQUEST_DIRECTION_OUTPUT, + GPIOD_LINE_REQUEST_FLAG_ACTIVE_LOW, NULL); + g_assert_cmpint(ret, ==, 0); + g_assert_cmpint(gpiod_line_active_state(line0), ==, + GPIOD_LINE_ACTIVE_STATE_LOW); + g_assert_cmpint(gpiod_line_active_state(line1), ==, + GPIOD_LINE_ACTIVE_STATE_LOW); + g_assert_cmpint(gpiod_line_active_state(line2), ==, + GPIOD_LINE_ACTIVE_STATE_LOW); + 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); + + ret = gpiod_line_set_config_bulk(&bulk, + GPIOD_LINE_REQUEST_DIRECTION_OUTPUT, 0, NULL); + g_assert_cmpint(ret, ==, 0); + g_assert_cmpint(gpiod_line_active_state(line0), ==, + GPIOD_LINE_ACTIVE_STATE_HIGH); + g_assert_cmpint(gpiod_line_active_state(line1), ==, + GPIOD_LINE_ACTIVE_STATE_HIGH); + g_assert_cmpint(gpiod_line_active_state(line2), ==, + GPIOD_LINE_ACTIVE_STATE_HIGH); + 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); +} + +GPIOD_TEST_CASE(set_flags_active_state, 0, { 8 }) +{ + g_autoptr(gpiod_chip_struct) chip = NULL; + struct gpiod_line *line; + gint ret; + + chip = gpiod_chip_open(gpiod_test_chip_path(0)); + g_assert_nonnull(chip); + gpiod_test_return_if_failed(); + + line = gpiod_chip_get_line(chip, 2); + g_assert_nonnull(line); + gpiod_test_return_if_failed(); + + ret = gpiod_line_request_output(line, GPIOD_TEST_CONSUMER, 1); + g_assert_cmpint(ret, ==, 0); + g_assert_cmpint(gpiod_line_active_state(line), ==, + GPIOD_LINE_ACTIVE_STATE_HIGH); + 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_cmpint(gpiod_line_active_state(line), ==, + GPIOD_LINE_ACTIVE_STATE_LOW); + 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_cmpint(gpiod_line_active_state(line), ==, + GPIOD_LINE_ACTIVE_STATE_HIGH); + g_assert_cmpint(gpiod_test_chip_get_value(0, 2), ==, 1); +} + +GPIOD_TEST_CASE(set_flags_bias, 0, { 8 }) +{ + g_autoptr(gpiod_chip_struct) chip = NULL; + struct gpiod_line *line; + gint ret; + + chip = gpiod_chip_open(gpiod_test_chip_path(0)); + g_assert_nonnull(chip); + gpiod_test_return_if_failed(); + + line = gpiod_chip_get_line(chip, 2); + g_assert_nonnull(line); + gpiod_test_return_if_failed(); + + ret = gpiod_line_request_input(line, GPIOD_TEST_CONSUMER); + g_assert_cmpint(ret, ==, 0); + g_assert_cmpint(gpiod_line_bias(line), ==, GPIOD_LINE_BIAS_AS_IS); + + ret = gpiod_line_set_flags(line, + GPIOD_LINE_REQUEST_FLAG_BIAS_DISABLE); + g_assert_cmpint(ret, ==, 0); + g_assert_cmpint(gpiod_line_bias(line), ==, GPIOD_LINE_BIAS_DISABLE); + + 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); + + 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); +} + +GPIOD_TEST_CASE(set_flags_drive, 0, { 8 }) +{ + g_autoptr(gpiod_chip_struct) chip = NULL; + struct gpiod_line *line; + gint ret; + + chip = gpiod_chip_open(gpiod_test_chip_path(0)); + g_assert_nonnull(chip); + gpiod_test_return_if_failed(); + + line = gpiod_chip_get_line(chip, 2); + g_assert_nonnull(line); + gpiod_test_return_if_failed(); + + ret = gpiod_line_request_output(line, GPIOD_TEST_CONSUMER, 0); + g_assert_cmpint(ret, ==, 0); + g_assert_cmpint(gpiod_line_is_open_drain(line), ==, false); + g_assert_cmpint(gpiod_line_is_open_source(line), ==, false); + + ret = gpiod_line_set_flags(line, + GPIOD_LINE_REQUEST_FLAG_OPEN_DRAIN); + g_assert_cmpint(ret, ==, 0); + g_assert_cmpint(gpiod_line_is_open_drain(line), ==, true); + g_assert_cmpint(gpiod_line_is_open_source(line), ==, false); + + ret = gpiod_line_set_flags(line, + GPIOD_LINE_REQUEST_FLAG_OPEN_SOURCE); + g_assert_cmpint(ret, ==, 0); + g_assert_cmpint(gpiod_line_is_open_drain(line), ==, false); + g_assert_cmpint(gpiod_line_is_open_source(line), ==, true); +} + +GPIOD_TEST_CASE(set_direction, 0, { 8 }) +{ + g_autoptr(gpiod_chip_struct) chip = NULL; + struct gpiod_line *line; + gint ret; + + chip = gpiod_chip_open(gpiod_test_chip_path(0)); + g_assert_nonnull(chip); + gpiod_test_return_if_failed(); + + line = gpiod_chip_get_line(chip, 2); + g_assert_nonnull(line); + gpiod_test_return_if_failed(); + + ret = gpiod_line_request_output(line, GPIOD_TEST_CONSUMER, 0); + g_assert_cmpint(ret, ==, 0); + g_assert_cmpint(gpiod_line_direction(line), ==, + GPIOD_LINE_DIRECTION_OUTPUT); + g_assert_cmpint(gpiod_test_chip_get_value(0, 2), ==, 0); + + ret = gpiod_line_set_direction_input(line); + g_assert_cmpint(ret, ==, 0); + g_assert_cmpint(gpiod_line_direction(line), ==, + GPIOD_LINE_DIRECTION_INPUT); + + ret = gpiod_line_set_direction_output(line, 1); + g_assert_cmpint(ret, ==, 0); + g_assert_cmpint(gpiod_line_direction(line), ==, + 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_chip_struct) chip = NULL; + struct gpiod_line_bulk bulk = GPIOD_LINE_BULK_INITIALIZER; + struct gpiod_line *line0, *line1, *line2; + int values[3]; + gint ret; + + chip = gpiod_chip_open(gpiod_test_chip_path(0)); + g_assert_nonnull(chip); + gpiod_test_return_if_failed(); + + line0 = gpiod_chip_get_line(chip, 0); + line1 = gpiod_chip_get_line(chip, 1); + line2 = gpiod_chip_get_line(chip, 2); + + g_assert_nonnull(line0); + g_assert_nonnull(line1); + g_assert_nonnull(line2); + gpiod_test_return_if_failed(); + + gpiod_line_bulk_add(&bulk, line0); + gpiod_line_bulk_add(&bulk, line1); + gpiod_line_bulk_add(&bulk, line2); + + values[0] = 0; + values[1] = 1; + values[2] = 2; + + ret = gpiod_line_request_bulk_output(&bulk, + GPIOD_TEST_CONSUMER, values); + g_assert_cmpint(ret, ==, 0); + g_assert_cmpint(gpiod_line_direction(line0), ==, + GPIOD_LINE_DIRECTION_OUTPUT); + g_assert_cmpint(gpiod_line_direction(line1), ==, + GPIOD_LINE_DIRECTION_OUTPUT); + g_assert_cmpint(gpiod_line_direction(line2), ==, + 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), ==, + GPIOD_LINE_DIRECTION_INPUT); + g_assert_cmpint(gpiod_line_direction(line1), ==, + GPIOD_LINE_DIRECTION_INPUT); + g_assert_cmpint(gpiod_line_direction(line2), ==, + GPIOD_LINE_DIRECTION_INPUT); + + values[0] = 2; + values[1] = 1; + values[2] = 0; + + ret = gpiod_line_set_direction_output_bulk(&bulk, values); + g_assert_cmpint(ret, ==, 0); + g_assert_cmpint(gpiod_line_direction(line0), ==, + GPIOD_LINE_DIRECTION_OUTPUT); + g_assert_cmpint(gpiod_line_direction(line1), ==, + GPIOD_LINE_DIRECTION_OUTPUT); + g_assert_cmpint(gpiod_line_direction(line2), ==, + 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), ==, + GPIOD_LINE_DIRECTION_OUTPUT); + g_assert_cmpint(gpiod_line_direction(line1), ==, + GPIOD_LINE_DIRECTION_OUTPUT); + g_assert_cmpint(gpiod_line_direction(line2), ==, + 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); +} + +GPIOD_TEST_CASE(output_value_caching, 0, { 8 }) +{ + g_autoptr(gpiod_chip_struct) chip = NULL; + struct gpiod_line *line; + struct gpiod_line_bulk bulk; + gint ret; + + chip = gpiod_chip_open(gpiod_test_chip_path(0)); + g_assert_nonnull(chip); + gpiod_test_return_if_failed(); + + line = gpiod_chip_get_line(chip, 2); + g_assert_nonnull(line); + gpiod_test_return_if_failed(); + + /* check cached by request... */ + ret = gpiod_line_request_output(line, GPIOD_TEST_CONSUMER, 1); + g_assert_cmpint(ret, ==, 0); + g_assert_cmpint(gpiod_test_chip_get_value(0, 2), ==, 1); + + /* ...by checking cached value applied by set_flags */ + ret = gpiod_line_set_flags(line, 0); + g_assert_cmpint(ret, ==, 0); + g_assert_cmpint(gpiod_test_chip_get_value(0, 2), ==, 1); + + /* check cached by set_value */ + ret = gpiod_line_set_value(line, 0); + g_assert_cmpint(ret, ==, 0); + 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_cmpint(gpiod_test_chip_get_value(0, 2), ==, 0); + + ret = gpiod_line_set_value(line, 1); + g_assert_cmpint(ret, ==, 0); + g_assert_cmpint(gpiod_test_chip_get_value(0, 2), ==, 1); + + ret = gpiod_line_set_flags(line, 0); + g_assert_cmpint(ret, ==, 0); + g_assert_cmpint(gpiod_test_chip_get_value(0, 2), ==, 1); + + /* check cached by set_config */ + ret = gpiod_line_set_config(line, GPIOD_LINE_REQUEST_DIRECTION_OUTPUT, + 0, 0); + g_assert_cmpint(ret, ==, 0); + 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_cmpint(gpiod_test_chip_get_value(0, 2), ==, 0); + + /* check cached by set_value_bulk default */ + ret = gpiod_line_set_value(line, 1); + g_assert_cmpint(ret, ==, 0); + g_assert_cmpint(gpiod_test_chip_get_value(0, 2), ==, 1); + + gpiod_line_bulk_init(&bulk); + gpiod_line_bulk_add(&bulk, line); + ret = gpiod_line_set_value_bulk(&bulk, NULL); + g_assert_cmpint(ret, ==, 0); + 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_cmpint(gpiod_test_chip_get_value(0, 2), ==, 0); +} + GPIOD_TEST_CASE(get_value_different_chips, 0, { 8, 8 }) { g_autoptr(gpiod_chip_struct) chipA = NULL; @@ -443,10 +789,11 @@ GPIOD_TEST_CASE(direction, 0, { 8 }) g_assert_nonnull(line); gpiod_test_return_if_failed(); - ret = gpiod_line_request_output(line, GPIOD_TEST_CONSUMER, 0); + ret = gpiod_line_request_output(line, GPIOD_TEST_CONSUMER, 1); g_assert_cmpint(ret, ==, 0); g_assert_cmpint(gpiod_line_direction(line), ==, GPIOD_LINE_DIRECTION_OUTPUT); + g_assert_cmpint(gpiod_test_chip_get_value(0, 5), ==, 1); gpiod_line_release(line); @@ -484,6 +831,27 @@ GPIOD_TEST_CASE(active_state, 0, { 8 }) g_assert_cmpint(gpiod_line_direction(line), ==, GPIOD_LINE_DIRECTION_INPUT); + + gpiod_line_release(line); + + ret = gpiod_line_request_output_flags(line, GPIOD_TEST_CONSUMER, + GPIOD_LINE_REQUEST_FLAG_ACTIVE_LOW, 0); + g_assert_cmpint(ret, ==, 0); + + g_assert_cmpint(gpiod_line_direction(line), ==, + GPIOD_LINE_DIRECTION_OUTPUT); + g_assert_cmpint(gpiod_test_chip_get_value(0, 5), ==, 1); + + gpiod_line_release(line); + + ret = gpiod_line_request_output_flags(line, + GPIOD_TEST_CONSUMER, 0, 0); + g_assert_cmpint(ret, ==, 0); + + g_assert_cmpint(gpiod_line_direction(line), ==, + GPIOD_LINE_DIRECTION_OUTPUT); + g_assert_cmpint(gpiod_test_chip_get_value(0, 5), ==, 0); + } GPIOD_TEST_CASE(misc_flags, 0, { 8 }) From patchwork Thu Nov 21 00:35:51 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kent Gibson X-Patchwork-Id: 1198609 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (no SPF record) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=linux-gpio-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="YMUUfvQU"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 47JLGj3bdFz9sPn for ; Thu, 21 Nov 2019 11:36:45 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726714AbfKUAgl (ORCPT ); Wed, 20 Nov 2019 19:36:41 -0500 Received: from mail-pf1-f181.google.com ([209.85.210.181]:35197 "EHLO mail-pf1-f181.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726705AbfKUAgl (ORCPT ); Wed, 20 Nov 2019 19:36:41 -0500 Received: by mail-pf1-f181.google.com with SMTP id q13so693466pff.2 for ; Wed, 20 Nov 2019 16:36:41 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=E7W94xtx0uI56sv+Ld6LRQS5pGxu5wsVfKel0MWTCao=; b=YMUUfvQUJ4wrLW18NL5NMpRQTYJgV/hej0Rme7bNzOMPoBf1kKBnlw2GP7IDpDOajT IhkSlXOBkcot+Ai3xjts5Gh5z9nOzmBiVlfy/8JIqhFnox7C4/avZ0jrqARYAtVtTx+3 8M68hD5WPI74VqLJyxzpEZ7a7XyfE2Rc+eVY3zXmC20wDOZwP9uYI1zuAmHeemDXWlRA Z4Fb7i+8Nu+k7wBM0GSkbh/tWGuxNvEEuxm9QUaJSe5Oxr2dpUn7Dvuoomym1ShaEDbk pmO0Xq7I0KFbpIIRkaRndn8Gh54X06qE4cbV3pkW8KItP0VN3ZDvmJ4KyKGa9uA+HL9y CRXQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=E7W94xtx0uI56sv+Ld6LRQS5pGxu5wsVfKel0MWTCao=; b=XQqC83ndIu6bA1UvuRR2c/B2sWxvpo4rQjRgZPffX+2FE946C/mdpUNw4SvZM/d8cx Q0UbRvhBLet+lsmNBRmgjUIyRgZ7OEqJm6Q5SCwdrA3UWexB5qrdRUrNspDBoaCXQEUD GsltDvC/I83JjWYc8wZZFiRphK3nj3xUpPQFUzPT4JywA779FVQBGZJ5ndSj6RyN77/z lJgoa8EHXa91fsiYeLjGMRliLNESKkl/1C0KtUoPQr2CvXn917YpTYZnhwReM29oSdXN UaQkxzcwPi3pF3dxFVyS7xRxGOTO5YrPCIhpqkeSl4IHnbXZZNePVlHP3gfCw0j+yam8 FU8g== X-Gm-Message-State: APjAAAW7y6Mw0jjypUrs8rTEQ2b53E1T6F89dkTu6QZLDkStzi1mYlt/ 7TInG5/Meh5F5CPxtwyCoyYgL0snaJA= X-Google-Smtp-Source: APXvYqz5mz5YRBKLWVQC0dZauVXcNo77Ys0GZAjtrmGPuFuzoNlcd0O1uIMarh6YN18xdcnjiV2S3g== X-Received: by 2002:a63:755c:: with SMTP id f28mr621040pgn.341.1574296600309; Wed, 20 Nov 2019 16:36:40 -0800 (PST) Received: from sol.lan (220-235-109-115.dyn.iinet.net.au. [220.235.109.115]) by smtp.gmail.com with ESMTPSA id s1sm420756pgk.9.2019.11.20.16.36.38 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 20 Nov 2019 16:36:39 -0800 (PST) From: Kent Gibson To: linux-gpio@vger.kernel.org, bgolaszewski@baylibre.com Cc: Kent Gibson Subject: [libgpiod] [PATCH v2 09/14] bindings: cxx: add support for SET_CONFIG Date: Thu, 21 Nov 2019 08:35:51 +0800 Message-Id: <20191121003556.9020-10-warthog618@gmail.com> X-Mailer: git-send-email 2.24.0 In-Reply-To: <20191121003556.9020-1-warthog618@gmail.com> References: <20191121003556.9020-1-warthog618@gmail.com> MIME-Version: 1.0 Sender: linux-gpio-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-gpio@vger.kernel.org Add methods to support setting line configuration. Signed-off-by: Kent Gibson --- bindings/cxx/gpiod.hpp | 55 +++++++++++++++++++++++++ bindings/cxx/line.cpp | 37 +++++++++++++++++ bindings/cxx/line_bulk.cpp | 83 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 175 insertions(+) diff --git a/bindings/cxx/gpiod.hpp b/bindings/cxx/gpiod.hpp index 2b1a6ab..dcae431 100644 --- a/bindings/cxx/gpiod.hpp +++ b/bindings/cxx/gpiod.hpp @@ -381,6 +381,32 @@ public: */ GPIOD_API void set_value(int val) const; + /** + * @brief Set configuration of this line. + * @param direction New direction. + * @param flags Replacement flags. + * @param value New value (0 or 1) - only matters for OUTPUT direction. + */ + GPIOD_API void set_config(int direction, ::std::bitset<32> flags, + int value = 0) const; + + /** + * @brief Set configuration flags of this line. + * @param flags Replacement flags. + */ + GPIOD_API void set_flags(::std::bitset<32> flags) const; + + /** + * @brief Change the direction this line to input. + */ + GPIOD_API void set_direction_input() const; + + /** + * @brief Change the direction this lines to output. + * @param value New value (0 or 1). + */ + GPIOD_API void set_direction_output(int value = 0) const; + /** * @brief Wait for an event on this line. * @param timeout Time to wait before returning if no event occurred. @@ -648,6 +674,35 @@ public: */ GPIOD_API void set_values(const ::std::vector& values) const; + /** + * @brief Set configuration of all lines held by this object. + * @param direction New direction. + * @param flags Replacement flags. + * @param values Vector of values to set. Must be the same size as the + * number of lines held by this line_bulk. + * Only relevant for output direction requests. + */ + GPIOD_API void set_config(int direction, ::std::bitset<32> flags, + const ::std::vector values = std::vector()) const; + + /** + * @brief Set configuration flags of all lines held by this object. + * @param flags Replacement flags. + */ + GPIOD_API void set_flags(::std::bitset<32> flags) const; + + /** + * @brief Change the direction all lines held by this object to input. + */ + GPIOD_API void set_direction_input() const; + + /** + * @brief Change the direction all lines held by this object to output. + * @param values Vector of values to set. Must be the same size as the + * number of lines held by this line_bulk. + */ + GPIOD_API void set_direction_output(const ::std::vector& values) const; + /** * @brief Poll the set of lines for line events. * @param timeout Number of nanoseconds to wait before returning an diff --git a/bindings/cxx/line.cpp b/bindings/cxx/line.cpp index dd6bb6a..a688b5d 100644 --- a/bindings/cxx/line.cpp +++ b/bindings/cxx/line.cpp @@ -158,6 +158,43 @@ void line::set_value(int val) const bulk.set_values({ val }); } +void line::set_config(int direction, ::std::bitset<32> flags, + int value) const +{ + this->throw_if_null(); + + line_bulk bulk({ *this }); + + bulk.set_config(direction, flags, { value }); +} + +void line::set_flags(::std::bitset<32> flags) const +{ + this->throw_if_null(); + + line_bulk bulk({ *this }); + + bulk.set_flags(flags); +} + +void line::set_direction_input() const +{ + this->throw_if_null(); + + line_bulk bulk({ *this }); + + bulk.set_direction_input(); +} + +void line::set_direction_output(int value) const +{ + this->throw_if_null(); + + line_bulk bulk({ *this }); + + bulk.set_direction_output({ value }); +} + bool line::event_wait(const ::std::chrono::nanoseconds& timeout) const { this->throw_if_null(); diff --git a/bindings/cxx/line_bulk.cpp b/bindings/cxx/line_bulk.cpp index 5f1cac4..b8f5eb7 100644 --- a/bindings/cxx/line_bulk.cpp +++ b/bindings/cxx/line_bulk.cpp @@ -176,6 +176,89 @@ void line_bulk::set_values(const ::std::vector& values) const "error setting GPIO line values"); } +void line_bulk::set_config(int direction, ::std::bitset<32> flags, + const ::std::vector values) const +{ + this->throw_if_empty(); + + if (!values.empty() && this->_m_bulk.size() != values.size()) + throw ::std::invalid_argument("the number of default values must correspond with the number of lines"); + + ::gpiod_line_bulk bulk; + int rv, gflags; + + gflags = 0; + + for (auto& it: reqflag_mapping) { + if ((it.first & flags).to_ulong()) + gflags |= it.second; + } + + this->to_line_bulk(::std::addressof(bulk)); + + rv = ::gpiod_line_set_config_bulk(::std::addressof(bulk), direction, + gflags, values.data()); + if (rv) + throw ::std::system_error(errno, ::std::system_category(), + "error setting GPIO line config"); +} + +void line_bulk::set_flags(::std::bitset<32> flags) const +{ + this->throw_if_empty(); + + ::gpiod_line_bulk bulk; + int rv, gflags; + + this->to_line_bulk(::std::addressof(bulk)); + + gflags = 0; + + for (auto& it: reqflag_mapping) { + if ((it.first & flags).to_ulong()) + gflags |= it.second; + } + + rv = ::gpiod_line_set_flags_bulk(::std::addressof(bulk), gflags); + if (rv) + throw ::std::system_error(errno, ::std::system_category(), + "error setting GPIO line flags"); +} + +void line_bulk::set_direction_input() const +{ + this->throw_if_empty(); + + ::gpiod_line_bulk bulk; + int rv; + + this->to_line_bulk(::std::addressof(bulk)); + + rv = ::gpiod_line_set_direction_input_bulk(::std::addressof(bulk)); + if (rv) + throw ::std::system_error(errno, ::std::system_category(), + "error setting GPIO line direction to input"); +} + +void line_bulk::set_direction_output(const ::std::vector& values) const +{ + this->throw_if_empty(); + + if (values.size() != this->_m_bulk.size()) + throw ::std::invalid_argument("the size of values array must correspond with the number of lines"); + + ::gpiod_line_bulk bulk; + int rv; + + this->to_line_bulk(::std::addressof(bulk)); + + rv = ::gpiod_line_set_direction_output_bulk(::std::addressof(bulk), + values.data()); + if (rv) + throw ::std::system_error(errno, ::std::system_category(), + "error setting GPIO line direction to output"); +} + line_bulk line_bulk::event_wait(const ::std::chrono::nanoseconds& timeout) const { this->throw_if_empty(); From patchwork Thu Nov 21 00:35:52 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kent Gibson X-Patchwork-Id: 1198610 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (no SPF record) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=linux-gpio-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="T1fSXl37"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 47JLGk0CyZz9sNx for ; Thu, 21 Nov 2019 11:36:46 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726716AbfKUAgo (ORCPT ); Wed, 20 Nov 2019 19:36:44 -0500 Received: from mail-pg1-f193.google.com ([209.85.215.193]:40021 "EHLO mail-pg1-f193.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726705AbfKUAgo (ORCPT ); Wed, 20 Nov 2019 19:36:44 -0500 Received: by mail-pg1-f193.google.com with SMTP id e17so620221pgd.7 for ; Wed, 20 Nov 2019 16:36:43 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=kSnyeo1X2JTqBLbCys03JvqhhOkGJtDeDc2nw0RC24E=; b=T1fSXl37+P0Y/wGQ6AWlzCxuKuzA5JCDTxfIUYgYFqZyVfyvjZ3m0JQBMauLOE9Y8e lNSUeNdSkwQSD6NB0ZIlD9fa4EPqNoCu9zzczytXfyoqFoO3GECtJ4Spq+m3JlxqrKjD aHof69R6o+ADVNA3zK5G8XY9Ej3FkgWnTlJ6nTztlX6AKFc1EPYmyUDhCE/nbFrNf4lc epND6W28g5+RFs2k2elE1L76I7Qvsn4VcdbdTtd9BtInHk3YMinhC4GhEG7UAOA3rQx/ 56dM90EDLZbA6GHbk4QKv0M4aFXXSsTeSU88dfcBreMnT3iNQmKSO/btYu4b7dHtbkjM reyw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=kSnyeo1X2JTqBLbCys03JvqhhOkGJtDeDc2nw0RC24E=; b=FibCTOUqbpzFDOROVGImaYaM2yYvvqN18cKaT4GhwEkdYxpEM+gvsnDB6XkDOte87X EGlCTLHNcmbQzVp1DT7opR5OwvS6zv6AIRbQGzpA/eDarqx+3gpbR3u/bkhXRlOXZ3Xv Rx1EvhhGWL8b3UXArVYrahEw56OTsBuSX9kuISI31Xh6clwSGz4/MO1Rh6OCo0bFK/Kk n7QRhYYKLUcX4PmRMOhJAmVaLfP0wSfM/eEKZBgoOvqhFoFG6i4p9ewHK30ocC2txd6D QeUrGPxZ47SQAxTvtPmDZo3MW4kAOFJ5WQItN2f3iuJIl5ic1N2Oi864NAKp2g1AMrbh +VTw== X-Gm-Message-State: APjAAAV8ofKec8iUndw6RYqhjMyXvruZcKilcquSkpBAj9XaFeIO3ycR 6/qo5nuN27m02sdlda84bdLAqF9smv8= X-Google-Smtp-Source: APXvYqzFa0X9E0xquCgXddGwxmhxe9i+0FDN6LpNuzyusBVnPZqjxPXV5wnTUPFkxw3Elcanv8YsUQ== X-Received: by 2002:aa7:8610:: with SMTP id p16mr7373040pfn.185.1574296603066; Wed, 20 Nov 2019 16:36:43 -0800 (PST) Received: from sol.lan (220-235-109-115.dyn.iinet.net.au. [220.235.109.115]) by smtp.gmail.com with ESMTPSA id s1sm420756pgk.9.2019.11.20.16.36.40 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 20 Nov 2019 16:36:42 -0800 (PST) From: Kent Gibson To: linux-gpio@vger.kernel.org, bgolaszewski@baylibre.com Cc: Kent Gibson Subject: [libgpiod] [PATCH v2 10/14] bindings: cxx: tests: add tests for SET_CONFIG methods Date: Thu, 21 Nov 2019 08:35:52 +0800 Message-Id: <20191121003556.9020-11-warthog618@gmail.com> X-Mailer: git-send-email 2.24.0 In-Reply-To: <20191121003556.9020-1-warthog618@gmail.com> References: <20191121003556.9020-1-warthog618@gmail.com> MIME-Version: 1.0 Sender: linux-gpio-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-gpio@vger.kernel.org Extend test coverage over set_config, set_flags, set_direction_input, and set_direction_output methods. Signed-off-by: Kent Gibson --- bindings/cxx/tests/tests-line.cpp | 128 ++++++++++++++++++++++++++++++ 1 file changed, 128 insertions(+) diff --git a/bindings/cxx/tests/tests-line.cpp b/bindings/cxx/tests/tests-line.cpp index 9a0b488..5353093 100644 --- a/bindings/cxx/tests/tests-line.cpp +++ b/bindings/cxx/tests/tests-line.cpp @@ -324,6 +324,134 @@ TEST_CASE("Line values can be set and read", "[line]") } } +TEST_CASE("Line can be reconfigured", "[line]") +{ + mockup::probe_guard mockup_chips({ 8 }); + ::gpiod::chip chip(mockup::instance().chip_name(0)); + ::gpiod::line_request config; + + config.consumer = consumer.c_str(); + + SECTION("set config (single line, active-state)") + { + auto line = chip.get_line(3); + config.request_type = ::gpiod::line_request::DIRECTION_INPUT; + config.flags = 0; + line.request(config); + REQUIRE(line.direction() == ::gpiod::line::DIRECTION_INPUT); + REQUIRE(line.active_state() == ::gpiod::line::ACTIVE_HIGH); + + line.set_config(::gpiod::line_request::DIRECTION_OUTPUT, + ::gpiod::line_request::FLAG_ACTIVE_LOW,1); + REQUIRE(line.direction() == ::gpiod::line::DIRECTION_OUTPUT); + REQUIRE(line.active_state() == ::gpiod::line::ACTIVE_LOW); + REQUIRE(mockup::instance().chip_get_value(0, 3) == 0); + line.set_value(0); + REQUIRE(mockup::instance().chip_get_value(0, 3) == 1); + + line.set_config(::gpiod::line_request::DIRECTION_OUTPUT, 0); + REQUIRE(line.direction() == ::gpiod::line::DIRECTION_OUTPUT); + REQUIRE(line.active_state() == ::gpiod::line::ACTIVE_HIGH); + REQUIRE(mockup::instance().chip_get_value(0, 3) == 0); + line.set_value(1); + REQUIRE(mockup::instance().chip_get_value(0, 3) == 1); + } + + SECTION("set flags (single line, active-state)") + { + auto line = chip.get_line(3); + config.request_type = ::gpiod::line_request::DIRECTION_OUTPUT; + config.flags = 0; + line.request(config,1); + REQUIRE(mockup::instance().chip_get_value(0, 3) == 1); + + line.set_flags(::gpiod::line_request::FLAG_ACTIVE_LOW); + REQUIRE(line.direction() == ::gpiod::line::DIRECTION_OUTPUT); + REQUIRE(line.active_state() == ::gpiod::line::ACTIVE_LOW); + REQUIRE(mockup::instance().chip_get_value(0, 3) == 0); + + line.set_flags(0); + REQUIRE(line.direction() == ::gpiod::line::DIRECTION_OUTPUT); + REQUIRE(line.active_state() == ::gpiod::line::ACTIVE_HIGH); + REQUIRE(mockup::instance().chip_get_value(0, 3) == 1); + } + + SECTION("set flags (single line, drive)") + { + auto line = chip.get_line(3); + config.request_type = ::gpiod::line_request::DIRECTION_OUTPUT; + config.flags = 0; + line.request(config); + REQUIRE(line.direction() == ::gpiod::line::DIRECTION_OUTPUT); + REQUIRE_FALSE(line.is_open_drain()); + REQUIRE_FALSE(line.is_open_source()); + + line.set_flags(::gpiod::line_request::FLAG_OPEN_DRAIN); + REQUIRE(line.direction() == ::gpiod::line::DIRECTION_OUTPUT); + REQUIRE(line.is_open_drain()); + REQUIRE_FALSE(line.is_open_source()); + + line.set_flags(::gpiod::line_request::FLAG_OPEN_SOURCE); + REQUIRE(line.direction() == ::gpiod::line::DIRECTION_OUTPUT); + REQUIRE_FALSE(line.is_open_drain()); + REQUIRE(line.is_open_source()); + + line.set_flags(0); + REQUIRE(line.direction() == ::gpiod::line::DIRECTION_OUTPUT); + REQUIRE_FALSE(line.is_open_drain()); + REQUIRE_FALSE(line.is_open_source()); + } + + SECTION("set flags (single line, bias)") + { + auto line = chip.get_line(3); + config.request_type = ::gpiod::line_request::DIRECTION_OUTPUT; + config.flags = 0; + line.request(config); + REQUIRE(line.direction() == ::gpiod::line::DIRECTION_OUTPUT); + REQUIRE_FALSE(line.is_open_drain()); + REQUIRE_FALSE(line.is_open_source()); + + line.set_flags(::gpiod::line_request::FLAG_OPEN_DRAIN); + REQUIRE(line.direction() == ::gpiod::line::DIRECTION_OUTPUT); + REQUIRE(line.is_open_drain()); + REQUIRE_FALSE(line.is_open_source()); + + line.set_flags(::gpiod::line_request::FLAG_OPEN_SOURCE); + REQUIRE(line.direction() == ::gpiod::line::DIRECTION_OUTPUT); + REQUIRE_FALSE(line.is_open_drain()); + REQUIRE(line.is_open_source()); + + line.set_flags(0); + REQUIRE(line.direction() == ::gpiod::line::DIRECTION_OUTPUT); + REQUIRE_FALSE(line.is_open_drain()); + REQUIRE_FALSE(line.is_open_source()); + } + + SECTION("set direction input (single line)") + { + auto line = chip.get_line(3); + config.request_type = ::gpiod::line_request::DIRECTION_OUTPUT; + config.flags = 0; + line.request(config); + REQUIRE(line.direction() == ::gpiod::line::DIRECTION_OUTPUT); + line.set_direction_input(); + REQUIRE(line.direction() == ::gpiod::line::DIRECTION_INPUT); + } + + SECTION("set direction output (single line)") + { + auto line = chip.get_line(3); + config.request_type = ::gpiod::line_request::DIRECTION_INPUT; + config.flags = 0; + line.request(config); + REQUIRE(line.direction() == ::gpiod::line::DIRECTION_INPUT); + line.set_direction_output(1); + REQUIRE(line.direction() == ::gpiod::line::DIRECTION_OUTPUT); + REQUIRE(mockup::instance().chip_get_value(0, 3) == 1); + } +} + TEST_CASE("Exported line can be released", "[line]") { mockup::probe_guard mockup_chips({ 8 }); From patchwork Thu Nov 21 00:35:53 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kent Gibson X-Patchwork-Id: 1198611 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (no SPF record) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=linux-gpio-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="ELelWmt5"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 47JLGm0SvMz9sNx for ; Thu, 21 Nov 2019 11:36:48 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726721AbfKUAgr (ORCPT ); Wed, 20 Nov 2019 19:36:47 -0500 Received: from mail-pj1-f67.google.com ([209.85.216.67]:36398 "EHLO mail-pj1-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726705AbfKUAgq (ORCPT ); Wed, 20 Nov 2019 19:36:46 -0500 Received: by mail-pj1-f67.google.com with SMTP id cq11so618275pjb.3 for ; Wed, 20 Nov 2019 16:36:46 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=W5LtyT4KdX2MuencblfVi1EJZKnnkO9ezbdxW8d2jPs=; b=ELelWmt5zAvWTBydfVF4+R28noXUXJx2Wppbxzgb66Aw9v7q+4ndOuhH+BWfuOaarg mpjw+UQLBSGMb3IDLKUQVGL+Ae4UttKQbdqKdZ148yaABxi8vJFcOQij0CMqAe8gsJNO USpmSRmNE6hbiSElo8BSHFHG0ZMRmV7E6cEZM0oHibXLl0OXowd2EE//tBA6zmVAnQMB YRbNR4vOkETRN7x5IzN1iovGoaRDWaOaqwL7yP1S3ytB6A3VylYbGbLZkrgpgmml9XMO Q7xU9qVfa/O9fO6rh4b5xMipnF1UvI6YS9e1adh1U1s/M9IH/psm9r89gPZpG6TCm8kv pokw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=W5LtyT4KdX2MuencblfVi1EJZKnnkO9ezbdxW8d2jPs=; b=h78ZotWHb9N8c8KU3Gz10kzedjiR9gEtoeOXmn2JoPsl7dv7GSFI3KYEQedms2hvg8 6hTX/8ssAXghAz90rkfsQYSd2LvlN0jGrTzQckv4BtelbnLWp83RBAvI0u2UwJ30Whsm uaNxDqifymIRdhPVsIXm29USZZDRRlOcPdd8BITNvN0ZliuxFhBgU6+DopgTovJl5Y7B LGCqz3stLFb2PWrJ/QwRApHFL4wkxx/u2nXfdG8x63zw4w5Dy2BHHAIx690FA7kDukM6 pRiNegOoLZPs/7rCVJ+O/EwEoOUrlfwLOfKNi3cx/AsS1TELXVi4hUe2CtYbOVVQ4w34 Hgnw== X-Gm-Message-State: APjAAAXKT8a13tmMURpKdL7z71V9tFB/NKPkKLsAXj4Y1h0ar5lSb083 EMXnHemyaBZAuU5TzMroC8lG1oXJtBM= X-Google-Smtp-Source: APXvYqyYgrpRKZtFwfDPMV+ojpdN24WP973K6hyMLdQrh9hC/+O/qywC79cvsvSv9vANKZ2aPAtddw== X-Received: by 2002:a17:90a:8818:: with SMTP id s24mr7779160pjn.31.1574296605729; Wed, 20 Nov 2019 16:36:45 -0800 (PST) Received: from sol.lan (220-235-109-115.dyn.iinet.net.au. [220.235.109.115]) by smtp.gmail.com with ESMTPSA id s1sm420756pgk.9.2019.11.20.16.36.43 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 20 Nov 2019 16:36:45 -0800 (PST) From: Kent Gibson To: linux-gpio@vger.kernel.org, bgolaszewski@baylibre.com Cc: Kent Gibson Subject: [libgpiod] [PATCH v2 11/14] bindings: python: add support for SET_CONFIG Date: Thu, 21 Nov 2019 08:35:53 +0800 Message-Id: <20191121003556.9020-12-warthog618@gmail.com> X-Mailer: git-send-email 2.24.0 In-Reply-To: <20191121003556.9020-1-warthog618@gmail.com> References: <20191121003556.9020-1-warthog618@gmail.com> MIME-Version: 1.0 Sender: linux-gpio-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-gpio@vger.kernel.org Add methods to support setting line configuration. Signed-off-by: Kent Gibson --- bindings/python/gpiodmodule.c | 381 +++++++++++++++++++++++++++++++++- 1 file changed, 379 insertions(+), 2 deletions(-) diff --git a/bindings/python/gpiodmodule.c b/bindings/python/gpiodmodule.c index 4723771..4f5e117 100644 --- a/bindings/python/gpiodmodule.c +++ b/bindings/python/gpiodmodule.c @@ -585,14 +585,149 @@ static PyObject *gpiod_Line_set_value(gpiod_LineObject *self, PyObject *args) if (!bulk_obj) return NULL; - vals = Py_BuildValue("((O))", val); + vals = Py_BuildValue("(O)", val); if (!vals) { Py_DECREF(bulk_obj); return NULL; } ret = PyObject_CallMethod((PyObject *)bulk_obj, - "set_values", "O", vals); + "set_values", "(O)", vals); + Py_DECREF(bulk_obj); + Py_DECREF(vals); + + return ret; +} + +PyDoc_STRVAR(gpiod_Line_set_config_doc, +"set_config(direction,flags,value) -> None\n" +"\n" +"Set the configuration of this GPIO line.\n" +"\n" +" direction\n" +" New direction (integer)\n" +" flags\n" +" New flags (integer)\n" +" value\n" +" New value (integer)"); + +static PyObject *gpiod_Line_set_config(gpiod_LineObject *self, PyObject *args) +{ + gpiod_LineBulkObject *bulk_obj; + PyObject *dirn, *flags, *val, *vals, *ret; + int rv; + + val = NULL; + rv = PyArg_ParseTuple(args, "OO|O", &dirn, &flags, &val); + if (!rv) + return NULL; + + bulk_obj = gpiod_LineToLineBulk(self); + if (!bulk_obj) + return NULL; + + if (val) { + vals = Py_BuildValue("(O)", val); + if (!vals) { + Py_DECREF(bulk_obj); + return NULL; + } + ret = PyObject_CallMethod((PyObject *)bulk_obj, + "set_config", "OO(O)", dirn, flags, vals); + Py_DECREF(vals); + } else + ret = PyObject_CallMethod((PyObject *)bulk_obj, + "set_config", "OO", dirn, flags); + + Py_DECREF(bulk_obj); + + return ret; +} + +PyDoc_STRVAR(gpiod_Line_set_flags_doc, +"set_flags(flags) -> None\n" +"\n" +"Set the flags of this GPIO line.\n" +"\n" +" flags\n" +" New flags (integer)"); + +static PyObject *gpiod_Line_set_flags(gpiod_LineObject *self, PyObject *args) +{ + gpiod_LineBulkObject *bulk_obj; + PyObject *ret; + + bulk_obj = gpiod_LineToLineBulk(self); + if (!bulk_obj) + return NULL; + + ret = PyObject_CallMethod((PyObject *)bulk_obj, + "set_flags", "O", args); + Py_DECREF(bulk_obj); + + return ret; +} + +PyDoc_STRVAR(gpiod_Line_set_direction_input_doc, +"set_direction_input() -> None\n" +"\n" +"Set the direction of this GPIO line to input.\n"); + +static PyObject *gpiod_Line_set_direction_input(gpiod_LineObject *self, + PyObject *Py_UNUSED(ignored)) +{ + gpiod_LineBulkObject *bulk_obj; + PyObject *ret; + + bulk_obj = gpiod_LineToLineBulk(self); + if (!bulk_obj) + return NULL; + + ret = PyObject_CallMethod((PyObject *)bulk_obj, + "set_direction_input", ""); + Py_DECREF(bulk_obj); + + return ret; +} + +PyDoc_STRVAR(gpiod_Line_set_direction_output_doc, +"set_direction_output(value) -> None\n" +"\n" +"Set the direction of this GPIO line to output.\n" +"\n" +" value\n" +" New value (integer)"); + +static PyObject *gpiod_Line_set_direction_output(gpiod_LineObject *self, + PyObject *args) +{ + gpiod_LineBulkObject *bulk_obj; + PyObject *val, *vals, *ret; + int rv; + const char *fmt; + + val = NULL; + rv = PyArg_ParseTuple(args, "|O", &val); + if (!rv) + return NULL; + + if (val) { + fmt = "(O)"; + vals = Py_BuildValue(fmt, val); + } else { + vals = Py_BuildValue("()"); + fmt = "O"; /* pass empty args to bulk */ + } + if (!vals) + return NULL; + + bulk_obj = gpiod_LineToLineBulk(self); + if (!bulk_obj) + return NULL; + + ret = PyObject_CallMethod((PyObject *)bulk_obj, + "set_direction_output", fmt, vals); + Py_DECREF(bulk_obj); Py_DECREF(vals); @@ -838,6 +973,30 @@ static PyMethodDef gpiod_Line_methods[] = { .ml_flags = METH_VARARGS, .ml_doc = gpiod_Line_set_value_doc, }, + { + .ml_name = "set_config", + .ml_meth = (PyCFunction)gpiod_Line_set_config, + .ml_flags = METH_VARARGS, + .ml_doc = gpiod_Line_set_config_doc, + }, + { + .ml_name = "set_flags", + .ml_meth = (PyCFunction)gpiod_Line_set_flags, + .ml_flags = METH_VARARGS, + .ml_doc = gpiod_Line_set_flags_doc, + }, + { + .ml_name = "set_direction_input", + .ml_meth = (PyCFunction)gpiod_Line_set_direction_input, + .ml_flags = METH_NOARGS, + .ml_doc = gpiod_Line_set_direction_input_doc, + }, + { + .ml_name = "set_direction_output", + .ml_meth = (PyCFunction)gpiod_Line_set_direction_output, + .ml_flags = METH_VARARGS, + .ml_doc = gpiod_Line_set_direction_output_doc, + }, { .ml_name = "release", .ml_meth = (PyCFunction)gpiod_Line_release, @@ -1283,6 +1442,200 @@ static PyObject *gpiod_LineBulk_set_values(gpiod_LineBulkObject *self, Py_RETURN_NONE; } +static int convert_values(PyObject *src, int *dst, Py_ssize_t n) +{ + int val; + Py_ssize_t num_vals, i; + PyObject *iter, *next; + + num_vals = PyObject_Size(src); + if (num_vals != n) { + PyErr_SetString(PyExc_TypeError, + "Number of values must correspond to the number of lines"); + return -1; + } + iter = PyObject_GetIter(src); + if (!iter) + return -1; + for (i = 0;; i++) { + next = PyIter_Next(iter); + if (!next) { + Py_DECREF(iter); + break; + } + val = PyLong_AsLong(next); + Py_DECREF(next); + if (PyErr_Occurred()) { + Py_DECREF(iter); + return -1; + } + dst[i] = (int)val; + } + return 0; +} + +PyDoc_STRVAR(gpiod_LineBulk_set_config_doc, +"set_config(direction,flags,values) -> None\n" +"\n" +"Set the configuration of all the lines held by this LineBulk object.\n" +"\n" +" direction\n" +" New direction (integer)\n" +" flags\n" +" New flags (integer)\n" +" values\n" +" List of values (integers) to set when direction is output.\n" +"\n" +"The number of values in the list passed as argument must be the same as\n" +"the number of lines held by this gpiod.LineBulk object. The index of each\n" +"value corresponds to the index of each line in the object.\n"); + +static PyObject *gpiod_LineBulk_set_config(gpiod_LineBulkObject *self, + PyObject *args) +{ + int rv, vals[GPIOD_LINE_BULK_MAX_LINES]; + PyObject *val_list; + struct gpiod_line_bulk bulk; + const int *valp; + int dirn, flags; + + if (gpiod_LineBulkOwnerIsClosed(self)) + return NULL; + + gpiod_LineBulkObjToCLineBulk(self, &bulk); + + val_list = NULL; + rv = PyArg_ParseTuple(args, "ii|(O)", &dirn, &flags, &val_list); + if (!rv) + return NULL; + + if (val_list == NULL) + valp = NULL; + else { + memset(vals, 0, sizeof(vals)); + rv = convert_values(val_list, vals, self->num_lines); + if (rv) + return NULL; + valp = vals; + } + + Py_BEGIN_ALLOW_THREADS; + rv = gpiod_line_set_config_bulk(&bulk, dirn, flags, valp); + Py_END_ALLOW_THREADS; + if (rv) + return PyErr_SetFromErrno(PyExc_OSError); + + Py_RETURN_NONE; +} + +PyDoc_STRVAR(gpiod_LineBulk_set_flags_doc, +"set_flags(flags) -> None\n" +"\n" +"Set the flags of all the lines held by this LineBulk object.\n" +"\n" +" flags\n" +" New flags (integer)"); + +static PyObject *gpiod_LineBulk_set_flags(gpiod_LineBulkObject *self, + PyObject *args) +{ + int rv; + struct gpiod_line_bulk bulk; + int flags; + + if (gpiod_LineBulkOwnerIsClosed(self)) + return NULL; + + gpiod_LineBulkObjToCLineBulk(self, &bulk); + + rv = PyArg_ParseTuple(args, "i", &flags); + if (!rv) + return NULL; + + Py_BEGIN_ALLOW_THREADS; + rv = gpiod_line_set_flags_bulk(&bulk, flags); + Py_END_ALLOW_THREADS; + if (rv) + return PyErr_SetFromErrno(PyExc_OSError); + + Py_RETURN_NONE; +} + +PyDoc_STRVAR(gpiod_LineBulk_set_direction_input_doc, +"set_direction_input() -> None\n" +"\n" +"Set the direction of all the lines held by this LineBulk object to input.\n"); + +static PyObject *gpiod_LineBulk_set_direction_input(gpiod_LineBulkObject *self, + PyObject *Py_UNUSED(ignored)) +{ + struct gpiod_line_bulk bulk; + int rv; + + if (gpiod_LineBulkOwnerIsClosed(self)) + return NULL; + + gpiod_LineBulkObjToCLineBulk(self, &bulk); + + Py_BEGIN_ALLOW_THREADS; + rv = gpiod_line_set_direction_input_bulk(&bulk); + Py_END_ALLOW_THREADS; + if (rv) + return PyErr_SetFromErrno(PyExc_OSError); + + Py_RETURN_NONE; +} + +PyDoc_STRVAR(gpiod_LineBulk_set_direction_output_doc, +"set_direction_output(value) -> None\n" +"\n" +"Set the direction of all the lines held by this LineBulk object to output.\n" +"\n" +" values\n" +" List of values (integers) to set when direction is output.\n" +"\n" +"The number of values in the list passed as argument must be the same as\n" +"the number of lines held by this gpiod.LineBulk object. The index of each\n" +"value corresponds to the index of each line in the object.\n"); + +static PyObject *gpiod_LineBulk_set_direction_output( + gpiod_LineBulkObject *self, + PyObject *args) +{ + int rv, vals[GPIOD_LINE_BULK_MAX_LINES]; + PyObject *val_list; + struct gpiod_line_bulk bulk; + const int *valp; + + if (gpiod_LineBulkOwnerIsClosed(self)) + return NULL; + + gpiod_LineBulkObjToCLineBulk(self, &bulk); + + val_list = NULL; + rv = PyArg_ParseTuple(args, "|O", &val_list); + if (!rv) + return NULL; + + if (val_list == NULL) + valp = NULL; + else { + memset(vals, 0, sizeof(vals)); + rv = convert_values(val_list, vals, self->num_lines); + if (rv) + return NULL; + valp = vals; + } + + Py_BEGIN_ALLOW_THREADS; + rv = gpiod_line_set_direction_output_bulk(&bulk, valp); + Py_END_ALLOW_THREADS; + if (rv) + return PyErr_SetFromErrno(PyExc_OSError); + + Py_RETURN_NONE; +} + PyDoc_STRVAR(gpiod_LineBulk_release_doc, "release() -> None\n" "\n" @@ -1431,6 +1784,30 @@ static PyMethodDef gpiod_LineBulk_methods[] = { .ml_doc = gpiod_LineBulk_set_values_doc, .ml_flags = METH_VARARGS, }, + { + .ml_name = "set_config", + .ml_meth = (PyCFunction)gpiod_LineBulk_set_config, + .ml_flags = METH_VARARGS, + .ml_doc = gpiod_LineBulk_set_config_doc, + }, + { + .ml_name = "set_flags", + .ml_meth = (PyCFunction)gpiod_LineBulk_set_flags, + .ml_flags = METH_VARARGS, + .ml_doc = gpiod_LineBulk_set_flags_doc, + }, + { + .ml_name = "set_direction_input", + .ml_meth = (PyCFunction)gpiod_LineBulk_set_direction_input, + .ml_flags = METH_NOARGS, + .ml_doc = gpiod_LineBulk_set_direction_input_doc, + }, + { + .ml_name = "set_direction_output", + .ml_meth = (PyCFunction)gpiod_LineBulk_set_direction_output, + .ml_flags = METH_VARARGS, + .ml_doc = gpiod_LineBulk_set_direction_output_doc, + }, { .ml_name = "release", .ml_meth = (PyCFunction)gpiod_LineBulk_release, From patchwork Thu Nov 21 00:35:54 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kent Gibson X-Patchwork-Id: 1198612 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (no SPF record) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=linux-gpio-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="sGQ8bDi4"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 47JLGq0hKVz9sNx for ; Thu, 21 Nov 2019 11:36:51 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726722AbfKUAgu (ORCPT ); Wed, 20 Nov 2019 19:36:50 -0500 Received: from mail-pl1-f196.google.com ([209.85.214.196]:34000 "EHLO mail-pl1-f196.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726705AbfKUAgu (ORCPT ); Wed, 20 Nov 2019 19:36:50 -0500 Received: by mail-pl1-f196.google.com with SMTP id h13so681988plr.1 for ; Wed, 20 Nov 2019 16:36:49 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=xZlbgmFt9O1mvX0rp/4awL3PbMSgZdBNoRECTogus8M=; b=sGQ8bDi4v7hWYSLrijBiPEXWqxwacOGNMt86Kq1boFEVfUnCj2b5SLTJqWdLkO7s5i Ed7JGNpwFcr/QeQfASdxh8rzItdhAiyehJZ2J3Ko2MCZlqwV3McEDk50eQHoLMpPx5/t r34hLLmgBtuoDXAEAY5GhXZBDWy5+zbjAkDFHiUpvZkrViDOAb/I1K+TFDpWbb63Uuk1 4m+No1BX0iO+MMrwl/AAaEW6H4e+ZKLlHud2S86icDqTZft8BhELjvi5GCUb8oMRJXKl bFojfE3puUUgtu+NQu43zT12dgaqrVSlFSRZRxMtTkxra0fTqGgrUrW9+5xo9I/4Wu0G gKsQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=xZlbgmFt9O1mvX0rp/4awL3PbMSgZdBNoRECTogus8M=; b=r2o/Wt8rL0x7mV9+PLNb8shnBFZhACZPuoVfmyRL34gME4NflmaXgWaEz2KNXZT0Q8 Ef9l/6qeLoDwYrZ8yXGBbZ2tLewHWiDiylvRnkZPj77ITQ8U3TtogkPJ+v9DmR5G2+VT u2NVR1UFaCkUjZvQRwjZHBuum17jaQzC8Dn/lKsL2z4mj1u/oLtK0m8cJxlRkpvCtfd6 hdEn8FDzYLiLORdTtFkfiWDm/B47sFO0gwHtgucu3rAzAs8jOxNjIjL5celyvTau6A+z W0Ox8ib60reJoJDEX1xylU/I4OrT482kE5KT1hj4dG4kAW1R8nOcUHV46Msuy924vHGG SwOw== X-Gm-Message-State: APjAAAUR8M775NQ29kCsuPO9sm6BatYlRci4idMvbmVKU2uaq6X14hgK EwJnSuAM9PGg5LzW1CstrUsD/LxIvNE= X-Google-Smtp-Source: APXvYqyX/KyUSW77mO9VRWQbhcTyfn6p47Bah6Xv8HOEahxkEy7EepaeUxYDvUhEvBfjhaJYBqMr6Q== X-Received: by 2002:a17:90a:dd42:: with SMTP id u2mr7648167pjv.57.1574296608446; Wed, 20 Nov 2019 16:36:48 -0800 (PST) Received: from sol.lan (220-235-109-115.dyn.iinet.net.au. [220.235.109.115]) by smtp.gmail.com with ESMTPSA id s1sm420756pgk.9.2019.11.20.16.36.46 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 20 Nov 2019 16:36:48 -0800 (PST) From: Kent Gibson To: linux-gpio@vger.kernel.org, bgolaszewski@baylibre.com Cc: Kent Gibson Subject: [libgpiod] [PATCH v2 12/14] bindings: python: tests: add tests for SET_CONFIG methods Date: Thu, 21 Nov 2019 08:35:54 +0800 Message-Id: <20191121003556.9020-13-warthog618@gmail.com> X-Mailer: git-send-email 2.24.0 In-Reply-To: <20191121003556.9020-1-warthog618@gmail.com> References: <20191121003556.9020-1-warthog618@gmail.com> MIME-Version: 1.0 Sender: linux-gpio-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-gpio@vger.kernel.org Extend test coverage over set_config, set_flags, set_direction_input, and set_direction_output methods. Signed-off-by: Kent Gibson --- bindings/python/tests/gpiod_py_test.py | 163 +++++++++++++++++++++++++ 1 file changed, 163 insertions(+) diff --git a/bindings/python/tests/gpiod_py_test.py b/bindings/python/tests/gpiod_py_test.py index 9330b43..704d916 100755 --- a/bindings/python/tests/gpiod_py_test.py +++ b/bindings/python/tests/gpiod_py_test.py @@ -493,6 +493,169 @@ class LineValues(MockupTestCase): line.set_value(0) self.assertEqual(mockup.chip_get_value(0, 3), 1) +class LineConfig(MockupTestCase): + + chip_sizes = ( 8, ) + + def test_set_config_direction(self): + with gpiod.Chip(mockup.chip_name(0)) as chip: + line = chip.get_line(3) + line.request(consumer=default_consumer, + type=gpiod.LINE_REQ_DIR_IN) + self.assertEqual(line.direction(), gpiod.Line.DIRECTION_INPUT) + line.set_config(gpiod.LINE_REQ_DIR_IN, 0, 0) + self.assertEqual(line.direction(), gpiod.Line.DIRECTION_INPUT) + line.set_config(gpiod.LINE_REQ_DIR_OUT,0,0) + self.assertEqual(line.direction(), gpiod.Line.DIRECTION_OUTPUT) + + def test_set_config_flags(self): + with gpiod.Chip(mockup.chip_name(0)) as chip: + line = chip.get_line(3) + line.request(consumer=default_consumer, + type=gpiod.LINE_REQ_DIR_OUT) + line.set_config(gpiod.LINE_REQ_DIR_OUT, + gpiod.LINE_REQ_FLAG_ACTIVE_LOW, 0) + self.assertEqual(mockup.chip_get_value(0, 3), 1) + line.set_config(gpiod.LINE_REQ_DIR_OUT, 0, 0) + self.assertEqual(mockup.chip_get_value(0, 3), 0) + + def test_set_config_output_value(self): + with gpiod.Chip(mockup.chip_name(0)) as chip: + line = chip.get_line(3) + line.request(consumer=default_consumer, + type=gpiod.LINE_REQ_DIR_IN) + line.set_config(gpiod.LINE_REQ_DIR_OUT,0,1) + self.assertEqual(mockup.chip_get_value(0, 3), 1) + line.set_config(gpiod.LINE_REQ_DIR_OUT,0,0) + self.assertEqual(mockup.chip_get_value(0, 3), 0) + + def test_set_config_output_no_value(self): + with gpiod.Chip(mockup.chip_name(0)) as chip: + line = chip.get_line(3) + line.request(consumer=default_consumer, + type=gpiod.LINE_REQ_DIR_OUT, + default_val=1) + self.assertEqual(mockup.chip_get_value(0, 3), 1) + line.set_config(gpiod.LINE_REQ_DIR_OUT,0) + self.assertEqual(mockup.chip_get_value(0, 3), 0) + + def test_set_config_bulk_output_no_values(self): + with gpiod.Chip(mockup.chip_name(0)) as chip: + lines = chip.get_lines(( 0, 3, 4, 6 )) + lines.request(consumer=default_consumer, + type=gpiod.LINE_REQ_DIR_OUT, + default_vals=(1,1,1,1)) + self.assertEqual(mockup.chip_get_value(0, 0), 1) + self.assertEqual(mockup.chip_get_value(0, 3), 1) + self.assertEqual(mockup.chip_get_value(0, 4), 1) + self.assertEqual(mockup.chip_get_value(0, 6), 1) + lines.set_config(gpiod.LINE_REQ_DIR_OUT,0) + self.assertEqual(mockup.chip_get_value(0, 0), 0) + self.assertEqual(mockup.chip_get_value(0, 3), 0) + self.assertEqual(mockup.chip_get_value(0, 4), 0) + self.assertEqual(mockup.chip_get_value(0, 6), 0) + +class LineFlags(MockupTestCase): + + chip_sizes = ( 8, ) + + def test_set_flags(self): + with gpiod.Chip(mockup.chip_name(0)) as chip: + line = chip.get_line(3) + line.request(consumer=default_consumer, + type=gpiod.LINE_REQ_DIR_OUT, + default_val=1) + self.assertEqual(mockup.chip_get_value(0, 3), 1) + line.set_flags(gpiod.LINE_REQ_FLAG_ACTIVE_LOW) + self.assertEqual(mockup.chip_get_value(0, 3), 0) + line.set_flags(0) + self.assertEqual(mockup.chip_get_value(0, 3), 1) + + def test_set_flags_bulk(self): + with gpiod.Chip(mockup.chip_name(0)) as chip: + lines = chip.get_lines(( 0, 3, 4, 6 )) + lines.request(consumer=default_consumer, + type=gpiod.LINE_REQ_DIR_OUT, + default_vals=(1,1,1,1)) + self.assertEqual(mockup.chip_get_value(0, 0), 1) + self.assertEqual(mockup.chip_get_value(0, 3), 1) + self.assertEqual(mockup.chip_get_value(0, 4), 1) + self.assertEqual(mockup.chip_get_value(0, 6), 1) + lines.set_flags(gpiod.LINE_REQ_FLAG_ACTIVE_LOW) + self.assertEqual(mockup.chip_get_value(0, 0), 0) + self.assertEqual(mockup.chip_get_value(0, 3), 0) + self.assertEqual(mockup.chip_get_value(0, 4), 0) + self.assertEqual(mockup.chip_get_value(0, 6), 0) + lines.set_flags(0) + self.assertEqual(mockup.chip_get_value(0, 0), 1) + self.assertEqual(mockup.chip_get_value(0, 3), 1) + self.assertEqual(mockup.chip_get_value(0, 4), 1) + self.assertEqual(mockup.chip_get_value(0, 6), 1) + +class LineDirection(MockupTestCase): + + chip_sizes = ( 8, ) + + def test_set_direction(self): + with gpiod.Chip(mockup.chip_name(0)) as chip: + line = chip.get_line(3) + line.request(consumer=default_consumer, + type=gpiod.LINE_REQ_DIR_OUT) + self.assertEqual(line.direction(), gpiod.Line.DIRECTION_OUTPUT) + line.set_direction_input() + self.assertEqual(line.direction(), gpiod.Line.DIRECTION_INPUT) + line.set_direction_output(0) + self.assertEqual(line.direction(), gpiod.Line.DIRECTION_OUTPUT) + self.assertEqual(mockup.chip_get_value(0, 3), 0) + line.set_direction_output(1) + self.assertEqual(line.direction(), gpiod.Line.DIRECTION_OUTPUT) + self.assertEqual(mockup.chip_get_value(0, 3), 1) + line.set_direction_output() + self.assertEqual(line.direction(), gpiod.Line.DIRECTION_OUTPUT) + self.assertEqual(mockup.chip_get_value(0, 3), 0) + + def test_set_direction_bulk(self): + with gpiod.Chip(mockup.chip_name(0)) as chip: + lines = chip.get_lines(( 0, 3, 4, 6 )) + lines.request(consumer=default_consumer, + type=gpiod.LINE_REQ_DIR_OUT) + self.assertEqual(lines.to_list()[0].direction(), gpiod.Line.DIRECTION_OUTPUT) + self.assertEqual(lines.to_list()[1].direction(), gpiod.Line.DIRECTION_OUTPUT) + self.assertEqual(lines.to_list()[2].direction(), gpiod.Line.DIRECTION_OUTPUT) + self.assertEqual(lines.to_list()[3].direction(), gpiod.Line.DIRECTION_OUTPUT) + lines.set_direction_input() + self.assertEqual(lines.to_list()[0].direction(), gpiod.Line.DIRECTION_INPUT) + self.assertEqual(lines.to_list()[1].direction(), gpiod.Line.DIRECTION_INPUT) + self.assertEqual(lines.to_list()[2].direction(), gpiod.Line.DIRECTION_INPUT) + self.assertEqual(lines.to_list()[3].direction(), gpiod.Line.DIRECTION_INPUT) + lines.set_direction_output((0,0,1,0)) + self.assertEqual(lines.to_list()[0].direction(), gpiod.Line.DIRECTION_OUTPUT) + self.assertEqual(lines.to_list()[1].direction(), gpiod.Line.DIRECTION_OUTPUT) + self.assertEqual(lines.to_list()[2].direction(), gpiod.Line.DIRECTION_OUTPUT) + self.assertEqual(lines.to_list()[3].direction(), gpiod.Line.DIRECTION_OUTPUT) + self.assertEqual(mockup.chip_get_value(0, 0), 0) + self.assertEqual(mockup.chip_get_value(0, 3), 0) + self.assertEqual(mockup.chip_get_value(0, 4), 1) + self.assertEqual(mockup.chip_get_value(0, 6), 0) + lines.set_direction_output((1,1,1,0)) + self.assertEqual(lines.to_list()[0].direction(), gpiod.Line.DIRECTION_OUTPUT) + self.assertEqual(lines.to_list()[1].direction(), gpiod.Line.DIRECTION_OUTPUT) + self.assertEqual(lines.to_list()[2].direction(), gpiod.Line.DIRECTION_OUTPUT) + self.assertEqual(lines.to_list()[3].direction(), gpiod.Line.DIRECTION_OUTPUT) + self.assertEqual(mockup.chip_get_value(0, 0), 1) + self.assertEqual(mockup.chip_get_value(0, 3), 1) + self.assertEqual(mockup.chip_get_value(0, 4), 1) + self.assertEqual(mockup.chip_get_value(0, 6), 0) + lines.set_direction_output() + self.assertEqual(lines.to_list()[0].direction(), gpiod.Line.DIRECTION_OUTPUT) + self.assertEqual(lines.to_list()[1].direction(), gpiod.Line.DIRECTION_OUTPUT) + self.assertEqual(lines.to_list()[2].direction(), gpiod.Line.DIRECTION_OUTPUT) + self.assertEqual(lines.to_list()[3].direction(), gpiod.Line.DIRECTION_OUTPUT) + self.assertEqual(mockup.chip_get_value(0, 0), 0) + self.assertEqual(mockup.chip_get_value(0, 3), 0) + self.assertEqual(mockup.chip_get_value(0, 4), 0) + self.assertEqual(mockup.chip_get_value(0, 6), 0) + class LineRequestBehavior(MockupTestCase): chip_sizes = ( 8, ) From patchwork Thu Nov 21 00:35:55 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kent Gibson X-Patchwork-Id: 1198613 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (no SPF record) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=linux-gpio-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="ZdIMaGYa"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 47JLGs2Nllz9sNx for ; Thu, 21 Nov 2019 11:36:53 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726725AbfKUAgx (ORCPT ); Wed, 20 Nov 2019 19:36:53 -0500 Received: from mail-pf1-f194.google.com ([209.85.210.194]:42059 "EHLO mail-pf1-f194.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726705AbfKUAgw (ORCPT ); Wed, 20 Nov 2019 19:36:52 -0500 Received: by mail-pf1-f194.google.com with SMTP id s5so674429pfh.9 for ; Wed, 20 Nov 2019 16:36:51 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=KZG+sko3Mu2G5Y3MZdfnnns/llFcRSW4rXp5yXhdtko=; b=ZdIMaGYaJrLPRFNlyTH91rtnBLWfKsVB2rzNDfV2UBN2FAqNeECpceG0HJdAR+2qiF fOBQxrzo1G0YpmB/1ao77tNt2iqMLWY5oN2C75FD9lyCMfDop3a/LZwczQx3cbCcYN7O VEBEyV5CBzPUVhGV9Qc5GWBY1Yu6LVLi6cBf+nLXLDI0hmJvWGi7VmvNT3johRrhpGrX hgugL8M3X1JDfy2g3DlmaWNMoy4mWnhQ1JWLao35gZn9huwPIhnvsRZ/wTJoXKRRt4HR UHjG6jJJwhlth3tHe+kD3UUyfVp44PRsvT3IEgmfKSd8Zuni4LEXWqWUk5/rVkjhe4TB 1XYw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=KZG+sko3Mu2G5Y3MZdfnnns/llFcRSW4rXp5yXhdtko=; b=t6S394ZS3R5MS25p1SrQ6xn300sC0xWvZU2r9T6dsq4fXqd/8pBdHrl81wMR/cV+vK bQJArbInOdABuK8AAcijrAYSwj4hVOA79OLA4DBD/KNHzhAu62MloHaK9Xg5qqJ1F6m0 RGAAfxx7uwvbbJff671oUcqqqsyrdWx8V96/8uTt+X1r91sgHfl8Z9A0P6jIJ16NtPIT 5SEHh8fwMzvk9N6cvDE/lL22gbCsVthjviKcZjVb+6wss6xHzBjpc/PhmZycLZXX3bpu DokPB8LjAsycTcW65MjihgoX1IBADbiY3GenRGe3hSCWOcWzdhkk3401BQLEpQegqk+n UVow== X-Gm-Message-State: APjAAAUKXhsrpvXfRU2s1h5uYRqsaEvNceWd1m7n2oDOWgwwGPRe+DUA nYMBcEezJDSOqosYScQjg7L8M6ENIiI= X-Google-Smtp-Source: APXvYqwRhVRKRLDeblYRPLOF/R457U5wWzN8H1MMahnkR9Xh4Msz+Wb+kbBH6QvLdJBkO20VlMZ/qg== X-Received: by 2002:a62:770d:: with SMTP id s13mr7429381pfc.239.1574296610891; Wed, 20 Nov 2019 16:36:50 -0800 (PST) Received: from sol.lan (220-235-109-115.dyn.iinet.net.au. [220.235.109.115]) by smtp.gmail.com with ESMTPSA id s1sm420756pgk.9.2019.11.20.16.36.48 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 20 Nov 2019 16:36:50 -0800 (PST) From: Kent Gibson To: linux-gpio@vger.kernel.org, bgolaszewski@baylibre.com Cc: Kent Gibson Subject: [libgpiod] [PATCH v2 13/14] tools: add support for bias flags Date: Thu, 21 Nov 2019 08:35:55 +0800 Message-Id: <20191121003556.9020-14-warthog618@gmail.com> X-Mailer: git-send-email 2.24.0 In-Reply-To: <20191121003556.9020-1-warthog618@gmail.com> References: <20191121003556.9020-1-warthog618@gmail.com> MIME-Version: 1.0 Sender: linux-gpio-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-gpio@vger.kernel.org Add support for bias flags to applicable tools - gpioget, gpioset, and gpiomon. Signed-off-by: Kent Gibson --- tools/gpioget.c | 32 +++++++++++++++++++++++++---- tools/gpiomon.c | 36 +++++++++++++++++++++++++++------ tools/gpioset.c | 54 ++++++++++++++++++++++++++++++++++++++++++++----- 3 files changed, 107 insertions(+), 15 deletions(-) diff --git a/tools/gpioget.c b/tools/gpioget.c index 196ebeb..17614cb 100644 --- a/tools/gpioget.c +++ b/tools/gpioget.c @@ -17,10 +17,11 @@ static const struct option longopts[] = { { "help", no_argument, NULL, 'h' }, { "version", no_argument, NULL, 'v' }, { "active-low", no_argument, NULL, 'l' }, + { "bias", required_argument, NULL, 'B' }, { GETOPT_NULL_LONGOPT }, }; -static const char *const shortopts = "+hvl"; +static const char *const shortopts = "+hvlB:"; static void print_help(void) { @@ -32,6 +33,25 @@ static void print_help(void) printf(" -h, --help:\t\tdisplay this message and exit\n"); printf(" -v, --version:\tdisplay the version and exit\n"); printf(" -l, --active-low:\tset the line active state to low\n"); + printf(" -B, --bias=[as-is|disable|pull-down|pull-up] (defaults to 'as-is'):\n"); + printf(" set the line bias\n"); + printf("\n"); + printf("Biases:\n"); + printf(" as-is:\tleave bias unchanged\n"); + printf(" disable:\tdisable bias\n"); + printf(" pull-up:\tenable pull-up\n"); + printf(" pull-down:\tenable pull-down\n"); +} + +static int bias_flags(const char *option) +{ + if (strcmp(option, "pull-down") == 0) + return GPIOD_CTXLESS_FLAG_BIAS_PULL_DOWN; + if (strcmp(option, "pull-up") == 0) + return GPIOD_CTXLESS_FLAG_BIAS_PULL_UP; + if (strcmp(option, "disable") == 0) + return GPIOD_CTXLESS_FLAG_BIAS_DISABLE; + return 0; } int main(int argc, char **argv) @@ -39,6 +59,7 @@ int main(int argc, char **argv) unsigned int *offsets, i, num_lines; int *values, optc, opti, rv; bool active_low = false; + int flags = 0; char *device, *end; for (;;) { @@ -56,6 +77,9 @@ int main(int argc, char **argv) case 'l': active_low = true; break; + case 'B': + flags = bias_flags(optarg); + break; case '?': die("try %s --help", get_progname()); default: @@ -86,9 +110,9 @@ int main(int argc, char **argv) die("invalid GPIO offset: %s", argv[i + 1]); } - rv = gpiod_ctxless_get_value_multiple(device, offsets, values, - num_lines, active_low, - "gpioget"); + rv = gpiod_ctxless_get_value_multiple_ext(device, offsets, values, + num_lines, active_low, + "gpioget", flags); if (rv < 0) die_perror("error reading GPIO values"); diff --git a/tools/gpiomon.c b/tools/gpiomon.c index 9a1843b..687212d 100644 --- a/tools/gpiomon.c +++ b/tools/gpiomon.c @@ -22,6 +22,7 @@ static const struct option longopts[] = { { "help", no_argument, NULL, 'h' }, { "version", no_argument, NULL, 'v' }, { "active-low", no_argument, NULL, 'l' }, + { "bias", required_argument, NULL, 'B' }, { "num-events", required_argument, NULL, 'n' }, { "silent", no_argument, NULL, 's' }, { "rising-edge", no_argument, NULL, 'r' }, @@ -31,7 +32,7 @@ static const struct option longopts[] = { { GETOPT_NULL_LONGOPT }, }; -static const char *const shortopts = "+hvln:srfbF:"; +static const char *const shortopts = "+hvlB:n:srfbF:"; static void print_help(void) { @@ -43,6 +44,8 @@ static void print_help(void) printf(" -h, --help:\t\tdisplay this message and exit\n"); printf(" -v, --version:\tdisplay the version and exit\n"); printf(" -l, --active-low:\tset the line active state to low\n"); + printf(" -B, --bias=[as-is|disable|pull-down|pull-up] (defaults to 'as-is'):\n"); + printf(" set the line bias\n"); printf(" -n, --num-events=NUM:\texit after processing NUM events\n"); printf(" -s, --silent:\t\tdon't print event info\n"); printf(" -r, --rising-edge:\tonly process rising edge events\n"); @@ -50,6 +53,12 @@ static void print_help(void) printf(" -b, --line-buffered:\tset standard output as line buffered\n"); printf(" -F, --format=FMT\tspecify custom output format\n"); printf("\n"); + printf("Biases:\n"); + printf(" as-is:\tleave bias unchanged\n"); + printf(" disable:\tdisable bias\n"); + printf(" pull-up:\tenable pull-up\n"); + printf(" pull-down:\tenable pull-down\n"); + printf("\n"); printf("Format specifiers:\n"); printf(" %%o: GPIO line offset\n"); printf(" %%e: event type (0 - falling edge, 1 rising edge)\n"); @@ -240,10 +249,22 @@ static int make_signalfd(void) return sigfd; } +static int bias_flags(const char *option) +{ + if (strcmp(option, "pull-down") == 0) + return GPIOD_CTXLESS_FLAG_BIAS_PULL_DOWN; + if (strcmp(option, "pull-up") == 0) + return GPIOD_CTXLESS_FLAG_BIAS_PULL_UP; + if (strcmp(option, "disable") == 0) + return GPIOD_CTXLESS_FLAG_BIAS_DISABLE; + return 0; +} + int main(int argc, char **argv) { unsigned int offsets[GPIOD_LINE_BULK_MAX_LINES], num_lines = 0, offset; bool active_low = false, watch_rising = false, watch_falling = false; + int flags = 0; struct timespec timeout = { 10, 0 }; int optc, opti, rv, i, event_type; struct mon_ctx ctx; @@ -266,6 +287,9 @@ int main(int argc, char **argv) case 'l': active_low = true; break; + case 'B': + flags = bias_flags(optarg); + break; case 'n': ctx.events_wanted = strtoul(optarg, &end, 10); if (*end != '\0') @@ -320,11 +344,11 @@ int main(int argc, char **argv) ctx.sigfd = make_signalfd(); - rv = gpiod_ctxless_event_monitor_multiple(argv[0], event_type, - offsets, num_lines, - active_low, "gpiomon", - &timeout, poll_callback, - event_callback, &ctx); + rv = gpiod_ctxless_event_monitor_multiple_ext( + argv[0], event_type, offsets, + num_lines, active_low, "gpiomon", + &timeout, poll_callback, + event_callback, &ctx, flags); if (rv) die_perror("error waiting for events"); diff --git a/tools/gpioset.c b/tools/gpioset.c index d9977a7..b91baea 100644 --- a/tools/gpioset.c +++ b/tools/gpioset.c @@ -23,6 +23,8 @@ static const struct option longopts[] = { { "help", no_argument, NULL, 'h' }, { "version", no_argument, NULL, 'v' }, { "active-low", no_argument, NULL, 'l' }, + { "bias", required_argument, NULL, 'B' }, + { "drive", required_argument, NULL, 'D' }, { "mode", required_argument, NULL, 'm' }, { "sec", required_argument, NULL, 's' }, { "usec", required_argument, NULL, 'u' }, @@ -30,7 +32,7 @@ static const struct option longopts[] = { { GETOPT_NULL_LONGOPT }, }; -static const char *const shortopts = "+hvlm:s:u:b"; +static const char *const shortopts = "+hvlB:D:m:s:u:b"; static void print_help(void) { @@ -42,12 +44,27 @@ static void print_help(void) printf(" -h, --help:\t\tdisplay this message and exit\n"); printf(" -v, --version:\tdisplay the version and exit\n"); printf(" -l, --active-low:\tset the line active state to low\n"); + printf(" -B, --bias=[as-is|disable|pull-down|pull-up] (defaults to 'as-is'):\n"); + printf(" set the line bias\n"); + printf(" -D, --drive=[push-pull|open-drain|open-source] (defaults to 'push-pull'):\n"); + printf(" set the line drive mode\n"); printf(" -m, --mode=[exit|wait|time|signal] (defaults to 'exit'):\n"); printf(" tell the program what to do after setting values\n"); printf(" -s, --sec=SEC:\tspecify the number of seconds to wait (only valid for --mode=time)\n"); printf(" -u, --usec=USEC:\tspecify the number of microseconds to wait (only valid for --mode=time)\n"); printf(" -b, --background:\tafter setting values: detach from the controlling terminal\n"); printf("\n"); + printf("Biases:\n"); + printf(" as-is:\tleave bias unchanged\n"); + printf(" disable:\tdisable bias\n"); + printf(" pull-up:\tenable pull-up\n"); + printf(" pull-down:\tenable pull-down\n"); + printf("\n"); + printf("Drives:\n"); + printf(" push-pull:\tdrive the line both high and low\n"); + printf(" open-drain:\tdrive the line low or go high impedance\n"); + printf(" open-source:\tdrive the line high or go high impedance\n"); + printf("\n"); printf("Modes:\n"); printf(" exit:\t\tset values and exit immediately\n"); printf(" wait:\t\tset values and wait for user to press ENTER\n"); @@ -178,11 +195,31 @@ static const struct mode_mapping *parse_mode(const char *mode) return NULL; } +static int bias_flags(const char *option) +{ + if (strcmp(option, "pull-down") == 0) + return GPIOD_CTXLESS_FLAG_BIAS_PULL_DOWN; + if (strcmp(option, "pull-up") == 0) + return GPIOD_CTXLESS_FLAG_BIAS_PULL_UP; + if (strcmp(option, "disable") == 0) + return GPIOD_CTXLESS_FLAG_BIAS_DISABLE; + return 0; +} + +static int drive_flags(const char *option) +{ + if (strcmp(option, "open-drain") == 0) + return GPIOD_CTXLESS_FLAG_OPEN_DRAIN; + if (strcmp(option, "open-source") == 0) + return GPIOD_CTXLESS_FLAG_OPEN_SOURCE; + return 0; +} + int main(int argc, char **argv) { const struct mode_mapping *mode = &modes[MODE_EXIT]; unsigned int *offsets, num_lines, i; - int *values, rv, optc, opti; + int *values, rv, optc, opti, flags = 0; struct callback_data cbdata; bool active_low = false; char *device, *end; @@ -204,6 +241,12 @@ int main(int argc, char **argv) case 'l': active_low = true; break; + case 'B': + flags |= bias_flags(optarg); + break; + case 'D': + flags |= drive_flags(optarg); + break; case 'm': mode = parse_mode(optarg); if (!mode) @@ -268,9 +311,10 @@ int main(int argc, char **argv) die("invalid offset: %s", argv[i + 1]); } - rv = gpiod_ctxless_set_value_multiple(device, offsets, values, - num_lines, active_low, "gpioset", - mode->callback, &cbdata); + rv = gpiod_ctxless_set_value_multiple_ext( + device, offsets, values, + num_lines, active_low, "gpioset", + mode->callback, &cbdata, flags); if (rv < 0) die_perror("error setting the GPIO line values"); From patchwork Thu Nov 21 00:35:56 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kent Gibson X-Patchwork-Id: 1198614 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (no SPF record) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=linux-gpio-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="meJ8j87u"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 47JLGv3bZ3z9sNx for ; Thu, 21 Nov 2019 11:36:55 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726729AbfKUAgz (ORCPT ); Wed, 20 Nov 2019 19:36:55 -0500 Received: from mail-pf1-f171.google.com ([209.85.210.171]:43366 "EHLO mail-pf1-f171.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726705AbfKUAgy (ORCPT ); Wed, 20 Nov 2019 19:36:54 -0500 Received: by mail-pf1-f171.google.com with SMTP id 3so670589pfb.10 for ; Wed, 20 Nov 2019 16:36:54 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=zMTMfyn0qgrWE3bsY0sIswHuBaSbLHENecV0WRLRQ1w=; b=meJ8j87uVRF2bRossMm5Ykb1YKEXxu49mPMMRhL8CsQ19ZMLIek7/CppQllvbkRVfr iQheLJaBSL1fu9xQhOjkf5qLzqHCpcX0+PN05aTY+ivK3cexTn6I57ggJE9WjybP4fJy 8lyF03DzVV1inho+hssVgZvDvHsr6gGdm0BN0uxbZdEgeq6ZElN8uLNg8xDx5oAOOrPr u0QGCQTm0fRhWA9Ye5ELjxE3N8/GgvBkG5erQMJER+aiANda7u9E16gpm6n0quhAmGpC Ag2yGHlqxmI6D8ug4jbJoqK5cv0XbsKucO/9jidzJc/je7F7TQGNq6LKNMPxTeaBwnME Ge2g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=zMTMfyn0qgrWE3bsY0sIswHuBaSbLHENecV0WRLRQ1w=; b=cGp1psDl4wAv/IMiyAgEZsXy373jhF8YTsH1QC7feFvutRM6Y4nBfx9KU6P6bRGjJs 4gkFZnfNKslJ7WoM0QMgVaATri33nvRWIKVTA5LM/Edw0oVfreuJWuhfHc/uEJHr6gd2 deBI1TdJH7CAfIFEOgpUhzOKTdetoNnd4cjnJU8L2KiUXCs61ua3sa6GRDengjb/wMcK F/9WQHutI6+/yu1KeozzRKLM99KJzhm35r9V5D00saZ4P+rtd7w1b+ILbVxq81glDjoM 1lLJ9UemhJ0v/qeeMQc5MuivAqjC2tiVo54Gf/gyUQ9/gJOjoFZbOnm/mrJNXU2C1f7Q WQfQ== X-Gm-Message-State: APjAAAXGL+ikRHb/7Sind8Cc6cYTQmSixkgtC0phjFEjI3nQ+3JYNm8j 4lxOYUr5FS8tW6h9BM12GYS8+cuZXB8= X-Google-Smtp-Source: APXvYqz61EqZG4WtGwww2h4r3k26cHEuAGA/RfBQ+P9FM4buQCGFMXKGuFVuVY1d3lyS/gONrTqy9w== X-Received: by 2002:a63:4f41:: with SMTP id p1mr6314365pgl.138.1574296613477; Wed, 20 Nov 2019 16:36:53 -0800 (PST) Received: from sol.lan (220-235-109-115.dyn.iinet.net.au. [220.235.109.115]) by smtp.gmail.com with ESMTPSA id s1sm420756pgk.9.2019.11.20.16.36.51 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 20 Nov 2019 16:36:53 -0800 (PST) From: Kent Gibson To: linux-gpio@vger.kernel.org, bgolaszewski@baylibre.com Cc: Kent Gibson Subject: [libgpiod] [PATCH v2 14/14] tools: add tests for bias and drive flags Date: Thu, 21 Nov 2019 08:35:56 +0800 Message-Id: <20191121003556.9020-15-warthog618@gmail.com> X-Mailer: git-send-email 2.24.0 In-Reply-To: <20191121003556.9020-1-warthog618@gmail.com> References: <20191121003556.9020-1-warthog618@gmail.com> MIME-Version: 1.0 Sender: linux-gpio-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-gpio@vger.kernel.org Add tests for bias flags to applicable tools - gpioget, gpioset, and gpiomon, as well as drive flags for gpioset. Signed-off-by: Kent Gibson --- tools/gpio-tools-test.bats | 139 +++++++++++++++++++++++++++++++++++++ 1 file changed, 139 insertions(+) diff --git a/tools/gpio-tools-test.bats b/tools/gpio-tools-test.bats index aff54f7..8bced02 100755 --- a/tools/gpio-tools-test.bats +++ b/tools/gpio-tools-test.bats @@ -312,6 +312,34 @@ teardown() { test "$output" = "1 1 0 0 1 0 1 0" } +@test "gpioget: read all lines (pull-up)" { + gpio_mockup_probe 8 8 8 + + gpio_mockup_set_pull 1 2 1 + gpio_mockup_set_pull 1 3 1 + gpio_mockup_set_pull 1 5 1 + gpio_mockup_set_pull 1 7 1 + + run_tool gpioget --bias=pull-up "$(gpio_mockup_chip_name 1)" 0 1 2 3 4 5 6 7 + + test "$status" -eq "0" + test "$output" = "1 1 1 1 1 1 1 1" +} + +@test "gpioget: read all lines (pull-down)" { + gpio_mockup_probe 8 8 8 + + gpio_mockup_set_pull 1 2 1 + gpio_mockup_set_pull 1 3 1 + gpio_mockup_set_pull 1 5 1 + gpio_mockup_set_pull 1 7 1 + + run_tool gpioget --bias=pull-down "$(gpio_mockup_chip_name 1)" 0 1 2 3 4 5 6 7 + + test "$status" -eq "0" + test "$output" = "0 0 0 0 0 0 0 0" +} + @test "gpioget: read some lines" { gpio_mockup_probe 8 8 8 @@ -405,6 +433,79 @@ teardown() { test "$status" -eq "0" } +@test "gpioset: set lines and wait for SIGTERM (push-pull)" { + gpio_mockup_probe 8 8 8 + + coproc_run_tool gpioset --drive=push-pull --mode=signal "$(gpio_mockup_chip_name 2)" \ + 0=0 1=0 2=1 3=1 4=1 5=1 6=0 7=1 + + gpio_mockup_check_value 2 0 0 + gpio_mockup_check_value 2 1 0 + gpio_mockup_check_value 2 2 1 + gpio_mockup_check_value 2 3 1 + gpio_mockup_check_value 2 4 1 + gpio_mockup_check_value 2 5 1 + gpio_mockup_check_value 2 6 0 + gpio_mockup_check_value 2 7 1 + + coproc_tool_kill + coproc_tool_wait + + test "$status" -eq "0" +} + +@test "gpioset: set lines and wait for SIGTERM (open-drain)" { + gpio_mockup_probe 8 8 8 + + gpio_mockup_set_pull 2 2 1 + gpio_mockup_set_pull 2 3 1 + gpio_mockup_set_pull 2 5 1 + gpio_mockup_set_pull 2 7 1 + + coproc_run_tool gpioset --drive=open-drain --mode=signal "$(gpio_mockup_chip_name 2)" \ + 0=0 1=0 2=1 3=1 4=1 5=1 6=0 7=1 + + gpio_mockup_check_value 2 0 0 + gpio_mockup_check_value 2 1 0 + gpio_mockup_check_value 2 2 1 + gpio_mockup_check_value 2 3 1 + gpio_mockup_check_value 2 4 0 + gpio_mockup_check_value 2 5 1 + gpio_mockup_check_value 2 6 0 + gpio_mockup_check_value 2 7 1 + + coproc_tool_kill + coproc_tool_wait + + test "$status" -eq "0" +} + +@test "gpioset: set lines and wait for SIGTERM (open-source)" { + gpio_mockup_probe 8 8 8 + + gpio_mockup_set_pull 2 2 1 + gpio_mockup_set_pull 2 3 1 + gpio_mockup_set_pull 2 5 1 + gpio_mockup_set_pull 2 7 1 + + coproc_run_tool gpioset --drive=open-source --mode=signal "$(gpio_mockup_chip_name 2)" \ + 0=0 1=0 2=1 3=0 4=1 5=1 6=0 7=1 + + gpio_mockup_check_value 2 0 0 + gpio_mockup_check_value 2 1 0 + gpio_mockup_check_value 2 2 1 + gpio_mockup_check_value 2 3 1 + gpio_mockup_check_value 2 4 1 + gpio_mockup_check_value 2 5 1 + gpio_mockup_check_value 2 6 0 + gpio_mockup_check_value 2 7 1 + + coproc_tool_kill + coproc_tool_wait + + test "$status" -eq "0" +} + @test "gpioset: set some lines and wait for ENTER" { gpio_mockup_probe 8 8 8 @@ -576,6 +677,44 @@ teardown() { "event:\\s+FALLING\\s+EDGE\\s+offset:\\s+4\\s+timestamp:\\s+\[[0-9]+\.[0-9]+\]" } +@test "gpiomon: single falling edge event (pull-up)" { + gpio_mockup_probe 8 8 + + gpio_mockup_set_pull 1 4 0 + + coproc_run_tool gpiomon --bias=pull-up "$(gpio_mockup_chip_name 1)" 4 + + gpio_mockup_set_pull 1 4 0 + sleep 0.2 + + coproc_tool_kill + coproc_tool_wait + + test "$status" -eq "0" + output_regex_match \ +"event:\\s+FALLING\\s+EDGE\\s+offset:\\s+4\\s+timestamp:\\s+\[[0-9]+\.[0-9]+\]" + +} + +@test "gpiomon: single rising edge event (pull-down)" { + gpio_mockup_probe 8 8 + + gpio_mockup_set_pull 1 4 1 + + coproc_run_tool gpiomon --bias=pull-down "$(gpio_mockup_chip_name 1)" 4 + + gpio_mockup_set_pull 1 4 1 + sleep 0.2 + + coproc_tool_kill + coproc_tool_wait + + test "$status" -eq "0" + output_regex_match \ +"event:\\s+RISING\\s+EDGE\\s+offset:\\s+4\\s+timestamp:\\s+\[[0-9]+\.[0-9]+\]" + +} + @test "gpiomon: single rising edge event (active-low)" { gpio_mockup_probe 8 8