-
Notifications
You must be signed in to change notification settings - Fork 8.2k
Description
Reported by Piotr Mienkowski:
I would like to propose to streamline/rework/clarify usage of GPIO, Pinmux driver combo which I believe become overcomplicated and may be confusing for a regular user.
The current API seems to be designed around Intel Quark architecture and QMSI SDK. In Quark there are separate Pinmux and GPIO modules and so we got separate Pinmux and GPIO drivers. However, in most SoCs GPIO module takes care of both PIO (reading/writing from/to a pin) and pin muxing (connecting pin to a peripheral/PIO controller). Other typical tasks of GPIO driver include connecting pull-ups/pull-downs, glitch filtering, debouncing, etc. By now the functional split between the two drivers become blurred and is overlapping.
Some examples:
At present GPIO driver defines GPIO_PUD_PULL_UP (Enable GPIO pin pull-up) to be used with gpio_pin_configure() function and Pinmux driver has pinmux_pin_pullup() function. Both are meant to do the same thing however gpio_pin_configure() will not work with Intel Quark chips and pinmux_pin_pullup() will mostly not work with other chips e.g. Freescale/NXP FRDM-K64F. Some SoCs e.g. Atmel SAM3x implement both functions but then even for Atmel SAM3x setting pin pull-down is only possible via gpio_pin_configure() function.
pinmux_pin_input_enable() function is used by Quark chips to disable/enable input pad and gpio_pin_configure() to set pin as input or output. This is not easily rendered from the function's name/description and in fact Atmel SAM3x driver implements pinmux_pin_input_enable() to configure pin as input or output overlapping it with the same functionality provided by gpio_pin_configure().
In case of ARM based chips e.g. Atmel SAM3x, Freescale/NXP FRDM-K64F to configure pin with pull-up and connect it to external peripheral one needs to call pinmux_pin_set() which takes as an argument pin index, e.g. pin PB2, third pin on port B would have index 34 and gpio_pin_configure() which takes as an argument port and port's pin number, e.g. PB2 has number 2. So in two subsequent calls we need to use different pin values even if we operate on the same pin. While this may be necessary for Quark chips it is not for other chip families.
Currently it is not possible to know which function should be used when and how without analyzing Zephyr's source code.
I do not have a full overview of all SoCs architectures nor Zephyr's approach to Device Driver API, however, the two solutions which may be worth considering are:
- Assuming that we want to have a uniform driver API across all architectures it would be likely best to phase out Pinmux driver and implement pin multiplexing in GPIO driver. That would require adding something like GPIO_FUNC_A, ..., GPIO_FUNC_D to GPIO API. The split between Pinmux and GPIO driver does not seem to be a good general solution.
- Assuming that driver API does not have to be strictly uniform across all architectures provide a way e.g. through SoC specific driver documentation to clearly indicate which drivers and driver features are supported by the given SoC. In this case Pinmux driver could continue to be used by Quark chips while other families could use GPIO driver.
(Imported from Jira ZEP-781)