zephyriot / zep-jira14

0 stars 0 forks source link

GPIO API Update #928

Open nashif opened 7 years ago

nashif commented 7 years ago

Reported by Piotr Mienkowski:

Current GPIO API despite its relative complexity has several limitations which make it difficult to use for some SoC architectures.

The API was designed around Intel Quark family and its focus is on providing functions which operate on a single pin where pin is provided as an index number. There is also a set of functions that operate on a whole port, however their functionality is limited.

Some architectures, like for example relatively big Atmel SMART SAM Cortex MCU family, are designed in such a way that all operations on the GPIO module should use pin mask and not pin number. This makes it very easy to operate on several pins simultaneously.

For such architectures gpiopin functions become irrelevant since operating on the whole port can always accomplish the same and then more. However the current set of gpioport functions is missing a 'mask' parameter which would allow to operate on a preselected set of pins and not the whole port.

Here is a proposal for a new API for port related functions:

int gpio_port_configure(struct device *port, uint32_t mask, uint32_t flags)
int gpio_port_read(struct device *port, uint32_t mask, uint32_t *value)

The write function is a bit more complicated. We could have:

int gpio_port_write(struct device *port, uint32_t mask, uint32_t value)

or alternatively:

int gpio_port_write(struct device *port, uint32_t value)
int gpio_port_set(struct device *port, uint32_t mask)
int gpio_port_clear(struct device *port, uint32_t mask)

the _set and _clear functions would set or clear pins indicated by the mask and leave the rest unchanged.

The callback functions also need more attention. We could have:

int gpio_port_enable_callback(struct device *port, uint32_t mask)
int gpio_port_disable_callback(struct device *port, uint32_t mask)

or alternatively:

int gpio_port_enable_callback(struct device *port, struct gpio_callback *callback)
int gpio_port_disable_callback(struct device *port, struct gpio_callback *callback)

The former one would make it easy to enable/disable several callbacks at once but it would also make it possible to mistakenly enable callbacks (interrupts) on pins for which no handler was installed. If a problematic pin happened to be connected to a clock source user would cause significant IRQ activity and strain on the system happening quietly in the background.

Maybe it would be also feasible to abandon the whole split between gpioport and gpiopin functions entirely and have gpio_* functions only. Then each SoC family would decide on their own if they want the 'pin' parameter to mean pin index or pin mask.

Other features currently not supported by GPIO driver:

(Imported from Jira ZEP-1024)

nashif commented 7 years ago

by Qiu Peiyang:

This story may be impacted by ZEP-781.

nashif commented 7 years ago

by Marcus Shawcroft:

The gpio API, like other driver APIs, should where possible define a standard semantic across all boards and SoCs, allowing individual SoC families to (re)define the semantic of the "pin" parameter would IMHO be a backward step. I can see an argument for folding the current set of port* and pin* functions into one single family, but that family should have standarized behaviour across all SoCs.