New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
api: gpio: Clean up GPIO dt-bindings flags #12651
Conversation
Codecov Report
@@ Coverage Diff @@
## master #12651 +/- ##
=======================================
Coverage 54.06% 54.06%
=======================================
Files 239 239
Lines 26922 26922
Branches 6505 6505
=======================================
Hits 14556 14556
Misses 9701 9701
Partials 2665 2665 Continue to review full report at Codecov.
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There are a couple capabilities in #11880 that don't seem to be supported by this version:
- The ability to configure direction as simultaneously input and output, a feature supported by multiple drivers including SX1509B and Nordic. By using separate bits we get better control of power consumption by explicitly disabling input and output buffers.
- The ability to explicitly configure drive strength as low or high, where the defaults differ between SX1509B and Nordic (noted as lacking)
- The ability to specify the initial level for output GPIOs.
There may be others. It also lacks an example of how to implement the extensions it provides, and it doesn't build.
All that can of course be addressed, but fundamentally I don't see anything here that justifies spending more time on a solution that is not demonstrably superior to the one that was proposed in early December and already has four approvals plus a LGTM.
The functionality was not changed. Pin configured as GPIO_DIR_OUT works simultaneously as input. Current proposal doesn't have ability to disable pin. This could be addressed by adding GPIO_DIR_DISABLED flag. But a better approach would be to use pinctrl like interface which provides a more sophisticated approach to configuring pin drive capabilities.
It's mentioned on the To Do list, will address shortly.
Supported by GPIO_DIR_OUT_LOW, GPIO_DIR_OUT_HIGH flags |
GPIO configuration flags will move and some that used to be in the low 8 bits are now higher, resulting in implicit constant conversion overflows. Use a boolean data type to hold boolean values. Signed-off-by: Peter A. Bigot <pab@pabigot.com> Signed-off-by: Piotr Mienkowski <piotr.mienkowski@gmail.com>
include/dt-bindings/gpio/gpio.h
Outdated
|
||
/** @cond INTERNAL_HIDDEN */ | ||
#define GPIO_POL_SHIFT 18 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If part of your motivation for rejecting #11880 was objection to defining offset macros for single-bit fields, you really ought to remove this one.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All GPIO_POL_ flags were deprecated and are going to be removed in the future. GPIO_POL_SHIFT
is required to define GPIO_POL_MASK
which is used in the code base.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So there is existing precedent in Zephyr for providing mask and shift defines for single-bit fields. Good to know.
Yes, which is my point. Ability to control input enable explicitly was added in #11880, and is relevant to at least two existing GPIO driver implementations.
That's an opinion that can be defended or challenged. But we don't have pinctrl. We won't have pinctrl for 1.14-LTS. I would like to have the functionality now. |
It was always possible "to configure direction as simultaneously input and output". I've added also |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
@Mierunski could you please take a look at this PR in the context of #11880? |
Wait, what? No they don't. At least I don't think so. I thought they were meant to say "configure the device to invert the signal polarity". (Whatever that means.) At least that's how they're used in most drivers now. |
That's not right either. The way I've always seen the They certainly don't affect the value written by |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some more issues resulting from a closer look.
* Write logical data value to a pin, taking into account GPIO_ACTIVE_LOW flag. | ||
* If an output was configured as Active Low, writing value 1 to a pin will set | ||
* it to low output state. Otherwise writing value 1 to a pin will set it to | ||
* high output state. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This isn't what those flags are intended to convey, nor does this describe how this function actually behaves (unless I am very confused...).
@@ -216,7 +222,8 @@ static inline int gpio_pin_write(struct device *port, u32_t pin, | |||
/** | |||
* @brief Read the data value of a single pin. | |||
* | |||
* Read the input state of a pin, returning the value 0 or 1. | |||
* Read the logical value of a pin, returning 0 or 1. The function takes into | |||
* account GPIO_ACTIVE_LOW flag. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The function does not adjust its return value based on GPIO_ACTIVE_LOW
.
/** Legacy flag indicating that GPIO pin polarity is normal. | ||
* | ||
* @deprecated Replace with `GPIO_ACTIVE_HIGH`. | ||
*/ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These two are not equivalent. In the intended use as documented in #11880 GPIO_ACTIVE_foo
is informational, indicating the active level of the signal. It's specifically needed in the DTS bindings to indicate whether an LED (for example) needs zero or one written to turn it on.
Polarity inversion is a configuration that affects how the driver sets up the GPIO peripheral.
/** Legacy flag indicating that GPIO pin polarity is inverted. | ||
* | ||
* @deprecated Replace with `GPIO_ACTIVE_LOW`. | ||
*/ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same: inverted polarity does not mean active low.
For all deprecated defines I would suggest compressing the defines and having a single comment block around them that states they will be deprecated. Don't attempt to document them any further because only existing implementation will have them in use and new implementations you want to discourage usage. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there any particular reason to have how bit positions 0, 1, and 2 are defined differ from the linux dt-binding gpio.h:
/* Bit 0 express polarity */
#define GPIO_ACTIVE_HIGH 0
#define GPIO_ACTIVE_LOW 1
/* Bit 1 express single-endedness */
#define GPIO_PUSH_PULL 0
#define GPIO_SINGLE_ENDED 2
/* Bit 2 express Open drain or open source */
#define GPIO_LINE_OPEN_SOURCE 0
#define GPIO_LINE_OPEN_DRAIN 4
/*
* Open Drain/Collector is the combination of single-ended open drain interface.
* Open Source/Emitter is the combination of single-ended open source interface.
*/
#define GPIO_OPEN_DRAIN (GPIO_SINGLE_ENDED | GPIO_LINE_OPEN_DRAIN)
#define GPIO_OPEN_SOURCE (GPIO_SINGLE_ENDED | GPIO_LINE_OPEN_SOURCE)
That was my impression when reviewing #11880 that the usage of
Linux documents its usage of Active-High and Active-Low flags. This is also mentioned in the description of gpio get_value, set_value functions. |
I don't read that comment from @galak quite the same way, though I can see that interpretation. The usage of active high/low flags in Linux is exactly as I've described; the difference is that Linux apparently uses them to control the sense of read/write operations in their API. Zephyr's read/write GPIO functions affect the signal value directly, not the logical value as Linux does. Maybe that was not the intent, but AFAICT all existing use of The |
My comment was about the bit position and names. There's a subtle point here about Linux compatibility and Device Tree. We should be aiming to utilize and conform to the Device Tree specs that are utilized in Linux, that's the canonical device tree definition repository. If there are some area's that the DTS binding aren't clear or need clarity we should aim to get that clarity. |
We were actually arguing about this comment. It's about intended use of As for the
This shouldn't be required as we are not aiming for binary compatibility. However, I can change encoding to be the same as in linux dt-binding gpio.h. This is not a problem. |
Discussion in dev review telecon 2019-01-24 leaves this open until next week and more review. |
I've tried to keep comments to minimum. Only in case of |
316ead0
to
f14c85a
Compare
This commit makes following changes to GPIO dt-bindings flags: - Added GPIO_DIR_OUT_LOW, GPIO_DIR_OUT_HIGH flags to initialize output in low or high state. - Added GPIO_ACTIVE_LOW, GPIO_ACTIVE_HIGH to indicate pin active state. - Added GPIO_OPEN_DRAIN, GPIO_OPEN_SOURCE to configure single ended pin driving mode. - reworked GPIO_INT_* flags to configure pin interrupts. - following flags were deprecated: GPIO_DS_DISCONNECT_*, GPIO_INT, GPIO_INT_ACTIVE_*, GPIO_INT_DOUBLE_EDGE, GPIO_INT_DEBOUNCE, GPIO_POL_*. Fixes zephyrproject-rtos#10339 Signed-off-by: Piotr Mienkowski <piotr.mienkowski@gmail.com>
New gpio.h DT bindings are based on Linux implementation. Old, deprecated GPIO flags have been changed to the current equivalent. - added GPIO_ACTIVE_LOW, GPIO_ACTIVE_HIGH to indicate pin active state - GPIO_INT_ACTIVE_LOW changed to GPIO_INT_LOW - GPIO_INT_ACTIVE_HIGH changed to GPIO_INT_HIGH Signed-off-by: Piotr Mienkowski <piotr.mienkowski@gmail.com>
Update gpio_pin_configure() to take into account GPIO flags defined by the devicetree. Signed-off-by: Piotr Mienkowski <piotr.mienkowski@gmail.com>
GPIO flags have been updated to match Linux implementation. Added open drain, open source output configuration. Support for GPIO_ACTIVE_* flags. Signed-off-by: Piotr Mienkowski <piotr.mienkowski@gmail.com>
GPIO flags have been updated to match Linux implementation. Support for GPIO_ACTIVE_*, GPIO_OUTPUT_INIT_* flags. Signed-off-by: Piotr Mienkowski <piotr.mienkowski@gmail.com>
I have reworked the way we configure input / output mode. Rather than using I've added also usage examples of As per request from @galak the encoding of flags used in DTS is now identical as in linux dt-binding gpio.h. |
This statement doesn't quite make sense. Either the implementation of
The very purpose of this PR is to rework usage of GPIO flags. So the statement once again doesn't quite make sense. Double so, taking into account that the usage of |
I don't think I'm overlooking it. I see it as two things: what do the flags indicate, and how do the driver methods work. The flag semantics I described in #11880 is generally consistent with the first half of the reference you gave: they describe what line level indicates "active" for the signal. I agree that the last half (how the flags affect interaction with the signal) is different, but that's not my fault. In #11880 I chose to leave the behavior of I would in principal be open to changing the driver functions to work with the logical levels, but we'd have to change a few things:
That seems a bit much to change, but if there's consensus that it's the right way forward and every GPIO driver maintainer commits to updating their code within the next few weeks (so it's available for several weeks of pre-release testing) I'd be willing to change #11880.
I'm not aware of doing anything to change the |
Since during the API call there seem to be misunderstanding about the purpose of If an application prefers to control CS (Chip Select) pin which is typically active low by writing |
Please see #11880 (comment) for a proposed compromise that supports existing usage while clarifying existing API and adding API to support positive/negative logic. |
@@ -42,12 +42,12 @@ | |||
compatible = "gpio-keys"; | |||
button0: button_0 { | |||
/* gpio flags need validation */ | |||
gpios = <&gpiof 6 GPIO_INT_ACTIVE_LOW>; | |||
gpios = <&gpiof 6 GPIO_INT_LOW>; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wasn't the GPIO_ACTIVE_LOW
flag supposed to be used also to specify active state of inputs? One may not want to use interrupts to handle buttons. Sometimes just reading the current state of the button could be desired.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Indeed. I will change this line to
gpios = <&gpiof 6 (GPIO_ACTIVE_LOW | GPIO_INT_LOW)>;
Significant unreviewed changes since this review was filed.
* Write logical data value to a pin, taking into account GPIO_ACTIVE_LOW flag. | ||
* If an output was configured as Active Low, writing value 1 to a pin will set | ||
* it to low output state. Otherwise writing value 1 to a pin will set it to | ||
* high output state. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am against changing the definition of how gpio_pin_write
and gpio_pin_read
are expected to behave. This would require alteration of all existing implementations of GPIO drivers (as the GPIO_ACTIVE_LOW
flag cannot be just not supported).
In my opinion the GPIO_ACTIVE_*
flags should be handled outside of particular GPIO drivers, for example in wrappers as I proposed in #11880 (comment).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I provided a bit more elaborate answer in my comment in #11880. In short GPIO_ACTIVE_LOW
is just a different name for GPIO_POL_INV
flag which controls the value returned by gpio_pin_write
and gpio_pin_read
functions. Unfortunately, the documentation of these functions did not state it explicitly. The only reason we rename the GPIO_POL_INV
flag to GPIO_ACTIVE_LOW
is to be compatible with the definition of DTS gpio node in Linux.
Superseded by #16648. |
This PR attempts to resolve the concerns and discussions of issue #10339 and is based on work in #11880 by @pabigot.
The main differences to #11880 are as follows:
where 'N' is the value/state we want to encode.
GPIO_ACTIVE_LOW
,GPIO_ACTIVE_HIGH
flags.gpio_pin_read()
,gpio_pin_write()
functions was updated to clarify usage of the new GPIO_ACTIVE_ flags.The following design goals were applied:
Linux implementation is followed.
One extra point which we likely should revisit are issues raised by @dwagenk. Current implementation of pin read/write and interrupt API is not consistent.
I have not yet verified that generated documentation is formatted correctly.
Fixes #10339