doc: dts: describe nexus node magic required for shield gpio translation
Document why and how we use the devicetree nexus map properties to
preserve devicetree flag specifications.
Signed-off-by: Peter Bigot <peter.bigot@nordicsemi.no>
diff --git a/doc/guides/dts/index.rst b/doc/guides/dts/index.rst
index 3f6501e..3e2d647 100644
--- a/doc/guides/dts/index.rst
+++ b/doc/guides/dts/index.rst
@@ -712,4 +712,77 @@
The include file ``include/generated_dts_board.h`` includes both these generated
files, giving Zephyr C source files access to the board's devicetree information.
+GPIO Nexus Nodes
+****************
+
+Each board has a set of General Purpose Input/Output (GPIO)
+peripherals that can be accessed through the :ref:`GPIO<gpio>` module.
+Many boards provide headers that allow :ref:`shields<shields>` from
+other vendors to be mounted on their boards. Each shield identifies
+its hardware in a devicetree overlay.
+
+GPIOs accessed by the shield peripherals must be identified using the
+shield GPIO abstraction, for example from the ``arduino-r3-header``
+compatible. Boards that provide the header must map the header pins
+to SOC-specific pins. This is accomplished by including a `nexus
+node`_ that looks like the following into the board devicetree file:
+
+.. _nexus node:
+ https://github.com/devicetree-org/devicetree-specification/blob/4b1dac80eaca45b4babf5299452a951008a5d864/source/devicetree-basics.rst#nexus-nodes-and-specifier-mapping
+
+.. code-block:: none
+
+ arduino_header: connector {
+ compatible = "arduino-header-r3";
+ #gpio-cells = <2>;
+ gpio-map-mask = <0xffffffff 0xffffffc0>;
+ gpio-map-pass-thru = <0 0x3f>;
+ gpio-map = <0 0 &gpioa 0 0>, /* A0 */
+ <1 0 &gpioa 1 0>, /* A1 */
+ <2 0 &gpioa 4 0>, /* A2 */
+ <3 0 &gpiob 0 0>, /* A3 */
+ <4 0 &gpioc 1 0>, /* A4 */
+ <5 0 &gpioc 0 0>, /* A5 */
+ <6 0 &gpioa 3 0>, /* D0 */
+ <7 0 &gpioa 2 0>, /* D1 */
+ <8 0 &gpioa 10 0>, /* D2 */
+ <9 0 &gpiob 3 0>, /* D3 */
+ <10 0 &gpiob 5 0>, /* D4 */
+ <11 0 &gpiob 4 0>, /* D5 */
+ <12 0 &gpiob 10 0>, /* D6 */
+ <13 0 &gpioa 8 0>, /* D7 */
+ <14 0 &gpioa 9 0>, /* D8 */
+ <15 0 &gpioc 7 0>, /* D9 */
+ <16 0 &gpiob 6 0>, /* D10 */
+ <17 0 &gpioa 7 0>, /* D11 */
+ <18 0 &gpioa 6 0>, /* D12 */
+ <19 0 &gpioa 5 0>, /* D13 */
+ <20 0 &gpiob 9 0>, /* D14 */
+ <21 0 &gpiob 8 0>; /* D15 */
+ };
+
+This specifies how Arduino pin references like ``<&arduino_header 11
+0>`` are converted to SOC gpio pin references like ``<&gpiob 4 0>``.
+
+In Zephyr GPIO specifiers generally have two parameters (indicated by
+``#gpio-cells = <2>``): the pin number and a set of flags. The low 6
+bits of the flags correspond to features that can be configured in
+devicetree. In some cases it's necessary to use a non-zero flag value
+to tell the driver how a particular pin behaves, as with:
+
+.. code-block:: none
+
+ drdy-gpios = <&arduino_header 11 GPIO_ACTIVE_LOW>;
+
+After preprocessing this becomes ``<&arduino_header 11 1>``. Normally
+the presence of such a flag would cause the map lookup to fail,
+because there is no map entry with a non-zero flags value. The
+``gpio-map-mask`` property specifies that, for lookup, all bits of the
+pin and all but the low 6 bits of the flags are used to identify the
+specifier. Then the ``gpio-map-pass-thru`` specifies that the low 6
+bits of the flags are copied over, so the SOC GPIO reference becomes
+``<&gpiob 4 1>`` as intended.
+
+See `nexus node`_ for more information about this capability.
+
.. include:: flash_partitions.inc