diff options
author | Andrew McRae <amcrae@google.com> | 2022-01-23 23:07:22 +1100 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2022-01-25 12:37:46 +0000 |
commit | 6cc52e9a26bd8da1dbb9a27789f2de4dfd4579af (patch) | |
tree | eabc598008f8edb01d13bdc58fda522c00ee8ada /docs | |
parent | 02f77c034be26ae6c7f53e3b090365ac9dc3f8c5 (diff) | |
download | chrome-ec-6cc52e9a26bd8da1dbb9a27789f2de4dfd4579af.tar.gz |
zephyr: Update Zephyr GPIO docs
Update GPIO docs
- no-auto-init
- access for non enum-name based GPIOS
- new interrupt handling
BUG=b:214608987
TEST=none
BRANCH=none
Signed-off-by: Andrew McRae <amcrae@google.com>
Cq-Depend: chromium:3392111,chromium:3406473
Change-Id: I78c418a4ae635370fa398a597a7b361137b811a7
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/3411031
Reviewed-by: Fabio Baltieri <fabiobaltieri@google.com>
Diffstat (limited to 'docs')
-rw-r--r-- | docs/zephyr/zephyr_gpio.md | 109 |
1 files changed, 91 insertions, 18 deletions
diff --git a/docs/zephyr/zephyr_gpio.md b/docs/zephyr/zephyr_gpio.md index b6328abf74..320086a70b 100644 --- a/docs/zephyr/zephyr_gpio.md +++ b/docs/zephyr/zephyr_gpio.md @@ -20,8 +20,9 @@ Kconfig Option | Default | Documentation Configure the GPIO module by declaring all GPIOs in the devicetree node with `compatible` property `named-gpios`. The GPIO module automatically initializes -all GPIOs from this node. The C source code accesses GPIOs using the specified -`enum-name` property. +all GPIOs from this node (unless the `no-auto-init` property is present). +Legacy C source code accesses GPIOs using the specified +`enum-name` property as an enum name of the GPIO. Named GPIO properties: @@ -29,7 +30,11 @@ Property | Description | Settings :------- | :---------- | :------- `#gpio-cells` | Specifier cell count, always `<0>`, required if the node label is used in a `-gpios` property. | `<0>` `gpios` | GPIO phandle, identifies the port (X), pin number (Y) and flags. | `<&gpioX Y flags>` -`enum-name` | The enum used to refer to the GPIO in the code. | `GPIO_<NAME>` +`enum-name` | An optional name used to define an enum to refer to the GPIO in legacy code. | `GPIO_<NAME>` +`no-auto-init` | If present, the GPIO **will not** be initialized at start-up. | boolean, default false + +The use of `no-auto-init` allows GPIOs to be skipped at start-up initialization time, +and selectively enabled by code at some later time. The file [gpio-enum-name.yaml] defines the list of valid `enum-name` values. @@ -57,6 +62,37 @@ included from the main project DTS file. For platform specific features, other flags may be available in the Zephyr [dt-bindings/gpio/gpio.h] file, such as `GPIO_VOLTAGE_1P8`. +### Legacy enum-name usage + +Only GPIOs that require referencing from legacy common code should have an `enum-name` property. +The legacy API (e.g `gpio_get_level(enum gpio_signal)`) requires a known name for the enum, which +is set using the `enum-name` property. + +### Zephyr GPIO API usage + +GPIOs references that are not in legacy common code should use the +[standard Zephyr API](https://docs.zephyrproject.org/latest/reference/peripherals/gpio.html) +to access the GPIOs. +To facilitate this, all GPIOs in `named-gpios` will have prebuilt `struct gpio_dt_spec` blocks +created that may be used directly in the Zephyr GPIO API calls. +These blocks are accessed via a macro (`GPIO_DT_LABEL`) using the node label on the GPIO. +The legacy enum can also be used to retrieve the `gpio_dt_spec` for an GPIO via the +function `gpio_get_dt_spec` (though this is a runtime lookup). E.g: + +``` + fan_status = gpio_pin_get_dt(GPIO_DT_LABEL(gpio_en_pp5000_fan)); +... + /* + * Legacy code gave us an enum gpio_signal, get a Zephyr reference + * for that GPIO. + */ + const struct gpio_dt_spec *my_gpio = gpio_get_dt_spec(my_signal); + my_status = gpio_pin_get_dt(my_gpio); +``` + +The goal is to migrate away from using the legacy API to use the Zephyr API, and +eventually deprecate the use of the `enum-name` property to generate the GPIO signal enum. + ### Unused GPIOs Unused GPIOs should be listed separately in an `unused-gpio` node. EC chip @@ -107,28 +143,65 @@ named-gpios { } ``` -## Board Specific Code +## GPIO Interrupts + +GPIO interrupts are specified in a device tree node with a `compatible` property +of `cros-ec,gpio-interrupts`. + +Child nodes of this single node contain the following properties: + +Property | Description | Settings +:------- | :---------- | :------- +`irq-gpio` | A reference via a node label to the GPIO that is associated with this interrupt. | `<&gpio_lable>` +`flags` | The GPIO [interrupt flags](https://docs.zephyrproject.org/latest/reference/peripherals/gpio.html) that define how the interrupt is generated. | `GPIO_INT_<flags>` +`handler` | The C name of the interrupt handler that handles the interrupt. | C function name. + +For example: + +``` +gpio-interrupts { + compatible = "cros-ec,gpio-interrupts"; +... + int_power_button: power_button { + irq-gpio = <&gpio_ec_pwr_btn_l>; + flags = <GPIO_INT_EDGE_BOTH>; + handler = "power_button_interrupt"; + }; +... +} +``` + +There must only be one named node containing all of the device tree interrupt +configuration, but of course overlays may be used to add child nodes or modify the +single node. -Projects that use GPIO interrupts have to specify the interrupt to routine -mappings in a board specific file. This normally happens in [gpio_map.h] in -the project `include` directory, by specifying a series of `GPIO_INT` in a -`EC_CROS_GPIO_INTERRUPTS` define. For example: +The C handler takes one argument, the `enum signal` of the GPIO, such as: ``` -#define EC_CROS_GPIO_INTERRUPTS \ - GPIO_INT(GPIO_AC_PRESENT, GPIO_INT_EDGE_BOTH, extpower_interrupt) \ - GPIO_INT(GPIO_LID_OPEN, GPIO_INT_EDGE_BOTH, lid_interrupt) \ - ... +void power_button_interrupt(enum gpio_signal signal) +{ + /* Process power button event */ +... +} ``` -The format of GPIO_INT is: +This matches the function signature of the existing legacy interrupt handlers, so no +shims are required. + +Before any interrupt can be received, it must be enabled. Legacy code uses +the functions `gpio_enable_interrupt(enum signal)` and +`gpio_disable_interrupt(enum signal)` functions. -`GPIO_INT(signal, flags, irq_handler)` +Whilst it is possible to use the Zephyr GPIO interrupt API directly, +for convenience (until the deprecation of the legacy GPIO enum signal names) +interrupts can be identified via a macro and the label on the interrupt child nodes, +and these can be used to enable or disable the interrupts: + +``` + gpio_enable_dt_interrupt(GPIO_INT_FROM_NODELABEL(int_power_button)); +``` -- `signal` is the GPIO `enum-name` defined in the `named-gpios` declaration, - any of [gpio-enum-name.yaml]. -- `flags` is a Zephyr GPIO interrupt flag, any of [include/drivers/gpio.h]. -- `irq_handler` is function called when the interrupt is triggered. +This avoid having to create boiler-plate callbacks as part of the interrupt setup. ## Threads |