Ideas for the ongoing pinctrl discussion #35077
Replies: 7 comments 13 replies
-
This is basically what we have for the clock control API. I could see some value in this, since it would allow hardware-specific overlays to configure a subsystem or application for e.g. "on" / "powersave" without cluttering the source code with board ifdefs. |
Beta Was this translation helpful? Give feedback.
-
For DTS, we have something like this today for NXP: In board.dts:
In SOC-pinctrl.dtsi (this data is generated from vendor XML files):
From #35039 for STM32:
From SoC dtsi we have:
|
Beta Was this translation helpful? Give feedback.
-
I have been giving this some more thought. The pinctrl DTS grouping makes sense if the pinctrl API takes an index for which group to configure. If the API does not take an index (but instead takes a pointer to a semi-opaque structure as discussed above) I do not see any gain from adding the group indirection in DTS. I therefore think DTS representation option 3. (see above) makes most sense. |
Beta Was this translation helpful? Give feedback.
-
Some notes/thoughts on the Devicetree representation used by Linux vs. Zephyr for the STM32 case: On Linux we have:
The Linux approach could be improved if we had the following content auto-generated:
That is, if we had a ...
#define USART2_TX_PD5 STM32_PINMUX('D', 5, AF7)
#define USART2_RTS_PD4 STM32_PINMUX('D', 4, AF7)
#define USART2_RX_PD6 STM32_PINMUX('D', 6, AF7)
#define USART2_CTS_NSS_PD3 STM32_PINMUX('D', 3, AF7)
... NOTE: This can be easily done re-using parts from https://github.com/zephyrproject-rtos/hal_stm32/blob/main/scripts/genpinctrl/genpinctrl.py This way, the
I'm not sure if the "pins1" and "pins2" subgroups can be extracted properly with current DT tooling, @mbolivar-nordic ? If we compare with the current approach in Zephyr:
I think that the most important difference is that if we used the Linux approach the board takes the final decision on pin settings such as the pull-up/down, slew-rate, etc. This is something that I think makes sense, it's really the board/application that has the information to make this decision. As of today the STM32 auto-generator provides common defaults, but they are not necessarily the best ones. They can certainly be overridden, though. A side note of a limitation I found when using current STM32 approach: #22748 (comment) |
Beta Was this translation helpful? Give feedback.
-
Some more notes and thoughts on DT representation. Feel free to edit, comment, discuss pros/cons, etc. 1. DT node for each state, containing all pins (Linux approach, e.g. for ST)
Pros:
Cons:
Notes:
2. DT node for each pin (Zephyr approach, e.g. for ST)
If the file is auto-generated and the board needs to change any of the default pin properties, it can do it like this:
There is a proof of concept that introduces low power/sleep states using this approach: Pros:
Cons:
3. Variant of (2) for auto-generated casesIf the auto-generated files do not contain pin configuration, i.e. only pin routing, we'd then have:
Pros:
Cons:
4. Vendor specific approach 1 (nRF)The pinctrl API doesn't need to make any assumption on how pinctrl data is stored internally. This means that, in practice, vendors can really decide what to do in nodes referenced from For example, for nRF we could have:
Pros:
Cons:
5. Vendor specific approach 2 (nRF)Following on vendor specific approach, we could have, for nRF:
Pros:
Cons:
|
Beta Was this translation helpful? Give feedback.
-
if at (4)
It is possible to use a variable length list at pin creation at any proposal. I mean, a pin can be defined and all properties can follow
User still have the possibility to do below changes because properties are stored by pin individually.
Not sure if this kind of flexibility should be available. |
Beta Was this translation helpful? Give feedback.
-
I noted that loopback interfaces currently require pinctrl definitions to avoid build errors. I'm not sure if this is a valid use case. |
Beta Was this translation helpful? Give feedback.
-
Here is my input to the ongoing discussions of how to structure the upcoming pinctrl API and devicetree nodes in Zephyr. These ideas build upon the many proposals and ideas by other members of the community. The following PRs have been used as inspiration:
The discussions have focused on two different areas of implementation; the pinctrl C/C++ API for configuring pin function and pin properties at runtime, and the devicetree representation of pre-defined pin functions and pin properties.
Devicetree representation
Multiple ideas for devicetree representation has surfaced during the ongoing API discussions. From what I have seen, the discussions have been centred around the following concepts:
pinctrl-n
properties (states), each with a reference to a pinctrl group node (a child of the pinctrl devicetree node). This pinctrl group contains a number of child nodes, each representing a pin, its function, and its properties to be configured when the given pinctrl group is selected. Apinctrl-names
property allow associating eachpinctrl-n
property with a name for easier reference.pinctrl-n
properties, each with a list of references to pins, their functions, and their properties to be configured when the givenpinctrl-n
is selected.API
Given the differences between the pin controllers/pin multiplexers present in the various SoCs, I do not see any way (or even value) of a truly common API. One option that comes close is an API that allows passing in a SoC pinctrl/pinmux specific data structure (or array of said data structure along with a length) representing the specific information needed for that given SoC pinctrl/pinmux as a void pointer.
SoC pinctrl/pinmux
DT_
macros can be added to extract the neededpinctrl-n
devicetree node properties and encode them as the SoC pinctrl/pinmux specific data structure, effectively reducing these structures to opaque types for typical use-cases.The data structures representing the
pinctrl-n
states internally supported by a given peripheral driver (e.g. normal state, power saving state, error recovery state, ...) can be stored within thestruct config
of the given driver. This has the benefit that disabling a driver (or an instance) will also prevent any of the unusedpinctrl-0
data structures from taking up flash. Most drivers will likely only support one state (normal) or two states (normal and power save).Should a user application have a need for
pinctrl-n
states not supported by the given peripheral driver (e.g. remapping of UART ports between a TTL UART pin header and a USB to UART IC), application specificpinctrl-n
nodes can be added (e.g. in a devicetree overlay). The data structures representing the custompinctrl-n
states can be extracted from DTS using the sameDT_
macros as used by the drivers - and the same pinctrl API can be used for selecting the custom states. Again, unusedpinctrl-n
properties (those, that are not referenced by code) will not take up any flash space.For more advanced use-cases (e.g those outlined for CircuitPython in #11918), the above can also support run-time configuration of pinctrl/pinmux without any compile-time devicetree representation of the desired
pinctrl-n
state. For this use-case, the data structures cannot be considered opaque, but would rather be filled in at run-time by the application and passed to the same pinctrl API as used in the above examples.Beta Was this translation helpful? Give feedback.
All reactions