doc: devicetree: overhaul bindings guide
The binding-template.yaml file has grown organically into something that's out of control. It makes too many 'see above' and 'see below' references to be read comfortably, and we can't cross reference from YAML. There are also many example DTS and YAML fragments scattered about in comments, which cannot be syntax highlighted properly. Fix that by overhauling the documentation into bindings.rst in the DT guide. This will let us link to individual sections when answering questions, allows us to cross-reference and use '.. code-block::', etc. A couple of things need to go to other pages. Signed-off-by: Martí Bolívar <marti.bolivar@nordicsemi.no>
This commit is contained in:
parent
43086d3535
commit
4c2886c1b7
|
@ -174,6 +174,12 @@ number 0 or 1 in the case of booleans. For example:
|
|||
|
||||
DT_PROP(I2C1, status) /* expands to the string literal "okay" */
|
||||
|
||||
.. note::
|
||||
|
||||
Don't use DT_NODE_HAS_PROP() for boolean properties. Use DT_PROP() instead
|
||||
as shown above. It will expand to either 0 or 1 depending on if the property
|
||||
is present or absent.
|
||||
|
||||
Properties with type ``array``, ``uint8-array``, and ``string-array`` work
|
||||
similarly, except ``DT_PROP()`` expands to an array initializer in these cases.
|
||||
Here is an example devicetree fragment:
|
||||
|
|
|
@ -3,56 +3,105 @@
|
|||
Devicetree bindings
|
||||
###################
|
||||
|
||||
A devicetree on its own is only half the story for describing hardware. The
|
||||
devicetree format itself is relatively unstructured, and doesn't tell the
|
||||
:ref:`build system <build_overview>` which pieces of information in a
|
||||
particular devicetree are useful to :ref:`device drivers <device_model_api>` or
|
||||
:ref:`applications <application>`.
|
||||
A devicetree on its own is only half the story for describing hardware, as it
|
||||
is a relatively unstructured format. *Devicetree bindings* provide the other
|
||||
half.
|
||||
|
||||
*Devicetree bindings* provide the other half of this information. Zephyr
|
||||
A devicetree binding declares requirements on the contents of nodes, and
|
||||
provides semantic information about the contents of valid nodes. Zephyr
|
||||
devicetree bindings are YAML files in a custom format (Zephyr does not use the
|
||||
dt-schema tools used by the Linux kernel). With one exception in
|
||||
:ref:`dt-inferred-bindings` the build system uses bindings when generating
|
||||
code for :ref:`dt-from-c`.
|
||||
dt-schema tools used by the Linux kernel).
|
||||
|
||||
This page introduces bindings, describes what they do, notes where they are
|
||||
found, and explains their data format.
|
||||
|
||||
.. note::
|
||||
|
||||
See the :ref:`devicetree_binding_index` for information on existing
|
||||
bindings.
|
||||
See the :ref:`devicetree_binding_index` for reference information on
|
||||
bindings built in to Zephyr.
|
||||
|
||||
.. contents::
|
||||
:local:
|
||||
:depth: 2
|
||||
|
||||
.. _dt-binding-compat:
|
||||
|
||||
Mapping nodes to bindings
|
||||
*************************
|
||||
Introduction
|
||||
************
|
||||
|
||||
During the :ref:`build_configuration_phase`, the build system tries to map each
|
||||
node in the devicetree to a binding file. When this succeeds, the build system
|
||||
uses the information in the binding file when generating macros for the node.
|
||||
Devicetree nodes are matched to bindings using their :ref:`compatible
|
||||
properties <dt-important-props>`.
|
||||
|
||||
Nodes are mapped to binding files by their :ref:`compatible properties
|
||||
<dt-syntax>`. Take the following node as an example:
|
||||
During the :ref:`build_configuration_phase`, the build system tries to match
|
||||
each node in the devicetree to a binding file. When this succeeds, the build
|
||||
system uses the information in the binding file both when validating the node's
|
||||
contents and when generating macros for the node.
|
||||
|
||||
.. _dt-bindings-simple-example:
|
||||
|
||||
A simple example
|
||||
================
|
||||
|
||||
Here is an example devicetree node:
|
||||
|
||||
.. code-block:: DTS
|
||||
|
||||
/* Node in a DTS file */
|
||||
bar-device {
|
||||
compatible = "foo-company,bar-device";
|
||||
/* ... */
|
||||
num-foos = <3>;
|
||||
};
|
||||
|
||||
The build system will try to map the ``bar-device`` node to a YAML binding with
|
||||
this ``compatible:`` line:
|
||||
Here is a minimal binding file which matches the node:
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
# A YAML binding matching the node
|
||||
|
||||
compatible: "foo-company,bar-device"
|
||||
|
||||
Built-in bindings are stored in :zephyr_file:`dts/bindings/`. Binding file
|
||||
names usually match their ``compatible:`` lines, so the above binding would be
|
||||
named :file:`foo-company,bar-device.yaml`.
|
||||
properties:
|
||||
num-foos:
|
||||
type: int
|
||||
required: true
|
||||
|
||||
The build system matches the ``bar-device`` node to its YAML binding because
|
||||
the node's ``compatible`` property matches the binding's ``compatible:`` line.
|
||||
|
||||
What the build system does with bindings
|
||||
========================================
|
||||
|
||||
The build system uses bindings both to validate devicetree nodes and to convert
|
||||
the devicetree's contents into the generated :ref:`devicetree_unfixed.h
|
||||
<dt-outputs>` header file.
|
||||
|
||||
For example, the build system would use the above binding to check that the
|
||||
required ``num-foos`` property is present in the ``bar-device`` node, and that
|
||||
its value, ``<3>``, has the correct type.
|
||||
|
||||
The build system will then generate a macro for the ``bar-device`` node's
|
||||
``num-foos`` property, which will expand to the integer literal ``3``. This
|
||||
macro lets you get the value of the property in C code using the API which is
|
||||
discussed later in this guide in :ref:`dt-from-c`.
|
||||
|
||||
For another example, the following node would cause a build error, because it
|
||||
has no ``num-foos`` property, and this property is marked required in the
|
||||
binding:
|
||||
|
||||
.. code-block:: DTS
|
||||
|
||||
bad-node {
|
||||
compatible = "foo-company,bar-device";
|
||||
};
|
||||
|
||||
Other ways nodes are matched to bindings
|
||||
========================================
|
||||
|
||||
If a node has more than one string in its ``compatible`` property, the build
|
||||
system looks for compatible bindings in the listed order and uses the first
|
||||
match. Take this node as an example:
|
||||
match.
|
||||
|
||||
Take this node as an example:
|
||||
|
||||
.. code-block:: DTS
|
||||
|
||||
|
@ -60,26 +109,823 @@ match. Take this node as an example:
|
|||
compatible = "foo-company,baz-device", "generic-baz-device";
|
||||
};
|
||||
|
||||
The ``baz-device`` node would get mapped to the binding for compatible
|
||||
``"generic-baz-device"`` if the build system can't find a binding for
|
||||
``"foo-company,baz-device"``.
|
||||
The ``baz-device`` node would get matched to a binding with a ``compatible:
|
||||
"generic-baz-device"`` line if the build system can't find a binding with a
|
||||
``compatible: "foo-company,baz-device"`` line.
|
||||
|
||||
Nodes without compatible properties can be mapped to bindings associated with
|
||||
their parent nodes. For an example, see the ``pwmleds`` node in the bindings
|
||||
file format described below.
|
||||
Nodes without compatible properties can be matched to bindings associated with
|
||||
their parent nodes. These are called "child bindings". If a node describes
|
||||
hardware on a bus, like I2C or SPI, then the bus type is also taken into
|
||||
account when matching nodes to bindings. (The :ref:`dt-bindings-file-syntax`
|
||||
section below describes how to write child bindings and bus-specific bindings.)
|
||||
|
||||
If a node describes hardware on a bus, like I2C or SPI, then the bus type is
|
||||
also taken into account when mapping nodes to bindings. See the comments near
|
||||
``on-bus:`` in the bindings syntax for details.
|
||||
Some special nodes without ``compatible`` properties are matched to
|
||||
:ref:`dt-inferred-bindings`. For these nodes, the build system generates macros
|
||||
based on the properties in the final devicetree.
|
||||
|
||||
.. _dt-where-bindings-are-located:
|
||||
|
||||
Where bindings are located
|
||||
==========================
|
||||
|
||||
Binding file names usually match their ``compatible:`` lines. For example, the
|
||||
above example binding would be named :file:`foo-company,bar-device.yaml` by
|
||||
convention.
|
||||
|
||||
The build system looks for bindings in :file:`dts/bindings`
|
||||
subdirectories of the following places:
|
||||
|
||||
- the zephyr repository
|
||||
- your :ref:`application source directory <application>`
|
||||
- your :ref:`board directory <board_porting_guide>`
|
||||
- any directories in the :ref:`DTS_ROOT <dts_root>` CMake variable
|
||||
- any :ref:`module <modules>` that defines a ``dts_root`` in its
|
||||
:ref:`modules_build_settings`
|
||||
|
||||
The build system will consider any YAML file in any of these, including
|
||||
in any subdirectories, when matching nodes to bindings.
|
||||
|
||||
.. warning::
|
||||
|
||||
The binding files must be located somewhere inside the :file:`dts/bindings`
|
||||
subdirectory of the above places.
|
||||
|
||||
For example, if :file:`my-app` is your application directory, then you must
|
||||
place application-specific bindings inside :file:`my-app/dts/bindings`. So
|
||||
:file:`my-app/dts/bindings/serial/my-company,my-serial-port.yaml` would be
|
||||
found, but :file:`my-app/my-company,my-serial-port.yaml` would be ignored.
|
||||
|
||||
.. _dt-bindings-file-syntax:
|
||||
|
||||
Bindings file syntax
|
||||
********************
|
||||
|
||||
Below is a template that shows the Zephyr bindings file syntax. It is stored in
|
||||
:zephyr_file:`dts/binding-template.yaml`.
|
||||
Zephyr bindings files are YAML files. The top-level value in the file is a
|
||||
mapping. A :ref:`simple example <dt-bindings-simple-example>` is given above.
|
||||
|
||||
.. literalinclude:: ../../../dts/binding-template.yaml
|
||||
:language: yaml
|
||||
The top-level keys in the mapping look like this:
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
# A high level description of the device the binding applies to:
|
||||
description: |
|
||||
This is the Vendomatic company's foo-device.
|
||||
|
||||
Descriptions which span multiple lines (like this) are OK,
|
||||
and are encouraged for complex bindings.
|
||||
|
||||
See https://yaml-multiline.info/ for formatting help.
|
||||
|
||||
# You can include definitions from other bindings using this syntax:
|
||||
include: other.yaml
|
||||
|
||||
# Used to match nodes to this binding as discussed above:
|
||||
compatible: "manufacturer,foo-device"
|
||||
|
||||
properties:
|
||||
# Requirements for and descriptions of the properties that this
|
||||
# binding's nodes need to satisfy go here.
|
||||
|
||||
child-binding:
|
||||
# You can constrain the children of the nodes matching this binding
|
||||
# using this key.
|
||||
|
||||
# If the node describes bus hardware, like an SPI bus controller
|
||||
# on an SoC, use 'bus:' to say which one, like this:
|
||||
bus: spi
|
||||
|
||||
# If the node instead appears as a device on a bus, like an external
|
||||
# SPI memory chip, use 'on-bus:' to say what type of bus, like this.
|
||||
# Like 'compatible', this key also influences the way nodes match
|
||||
# bindings.
|
||||
on-bus: spi
|
||||
|
||||
foo-cells:
|
||||
# "Specifier" cell names for the 'foo' domain go here; example 'foo'
|
||||
# values are 'gpio', 'pwm', and 'dma'. See below for more information.
|
||||
|
||||
The following sections describe these keys in more detail:
|
||||
|
||||
- :ref:`dt-bindings-description`
|
||||
- :ref:`dt-bindings-compatible`
|
||||
- :ref:`dt-bindings-properties`
|
||||
- :ref:`dt-bindings-child`
|
||||
- :ref:`dt-bindings-bus`
|
||||
- :ref:`dt-bindings-on-bus`
|
||||
- :ref:`dt-bindings-cells`
|
||||
- :ref:`dt-bindings-include`
|
||||
|
||||
The ``include:`` key usually appears early in the binding file, but it is
|
||||
documented last here because you need to know how the other keys work before
|
||||
understanding ``include:``.
|
||||
|
||||
.. _dt-bindings-description:
|
||||
|
||||
Description
|
||||
===========
|
||||
|
||||
A free-form description of node hardware goes here. You can put links to
|
||||
datasheets or example nodes or properties as well.
|
||||
|
||||
.. _dt-bindings-compatible:
|
||||
|
||||
Compatible
|
||||
==========
|
||||
|
||||
This key is used to match nodes to this binding as described above.
|
||||
It should look like this in a binding file:
|
||||
|
||||
.. code-block:: YAML
|
||||
|
||||
# Note the comma-separated vendor prefix and device name
|
||||
compatible: "manufacturer,device"
|
||||
|
||||
This devicetree node would match the above binding:
|
||||
|
||||
.. code-block:: DTS
|
||||
|
||||
device {
|
||||
compatible = "manufacturer,device";
|
||||
};
|
||||
|
||||
Assuming no binding has ``compatible: "manufacturer,device-v2"``, it would also
|
||||
match this node:
|
||||
|
||||
.. code-block:: DTS
|
||||
|
||||
device-2 {
|
||||
compatible = "manufacturer,device-v2", "manufacturer,device";
|
||||
};
|
||||
|
||||
Each node's ``compatible`` property is tried in order. The first matching
|
||||
binding is used. The :ref:`on-bus: <dt-bindings-on-bus>` key can be used to
|
||||
refine the search.
|
||||
|
||||
If more than one binding for a compatible is found, an error is raised.
|
||||
|
||||
The ``manufacturer`` prefix identifies the device vendor. See
|
||||
:zephyr_file:`dts/bindings/vendor-prefixes.txt` for a list of accepted vendor
|
||||
prefixes. The ``device`` part is usually from the datasheet.
|
||||
|
||||
Some bindings apply to a generic class of devices which do not have a specific
|
||||
vendor. In these cases, there is no vendor prefix. One example is the
|
||||
:dtcompatible:`gpio-leds` compatible which is commonly used to describe board
|
||||
LEDs connected to GPIOs.
|
||||
|
||||
If more than one binding for a compatible is found, an error is raised.
|
||||
|
||||
.. _dt-bindings-properties:
|
||||
|
||||
Properties
|
||||
==========
|
||||
|
||||
The ``properties:`` key describes the properties that nodes which match the
|
||||
binding can contain.
|
||||
|
||||
For example, a binding for a UART peripheral might look something like this:
|
||||
|
||||
.. code-block:: YAML
|
||||
|
||||
compatible: "manufacturer,serial"
|
||||
|
||||
properties:
|
||||
reg:
|
||||
type: array
|
||||
description: UART peripheral MMIO register space
|
||||
required: true
|
||||
current-speed:
|
||||
type: int
|
||||
description: current baud rate
|
||||
required: true
|
||||
label:
|
||||
type: string
|
||||
description: human-readable name
|
||||
required: false
|
||||
|
||||
The properties in the following node would be validated by the above binding:
|
||||
|
||||
.. code-block:: DTS
|
||||
|
||||
my-serial@deadbeef {
|
||||
compatible = "manufacturer,serial";
|
||||
reg = <0xdeadbeef 0x1000>;
|
||||
current-speed = <115200>;
|
||||
label = "UART_0";
|
||||
};
|
||||
|
||||
This is used to check that required properties appear, and to control the
|
||||
format of output generated for them.
|
||||
|
||||
Except for some special properties, like ``reg``, whose meaning is defined by
|
||||
the devicetree specification itself, only properties listed in the
|
||||
``properties:`` key will have generated macros.
|
||||
|
||||
.. _dt-bindings-example-properties:
|
||||
|
||||
Example property definitions
|
||||
++++++++++++++++++++++++++++
|
||||
|
||||
Here are some more examples.
|
||||
|
||||
.. code-block:: YAML
|
||||
|
||||
properties:
|
||||
# Describes a property like 'current-speed = <115200>;'. We pretend that
|
||||
# it's obligatory for the example node and set 'required: true'.
|
||||
current-speed:
|
||||
type: int
|
||||
required: true
|
||||
description: Initial baud rate for bar-device
|
||||
|
||||
# Describes an optional property like 'keys = "foo", "bar";'
|
||||
keys:
|
||||
type: string-array
|
||||
required: false
|
||||
description: Keys for bar-device
|
||||
|
||||
# Describes an optional property like 'maximum-speed = "full-speed";'
|
||||
# the enum specifies known values that the string property may take
|
||||
maximum-speed:
|
||||
type: string
|
||||
required: false
|
||||
description: Configures USB controllers to work up to a specific speed.
|
||||
enum:
|
||||
- "low-speed"
|
||||
- "full-speed"
|
||||
- "high-speed"
|
||||
- "super-speed"
|
||||
|
||||
# Describes an optional property like 'resolution = <16>;'
|
||||
# the enum specifies known values that the int property may take
|
||||
resolution:
|
||||
type: int
|
||||
required: false
|
||||
enum:
|
||||
- 8
|
||||
- 16
|
||||
- 24
|
||||
- 32
|
||||
|
||||
# Describes a required property '#address-cells = <1>'; the const
|
||||
# specifies that the value for the property is expected to be the value 1
|
||||
"#address-cells":
|
||||
type: int
|
||||
required: true
|
||||
const: 1
|
||||
|
||||
int-with-default:
|
||||
type: int
|
||||
required: false
|
||||
default: 123
|
||||
description: Value for int register, default is power-up configuration.
|
||||
|
||||
array-with-default:
|
||||
type: array
|
||||
required: false
|
||||
default: [1, 2, 3] # Same as 'array-with-default = <1 2 3>'
|
||||
|
||||
string-with-default:
|
||||
type: string
|
||||
required: false
|
||||
default: "foo"
|
||||
|
||||
string-array-with-default:
|
||||
type: string-array
|
||||
required: false
|
||||
default: ["foo", "bar"] # Same as 'string-array-with-default = "foo", "bar"'
|
||||
|
||||
uint8-array-with-default:
|
||||
type: uint8-array
|
||||
required: false
|
||||
default: [0x12, 0x34] # Same as 'uint8-array-with-default = [12 34]'
|
||||
|
||||
Property entry syntax
|
||||
+++++++++++++++++++++
|
||||
|
||||
As shown by the above examples, each property entry in a binding looks like
|
||||
this:
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
<property name>:
|
||||
required: <true | false>
|
||||
type: <string | int | boolean | array | uint8-array | string-array |
|
||||
phandle | phandles | phandle-array | path | compound>
|
||||
deprecated: <true | false>
|
||||
default: <default>
|
||||
description: <description of the property>
|
||||
enum:
|
||||
- <item1>
|
||||
- <item2>
|
||||
...
|
||||
- <itemN>
|
||||
const: <string | int>
|
||||
|
||||
Required properties
|
||||
+++++++++++++++++++
|
||||
|
||||
If a node matches a binding but is missing any property which the binding
|
||||
defines with ``required: true``, the build fails.
|
||||
|
||||
Property types
|
||||
++++++++++++++
|
||||
|
||||
The type of a property constrains its values.
|
||||
The following types are available. See :ref:`dt-writing-property-values`
|
||||
for more details about writing values of each type in a DTS file.
|
||||
|
||||
.. list-table::
|
||||
:header-rows: 1
|
||||
:widths: 1 3 2
|
||||
|
||||
* - Type
|
||||
- Description
|
||||
- Example in DTS
|
||||
|
||||
* - ``string``
|
||||
- exactly one string
|
||||
- ``label = "UART_0";``
|
||||
|
||||
* - ``int``
|
||||
- exactly one 32-bit value (cell)
|
||||
- ``current-speed = <115200>;``
|
||||
|
||||
* - ``boolean``
|
||||
- flags that don't take a value when true, and are absent if false
|
||||
- ``hw-flow-control;``
|
||||
|
||||
* - ``array``
|
||||
- zero or more 32-bit values (cells)
|
||||
- ``offsets = <0x100 0x200 0x300>;``
|
||||
|
||||
* - ``uint8-array``
|
||||
- zero or more bytes, in hex ('bytestring' in the Devicetree specification)
|
||||
- ``local-mac-address = [de ad be ef 12 34];``
|
||||
|
||||
* - ``string-array``
|
||||
- zero or more strings
|
||||
- ``dma-names = "tx", "rx";``
|
||||
|
||||
* - ``phandle``
|
||||
- exactly one phandle
|
||||
- ``interrupt-parent = <&gic>;``
|
||||
|
||||
* - ``phandles``
|
||||
- zero or more phandles
|
||||
- ``pinctrl-0 = <&usart2_tx_pd5 &usart2_rx_pd6>;``
|
||||
|
||||
* - ``phandle-array``
|
||||
- a list of phandles and 32-bit cells (usually specifiers)
|
||||
- ``dmas = <&dma0 2>, <&dma0 3>;``
|
||||
|
||||
* - ``path``
|
||||
- a path to a node as a phandle path reference or path string
|
||||
- ``zephyr,bt-c2h-uart = &uart0;`` or
|
||||
``foo = "/path/to/some/node";``
|
||||
|
||||
* - ``compound``
|
||||
- a catch-all for more complex types (no macros will be generated)
|
||||
- ``foo = <&label>, [01 02];``
|
||||
|
||||
Deprecated properties
|
||||
+++++++++++++++++++++
|
||||
|
||||
A property with ``deprecated: true`` indicates to both the user and the tooling
|
||||
that the property is meant to be phased out.
|
||||
|
||||
The tooling will report a warning if the devicetree includes the property that
|
||||
is flagged as deprecated. (This warning is upgraded to an error in the
|
||||
:ref:`twister_script` for upstream pull requests.)
|
||||
|
||||
Default values for properties
|
||||
+++++++++++++++++++++++++++++
|
||||
|
||||
The optional ``default:`` setting gives a value that will be used if the
|
||||
property is missing from the devicetree node.
|
||||
|
||||
For example, with this binding fragment:
|
||||
|
||||
.. code-block:: YAML
|
||||
|
||||
properties:
|
||||
foo:
|
||||
type: int
|
||||
default: 3
|
||||
|
||||
If property ``foo`` is missing in a matching node, then the output will be as
|
||||
if ``foo = <3>;`` had appeared in the DTS (except YAML data types are used for
|
||||
the default value).
|
||||
|
||||
Note that it only makes sense to combine ``default:`` with ``required: false``.
|
||||
Combining it with ``required: true`` will raise an error.
|
||||
|
||||
There is a risk in using ``default:`` when the value in the binding may be
|
||||
incorrect for a particular board or hardware configuration. For example,
|
||||
defaulting the capacity of the connected power cell in a charging IC binding
|
||||
is likely to be incorrect. For such properties it's better to make the
|
||||
property ``required: true``, forcing the devicetree maintainer into an explicit
|
||||
and witting choice.
|
||||
|
||||
Driver developers should use their best judgment as to whether a value can be
|
||||
safely defaulted. Candidates for default values include:
|
||||
|
||||
- delays that would be different only under unusual conditions
|
||||
(such as intervening hardware)
|
||||
- configuration for devices that have a standard initial configuration (such as
|
||||
a USB audio headset)
|
||||
- defaults which match the vendor-specified power-on reset value
|
||||
(as long as they are independent from other properties)
|
||||
|
||||
Power-on reset values may be used for defaults as long as they're independent.
|
||||
If changing one property would require changing another to create a consistent
|
||||
configuration, then those properties should be made required.
|
||||
|
||||
In any case where ``default:`` is used, the property documentation should
|
||||
explain why the value was selected and any conditions that would make it
|
||||
necessary to provide a different value. (This is mandatory for built-in
|
||||
bindings.)
|
||||
|
||||
See :ref:`dt-bindings-example-properties` for examples. Putting ``default:`` on
|
||||
any property type besides those used in the examples will raise an error.
|
||||
|
||||
Enum values
|
||||
+++++++++++
|
||||
|
||||
The ``enum:`` line is followed by a list of values the property may contain. If
|
||||
a property value in DTS is not in the ``enum:`` list in the binding, an error
|
||||
is raised. See :ref:`dt-bindings-example-properties` for examples.
|
||||
|
||||
Const
|
||||
+++++
|
||||
|
||||
This specifies a constant value the property must take. It is mainly useful for
|
||||
constraining the values of common properties for a particular piece of
|
||||
hardware.
|
||||
|
||||
.. _dt-bindings-child:
|
||||
|
||||
Child-binding
|
||||
=============
|
||||
|
||||
``child-binding`` can be used when a node has children that all share the same
|
||||
properties. Each child gets the contents of ``child-binding`` as its binding,
|
||||
though an explicit ``compatible = ...`` on the child node takes precedence, if
|
||||
a binding is found for it.
|
||||
|
||||
Consider a binding for a PWM LED node like this one, where the child nodes are
|
||||
required to have a ``pwms`` property:
|
||||
|
||||
.. code-block:: DTS
|
||||
|
||||
pwmleds {
|
||||
compatible = "pwm-leds";
|
||||
|
||||
red_pwm_led {
|
||||
pwms = <&pwm3 4 15625000>;
|
||||
};
|
||||
green_pwm_led {
|
||||
pwms = <&pwm3 0 15625000>;
|
||||
};
|
||||
/* ... */
|
||||
};
|
||||
|
||||
The binding would look like this:
|
||||
|
||||
.. code-block:: YAML
|
||||
|
||||
compatible: "pwm-leds"
|
||||
|
||||
child-binding:
|
||||
description: LED that uses PWM
|
||||
|
||||
properties:
|
||||
pwms:
|
||||
type: phandle-array
|
||||
required: true
|
||||
|
||||
``child-binding`` also works recursively. For example, this binding:
|
||||
|
||||
.. code-block:: YAML
|
||||
|
||||
compatible: foo
|
||||
|
||||
child-binding:
|
||||
child-binding:
|
||||
properties:
|
||||
my-property:
|
||||
type: int
|
||||
required: true
|
||||
|
||||
will apply to the ``grandchild`` node in this DTS:
|
||||
|
||||
.. code-block:: DTS
|
||||
|
||||
parent {
|
||||
compatible = "foo";
|
||||
child {
|
||||
grandchild {
|
||||
my-property = <123>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
.. _dt-bindings-bus:
|
||||
|
||||
Bus
|
||||
===
|
||||
|
||||
If the node is a bus controller, use ``bus:`` in the binding to say what type
|
||||
of bus. For example, a binding for a SPI peripheral on an SoC would look like
|
||||
this:
|
||||
|
||||
.. code-block:: YAML
|
||||
|
||||
compatible: "manufacturer,spi-peripheral"
|
||||
bus: spi
|
||||
# ...
|
||||
|
||||
The presence of this key in the binding informs the build system that the
|
||||
children of any node matching this binding appear on this type of bus.
|
||||
|
||||
This in turn influences the way ``on-bus:`` is used to match bindings for the
|
||||
child nodes.
|
||||
|
||||
.. _dt-bindings-on-bus:
|
||||
|
||||
On-bus
|
||||
======
|
||||
|
||||
If the node appears as a device on a bus, use ``on-bus:`` in the binding to say
|
||||
what type of bus.
|
||||
|
||||
For example, a binding for an external SPI memory chip should include this line:
|
||||
|
||||
.. code-block:: YAML
|
||||
|
||||
on-bus: spi
|
||||
|
||||
And a binding for an I2C based temperature sensor should include this line:
|
||||
|
||||
.. code-block:: YAML
|
||||
|
||||
on-bus: i2c
|
||||
|
||||
When looking for a binding for a node, the build system checks if the binding
|
||||
for the parent node contains ``bus: <bus type>``. If it does, then only
|
||||
bindings with a matching ``on-bus: <bus type>`` and bindings without an
|
||||
explicit ``on-bus`` are considered. Bindings with an explicit ``on-bus: <bus
|
||||
type>`` are searched for first, before bindings without an explicit ``on-bus``.
|
||||
The search repeats for each item in the node's ``compatible`` property, in
|
||||
order.
|
||||
|
||||
This feature allows the same device to have different bindings depending on
|
||||
what bus it appears on. For example, consider a sensor device with compatible
|
||||
``manufacturer,sensor`` which can be used via either I2C or SPI.
|
||||
|
||||
The sensor node may therefore appear in the devicetree as a child node of
|
||||
either an SPI or an I2C controller, like this:
|
||||
|
||||
.. code-block:: DTS
|
||||
|
||||
spi-bus@... {
|
||||
/* ... some compatible with 'bus: spi', etc. ... */
|
||||
|
||||
sensor@0 {
|
||||
compatible = "manufacturer,sensor";
|
||||
reg = <0>;
|
||||
/* ... */
|
||||
};
|
||||
};
|
||||
|
||||
i2c-bus@... {
|
||||
/* ... some compatible with 'bus: i2c', etc. ... */
|
||||
|
||||
sensor@79 {
|
||||
compatible = "manufacturer,sensor";
|
||||
reg = <79>;
|
||||
/* ... */
|
||||
};
|
||||
};
|
||||
|
||||
You can write two separate binding files which match these individual sensor
|
||||
nodes, even though they have the same compatible:
|
||||
|
||||
.. code-block:: YAML
|
||||
|
||||
# manufacturer,sensor-spi.yaml, which matches sensor@0 on the SPI bus:
|
||||
compatible: "manufacturer,sensor"
|
||||
on-bus: spi
|
||||
|
||||
# manufacturer,sensor-i2c.yaml, which matches sensor@79 on the I2C bus:
|
||||
compatible: "manufacturer,sensor"
|
||||
properties:
|
||||
uses-clock-stretching:
|
||||
type: boolean
|
||||
required: false
|
||||
on-bus: i2c
|
||||
|
||||
Only ``sensor@79`` can have a ``use-clock-stretching`` property. The
|
||||
bus-sensitive logic ignores :file:`manufacturer,sensor-i2c.yaml` when searching
|
||||
for a binding for ``sensor@0``.
|
||||
|
||||
.. _dt-bindings-cells:
|
||||
|
||||
Specifier cell names (\*-cells)
|
||||
===============================
|
||||
|
||||
Specifier cells are usually used with ``phandle-array`` type properties briefly
|
||||
introduced above.
|
||||
|
||||
To understand the purpose of ``*-cells``, assume that some node has the
|
||||
following ``pwms`` property with type ``phandle-array``:
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
my-device {
|
||||
pwms = <&pwm0 1 2>, <&pwm3 4>;
|
||||
};
|
||||
|
||||
The tooling strips the final ``s`` from the property name of such properties,
|
||||
resulting in ``pwm``. Then the value of the ``#pwm-cells`` property is
|
||||
looked up in each of the PWM controller nodes ``pwm0`` and ``pwm3``, like so:
|
||||
|
||||
.. code-block:: DTS
|
||||
|
||||
pwm0: pwm@... {
|
||||
compatible = "foo,pwm";
|
||||
#pwm-cells = <2>;
|
||||
};
|
||||
|
||||
pwm3: pwm@... {
|
||||
compatible = "bar,pwm";
|
||||
#pwm-cells = <1>;
|
||||
};
|
||||
|
||||
The ``&pwm0 1 2`` part of the property value has two cells, ``1`` and ``2``,
|
||||
which matches ``#pwm-cells = <2>;``, so these cells are considered the
|
||||
*specifier* associated with ``pwm0`` in the phandle array.
|
||||
|
||||
Similarly, the cell ``4`` is the specifier associated with ``pwm3``.
|
||||
|
||||
The number of PWM cells in the specifiers in ``pwms`` must match the
|
||||
``#pwm-cells`` values, as shown above. If there is a mismatch, an error is
|
||||
raised. For example, this node would result in an error:
|
||||
|
||||
.. code-block:: DTS
|
||||
|
||||
my-bad-device {
|
||||
/* wrong: 2 cells given in the specifier, but #pwm-cells is 1 in pwm3. */
|
||||
pwms = <&pwm3 5 6>;
|
||||
};
|
||||
|
||||
The binding for each PWM controller must also have a ``*-cells`` key, in this
|
||||
case ``pwm-cells``, giving names to the cells in each specifier:
|
||||
|
||||
.. code-block:: YAML
|
||||
|
||||
# foo,pwm.yaml
|
||||
compatible: "foo,pwm"
|
||||
...
|
||||
pwm-cells:
|
||||
- channel
|
||||
- period
|
||||
|
||||
# bar,pwm.yaml
|
||||
compatible: "bar,pwm"
|
||||
...
|
||||
pwm-cells:
|
||||
- period
|
||||
|
||||
A ``*-names`` (e.g. ``pwm-names``) property can appear on the node as well,
|
||||
giving a name to each entry.
|
||||
|
||||
This allows the cells in the specifiers to be accessed by name, e.g. using APIs
|
||||
like :c:macro:`DT_PWMS_CHANNEL_BY_NAME`.
|
||||
|
||||
Because other property names are derived from the name of the property by
|
||||
removing the final ``s``, the property name must end in ``s``. An error is
|
||||
raised if it doesn't.
|
||||
|
||||
``*-gpios`` properties are special-cased so that e.g. ``foo-gpios`` resolves to
|
||||
``#gpio-cells`` rather than ``#foo-gpio-cells``.
|
||||
|
||||
If the specifier is empty (e.g. ``#clock-cells = <0>``), then ``*-cells`` can
|
||||
either be omitted (recommended) or set to an empty array. Note that an empty
|
||||
array is specified as e.g. ``clock-cells: []`` in YAML.
|
||||
|
||||
All ``phandle-array`` type properties support mapping through ``*-map``
|
||||
properties, e.g. ``gpio-map``, as defined by the Devicetree specification.
|
||||
|
||||
.. _dt-bindings-include:
|
||||
|
||||
Include
|
||||
=======
|
||||
|
||||
Bindings can include other files, which can be used to share common property
|
||||
definitions between bindings. Use the ``include:`` key for this. Its value is
|
||||
either a string or a list.
|
||||
|
||||
In the simplest case, you can include another file by giving its name as a
|
||||
string, like this:
|
||||
|
||||
.. code-block:: YAML
|
||||
|
||||
include: foo.yaml
|
||||
|
||||
If any file named :file:`foo.yaml` is found (see
|
||||
:ref:`dt-where-bindings-are-located` for the search process), it will be
|
||||
included into this binding.
|
||||
|
||||
Included files are merged into bindings with a simple recursive dictionary
|
||||
merge. The build system will check that the resulting merged binding is
|
||||
well-formed.
|
||||
|
||||
It is an error if a key appears with a different value in a binding and in a
|
||||
file it includes, with one exception: a binding can have ``required: true`` for
|
||||
a :ref:`property definition <dt-bindings-properties>` for which the included
|
||||
file has ``required: false``. The ``required: true`` takes precedence, allowing
|
||||
bindings to strengthen requirements from included files.
|
||||
|
||||
Note that weakening requirements by having ``required: false`` where the
|
||||
included file has ``required: true`` is an error. This is meant to keep the
|
||||
organization clean.
|
||||
|
||||
The file :zephyr_file:`base.yaml <dts/bindings/base/base.yaml>` contains
|
||||
definitions for many common properties. When writing a new binding, it is a
|
||||
good idea to check if :file:`base.yaml` already defines some of the needed
|
||||
properties, and include it if it does.
|
||||
|
||||
Note that you can make a property defined in base.yaml obligatory like this,
|
||||
taking :ref:`reg <dt-important-props>` as an example:
|
||||
|
||||
.. code-block:: YAML
|
||||
|
||||
reg:
|
||||
required: true
|
||||
|
||||
This relies on the dictionary merge to fill in the other keys for ``reg``, like
|
||||
``type``.
|
||||
|
||||
To include multiple files, you can use a list of strings:
|
||||
|
||||
.. code-block:: YAML
|
||||
|
||||
include:
|
||||
- foo.yaml
|
||||
- bar.yaml
|
||||
|
||||
This includes the files :file:`foo.yaml` and :file:`bar.yaml`. (You can
|
||||
write this list in a single line of YAML as ``include: [foo.yaml, bar.yaml]``.)
|
||||
|
||||
When including multiple files, any overlapping ``required`` keys on properties
|
||||
in the included files are ORed together. This makes sure that a ``required:
|
||||
true`` is always respected.
|
||||
|
||||
In some cases, you may want to include some property definitions from a file,
|
||||
but not all of them. In this case, ``include:`` should be a list, and you can
|
||||
filter out just the definitions you want by putting a mapping in the list, like
|
||||
this:
|
||||
|
||||
.. code-block:: YAML
|
||||
|
||||
include:
|
||||
- name: foo.yaml
|
||||
property-allowlist:
|
||||
- i-want-this-one
|
||||
- and-this-one
|
||||
- name: bar.yaml
|
||||
property-blocklist:
|
||||
- do-not-include-this-one
|
||||
- or-this-one
|
||||
|
||||
Each map element must have a ``name`` key which is the filename to include, and
|
||||
may have ``property-allowlist`` and ``property-blocklist`` keys that filter
|
||||
which properties are included.
|
||||
|
||||
You cannot have a single map element with both ``property-allowlist`` and
|
||||
``property-blocklist`` keys. A map element with neither ``property-allowlist``
|
||||
nor ``property-blocklist`` is valid; no additional filtering is done.
|
||||
|
||||
You can freely intermix strings and mappings in a single ``include:`` list:
|
||||
|
||||
.. code-block:: YAML
|
||||
|
||||
include:
|
||||
- foo.yaml
|
||||
- name: bar.yaml
|
||||
property-blocklist:
|
||||
- do-not-include-this-one
|
||||
- or-this-one
|
||||
|
||||
Finally, you can filter from a child binding like this:
|
||||
|
||||
.. code-block:: YAML
|
||||
|
||||
include:
|
||||
- name: bar.yaml
|
||||
child-binding:
|
||||
property-allowlist:
|
||||
- child-prop-to-allow
|
||||
|
||||
.. _dt-inferred-bindings:
|
||||
|
||||
|
|
|
@ -442,6 +442,18 @@ Additional notes on the above:
|
|||
values as *node identifiers*. Node identifiers are covered in more detail in
|
||||
:ref:`dt-from-c`.
|
||||
|
||||
- Array and similar type property values can be split several ``<>``
|
||||
blocks, like this:
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
foo = <1 2>, <3 4>; // Okay for 'type: array'
|
||||
foo = <&label1 &label2>, <&label3 &label4>; // Okay for 'type: phandles'
|
||||
foo = <&label1 1 2>, <&label2 3 4>; // Okay for 'type: phandle-array'
|
||||
|
||||
This is recommended for readability when possible if the value can be
|
||||
logically grouped into blocks of sub-values.
|
||||
|
||||
.. _dt-alias-chosen:
|
||||
|
||||
Aliases and chosen nodes
|
||||
|
|
|
@ -1,437 +1,10 @@
|
|||
description: |
|
||||
Free-form description of the device/node. Can have multiple
|
||||
lines/paragraphs.
|
||||
|
||||
See https://yaml-multiline.info/ for formatting help.
|
||||
|
||||
# Used to map nodes to bindings
|
||||
compatible: "manufacturer,device"
|
||||
|
||||
# The 'compatible' above would match this node:
|
||||
# The contents of this file have been moved to the documentation.
|
||||
#
|
||||
# device {
|
||||
# compatible = "manufacturer,device";
|
||||
# ...
|
||||
# };
|
||||
# See this page in the HTML documentation:
|
||||
#
|
||||
# Assuming no binding has 'compatible: "manufacturer,device-v2"', it would also
|
||||
# match this node:
|
||||
# User and Developer Guides >
|
||||
# Devicetree Guide >
|
||||
# Devicetree bindings
|
||||
#
|
||||
# device {
|
||||
# compatible = "manufacturer,device-v2", "manufacturer,device";
|
||||
# ...
|
||||
# };
|
||||
#
|
||||
# Strings in 'compatible' properties on nodes are tried from left to right, and
|
||||
# the first binding found is used.
|
||||
#
|
||||
# If more than one binding for a compatible is found, an error is raised.
|
||||
|
||||
# Bindings can include other files, which can be used to share common
|
||||
# definitions between bindings.
|
||||
#
|
||||
# Included files are merged into bindings with a simple recursive dictionary
|
||||
# merge. It is up to the binding author to make sure that the final merged
|
||||
# binding is well-formed, though it is checked by the code as well.
|
||||
#
|
||||
# It is an error if a key appears with a different value in a binding and in a
|
||||
# file it includes, with one exception: A binding can have 'required: true' for
|
||||
# some property for which the included file has 'required: false' (see the
|
||||
# description of 'properties' below). The 'required: true' from the binding
|
||||
# takes precedence, allowing bindings to strengthen requirements from included
|
||||
# files.
|
||||
#
|
||||
# Note that weakening requirements by having 'required: false' where the
|
||||
# included file has 'required: true' is an error. This is meant to keep the
|
||||
# organization clean.
|
||||
#
|
||||
# The file base.yaml contains definitions for many common properties. When
|
||||
# writing a new binding, it is a good idea to check if base.yaml already
|
||||
# defines some of the needed properties, and including it in that case. Note
|
||||
# that you can make a property defined in base.yaml obligatory like this
|
||||
# (taking 'reg' as an example):
|
||||
#
|
||||
# reg:
|
||||
# required: true
|
||||
#
|
||||
# This relies on the dictionary merge to fill in the other keys for 'reg', like
|
||||
# 'type'.
|
||||
#
|
||||
# When including multiple files, any overlapping 'required' keys on properties
|
||||
# in the included files are ORed together. This makes sure that a
|
||||
# 'required: true' is always respected.
|
||||
#
|
||||
# When 'include:' is a list, its elements can be either filenames as
|
||||
# strings, or maps. Each map element must have a 'name' key which is
|
||||
# the filename to include, and may have 'property-allowlist' and
|
||||
# 'property-blocklist' keys that filter which properties are included.
|
||||
# You can freely intermix strings and maps in a single 'include:' list.
|
||||
# You cannot have a single map element with both 'property-allowlist' and
|
||||
# 'property-blocklist' keys. A map element with neither 'property-allowlist'
|
||||
# nor 'property-blocklist' is valid; no additional filtering is done.
|
||||
include: other.yaml
|
||||
# To include multiple files:
|
||||
#
|
||||
# include:
|
||||
# - other1.yaml
|
||||
# - other2.yaml
|
||||
#
|
||||
# To filter the included properties:
|
||||
#
|
||||
# include:
|
||||
# - name: other1.yaml
|
||||
# property-allowlist:
|
||||
# - i-want-this-one
|
||||
# - and-this-one
|
||||
# - other2.yaml
|
||||
# property-blocklist:
|
||||
# - do-not-include-this-one
|
||||
# - or-this-one
|
||||
#
|
||||
# You can intermix these types of includes:
|
||||
#
|
||||
# include:
|
||||
# - other1.yaml
|
||||
# - other2.yaml
|
||||
# property-blocklist:
|
||||
# - do-not-include-this-one
|
||||
# - or-this-one
|
||||
#
|
||||
# And you can filter from a child binding like this:
|
||||
#
|
||||
# include:
|
||||
# - name: bar.yaml
|
||||
# child-binding:
|
||||
# property-allowlist:
|
||||
# - child-prop-to-allow
|
||||
|
||||
# If the node describes a bus, then the bus type should be given, like below
|
||||
bus: <string describing bus type, e.g. "i2c">
|
||||
|
||||
# If the node appears on a bus, then the bus type should be given, like below.
|
||||
#
|
||||
# When looking for a binding for a node, the code checks if the binding for the
|
||||
# parent node contains 'bus: <bus type>'. If it does, then only bindings with a
|
||||
# matching 'on-bus: <bus type>' and bindings without an explicit 'on-bus'
|
||||
# are considered. Bindings with an explicit 'on-bus: <bus type>' are looked
|
||||
# for first, and if none is found bindings without an explicit `on-bus` are
|
||||
# attempted. These two tests are done for each item in the `compatible` array
|
||||
# in the order specified. This allows the same type of device to have different
|
||||
# bindings depending on what bus it appears on.
|
||||
on-bus: <string describing bus type, e.g. "i2c">
|
||||
|
||||
# 'properties' describes properties on the node, e.g.
|
||||
#
|
||||
# reg = <1 2>;
|
||||
# current-speed = <115200>;
|
||||
# label = "foo";
|
||||
#
|
||||
# This is used to check that required properties appear, and to
|
||||
# control the format of output generated for them. Except for some
|
||||
# special-cased properties like 'reg', only properties listed here will
|
||||
# generate output.
|
||||
#
|
||||
# A typical property entry looks like this:
|
||||
#
|
||||
# <property name>:
|
||||
# deprecated: <true | false>
|
||||
# required: <true | false>
|
||||
# type: <string | int | boolean | array | uint8-array | string-array |
|
||||
# phandle | phandles | phandle-array | path | compound>
|
||||
# description: <description of the property>
|
||||
# enum:
|
||||
# - <item1>
|
||||
# - <item2>
|
||||
# ...
|
||||
# - <itemN>
|
||||
# const: <string | int>
|
||||
# default: <default>
|
||||
#
|
||||
# These types are available:
|
||||
#
|
||||
# - 'type: string' is for properties that are assigned a single string, like
|
||||
#
|
||||
# ident = "foo";
|
||||
#
|
||||
# - 'type: int' is for properties that are assigned a single 32-bit value,
|
||||
# like
|
||||
#
|
||||
# frequency = <100>;
|
||||
#
|
||||
# - 'type: boolean' is for properties used as flags that don't take a value,
|
||||
# like
|
||||
#
|
||||
# hw-flow-control;
|
||||
#
|
||||
# The macro generated for the property gets set to 1 if the property exists
|
||||
# on the node, and to 0 otherwise. When combined with 'required: true',
|
||||
# this type just forces the flag to appear on the node. The output will
|
||||
# always be 1 in that case.
|
||||
#
|
||||
# Warning: Since a macro is always generated for 'type: boolean'
|
||||
# properties, don't use #ifdef in tests. Do this instead:
|
||||
#
|
||||
# #if DT_SOME_BOOLEAN_PROP == 1
|
||||
#
|
||||
# - 'type: array' is for properties that are assigned zero or more 32-bit
|
||||
# values, like
|
||||
#
|
||||
# pin-config = <1 2 3>;
|
||||
#
|
||||
# - 'type: uint8-array' is for properties that are assigned zero or more
|
||||
# bytes with the [] syntax, like
|
||||
#
|
||||
# lookup-table = [89 AB CD EF];
|
||||
#
|
||||
# Each byte is given in hex.
|
||||
#
|
||||
# This type is called 'bytestring' in the Devicetree specification.
|
||||
#
|
||||
# - 'type: string-array' if for properties that are assigned zero or more
|
||||
# strings, like
|
||||
#
|
||||
# idents = "foo", "bar", "baz";
|
||||
#
|
||||
# - 'type: phandle' is for properties that are assigned a single phandle,
|
||||
# like
|
||||
#
|
||||
# foo = <&label>;
|
||||
#
|
||||
# - 'type: phandles' is for properties that are assigned zero or more
|
||||
# phandles, like
|
||||
#
|
||||
# foo = <&label1 &label2 ...>;
|
||||
#
|
||||
# - 'type: phandle-array' is for properties that take a list of phandles and
|
||||
# (possibly) 32-bit numbers, like
|
||||
#
|
||||
# pwms = <&ctrl-1 1 2 &ctrl-2 3 4>;
|
||||
#
|
||||
# This type requires that the property works in the standard way that
|
||||
# devicetree properties like pwms, clocks, *-gpios, and io-channels work.
|
||||
# Taking 'pwms' as an example, the final -s is stripped from the property
|
||||
# name, and #pwm-cells is looked up in the node for the controller
|
||||
# (&ctrl-1/&ctrl-2) to determine the number of data values after the
|
||||
# phandle. The binding for each controller must also have a *-cells key
|
||||
# (e.g. pwm-cells), giving names to data values. See below for an
|
||||
# explanation of *-cells.
|
||||
#
|
||||
# A *-names (e.g. pwm-names) property can appear on the node as well,
|
||||
# giving a name to each entry (the 'pwms' example above has two entries,
|
||||
# <&ctrl-1 1 2> and <&ctrl-2 3 4>).
|
||||
#
|
||||
# Because other property names are derived from the name of the property by
|
||||
# removing the final -s, the property name must end in -s. An error is
|
||||
# raised if it doesn't.
|
||||
#
|
||||
# *-gpios properties are special-cased so that e.g. foo-gpios resolves to
|
||||
# #gpio-cells rather than #foo-gpio-cells.
|
||||
#
|
||||
# All phandle-array properties support mapping through *-map properties,
|
||||
# e.g. gpio-map. See the devicetree spec.
|
||||
#
|
||||
# - 'type: path' is for properties that are assigned a path. Usually, this
|
||||
# would be done with a path reference:
|
||||
#
|
||||
# foo = &label;
|
||||
#
|
||||
# Plain strings are accepted too, and are verified to be a path to an
|
||||
# existing node:
|
||||
#
|
||||
# foo = "/path/to/some/node";
|
||||
#
|
||||
# - 'type: compound' is a catch-all for more complex types, e.g.
|
||||
#
|
||||
# foo = <&label>, [01 02];
|
||||
#
|
||||
# 'type: array' and the other array types also allow splitting the value into
|
||||
# several <> blocks, e.g. like this:
|
||||
#
|
||||
# foo = <1 2>, <3 4>; // Okay for 'type: array'
|
||||
# foo = <&label1 &label2>, <&label3 &label4>; // Okay for 'type: phandles'
|
||||
# foo = <&label1 1 2>, <&label2 3 4>; // Okay for 'type: phandle-array'
|
||||
# etc.
|
||||
#
|
||||
# A property with 'deprecated: True' indicates to both the user and the tooling
|
||||
# that the property is meant to be phased out. The tooling will report a
|
||||
# warning if the devicetree includes the property that is flagged as deprecated.
|
||||
# There will be no other impact to having 'deprecated: True' set on the property.
|
||||
#
|
||||
# The optional 'default:' setting gives a value that will be used if the
|
||||
# property is missing from the device tree node. If 'default: <default>' is
|
||||
# given for a property <prop> and <prop> is missing, then the output will be as
|
||||
# if '<prop> = <default>' had appeared (except YAML data types are used for the
|
||||
# default value).
|
||||
#
|
||||
# Note that it only makes sense to combine 'default:' with 'required: false'.
|
||||
# Combining it with 'required: true' will raise an error.
|
||||
#
|
||||
# There is a risk in using 'default:' when the value in the binding may be
|
||||
# incorrect for a particular board or hardware configuration. For example,
|
||||
# defaulting the capacity of the connected power cell in a charging IC binding
|
||||
# is likely to be incorrect. For such properties it's better to make the
|
||||
# property 'required: true', forcing the devicetree maintainer into an explicit
|
||||
# and witting choice.
|
||||
#
|
||||
# Driver developers should use their best judgment as to whether a value can be
|
||||
# safely defaulted. Candidates for default values include delays that would
|
||||
# different only under unusual conditions (such as intervening hardware), or
|
||||
# configuration for devices that have a standard initial configuration (such as
|
||||
# a USB audio headset).
|
||||
#
|
||||
# Properties may also be defaulted to the vendor-specified power-up default as
|
||||
# long as they're independent. If changing one property would require changing
|
||||
# another to create a consistent configuration then those properties should be
|
||||
# made required.
|
||||
#
|
||||
# In any case where 'default:' is used the property documentation should
|
||||
# explain why the value was selected and any conditions that would make it
|
||||
# necessary to provide a different value.
|
||||
#
|
||||
# See below for examples of 'default:'. Putting 'default:' on any property type
|
||||
# besides those used in the examples will raise an error.
|
||||
properties:
|
||||
# Describes a property like 'current-speed = <115200>;'. We pretend that
|
||||
# it's obligatory for the example node and set 'required: true'.
|
||||
current-speed:
|
||||
type: int
|
||||
required: true
|
||||
description: Initial baud rate for bar-device
|
||||
|
||||
# Describes an optional property like 'keys = "foo", "bar";'
|
||||
keys:
|
||||
type: string-array
|
||||
required: false
|
||||
description: Keys for bar-device
|
||||
|
||||
# Describes an optional property like 'maximum-speed = "full-speed";
|
||||
# the enum specifies known values that the string property may take
|
||||
maximum-speed:
|
||||
type: string
|
||||
required: false
|
||||
description: Configures USB controllers to work up to a specific speed.
|
||||
enum:
|
||||
- "low-speed"
|
||||
- "full-speed"
|
||||
- "high-speed"
|
||||
- "super-speed"
|
||||
|
||||
# Describes a required property '#address-cells = <1>'; the const
|
||||
# specifies that the value for the property is expected to be the value 1
|
||||
"#address-cells":
|
||||
type: int
|
||||
required: true
|
||||
const: 1
|
||||
|
||||
int-with-default:
|
||||
type: int
|
||||
required: false
|
||||
default: 123
|
||||
description: Value for int register, default is power-up configuration.
|
||||
|
||||
array-with-default:
|
||||
type: array
|
||||
required: false
|
||||
default: [1, 2, 3] # Same as 'array-with-default = <1 2 3>'
|
||||
|
||||
string-with-default:
|
||||
type: string
|
||||
required: false
|
||||
default: "foo"
|
||||
|
||||
string-array-with-default:
|
||||
type: string-array
|
||||
required: false
|
||||
default: ["foo", "bar"] # Same as 'string-array-with-default = "foo", "bar"'
|
||||
|
||||
uint8-array-with-default:
|
||||
type: uint8-array
|
||||
required: false
|
||||
default: [0x12, 0x34] # Same as 'uint8-array-with-default = [12 34]'
|
||||
|
||||
# 'child-binding' can be used when a node has children that all share the same
|
||||
# properties. Each child gets the contents of 'child-binding' as its binding
|
||||
# (though an explicit 'compatible = ...' on the child node takes precedence, if
|
||||
# a binding is found for it).
|
||||
#
|
||||
# The example below is for a binding for PWM LEDs, where the child nodes are
|
||||
# required to have a 'pwms' property. It corresponds to this .dts structure
|
||||
# (assuming the binding has 'compatible: "pwm-leds"'):
|
||||
#
|
||||
# pwmleds {
|
||||
# compatible = "pwm-leds";
|
||||
#
|
||||
# red_pwm_led {
|
||||
# pwms = <&pwm3 4 15625000>;
|
||||
# };
|
||||
# green_pwm_led {
|
||||
# pwms = <&pwm3 0 15625000>;
|
||||
# };
|
||||
# ...
|
||||
# };
|
||||
child-binding:
|
||||
description: LED that uses PWM
|
||||
|
||||
properties:
|
||||
pwms:
|
||||
type: phandle-array
|
||||
required: true
|
||||
|
||||
# 'child-binding' also works recursively. For example, the binding below would
|
||||
# provide a binding for the 'grandchild' node in this .dts (assuming
|
||||
# 'compatible: "foo"'):
|
||||
#
|
||||
# parent {
|
||||
# compatible = "foo";
|
||||
# child {
|
||||
# grandchild {
|
||||
# prop = <123>;
|
||||
# };
|
||||
# };
|
||||
# }
|
||||
child-binding:
|
||||
description: ...
|
||||
|
||||
...
|
||||
|
||||
child-binding:
|
||||
description: ...
|
||||
|
||||
properties:
|
||||
prop:
|
||||
type: int
|
||||
required: true
|
||||
|
||||
# If the binding describes an interrupt controller, GPIO controller, pinmux
|
||||
# device, or any other node referenced by other nodes via 'phandle-array'
|
||||
# properties, then *-cells should be given.
|
||||
#
|
||||
# To understand the purpose of *-cells, assume that some node has
|
||||
#
|
||||
# pwms = <&pwm-ctrl 1 2>;
|
||||
#
|
||||
# , where &pwm-ctrl refers to a node whose binding is this file.
|
||||
#
|
||||
# The <1 2> part of the property value is called a *specifier* (this
|
||||
# terminology is from the devicetree specification), and contains additional
|
||||
# data associated with the GPIO. Here, the specifier has two cells, and the
|
||||
# node pointed at by &gpio-ctrl is expected to have '#pwm-cells = <2>'.
|
||||
#
|
||||
# *-cells gives a name to each cell in the specifier. These names are used when
|
||||
# generating identifiers.
|
||||
#
|
||||
# In this example, assume that 1 refers to a pin and that 2 is a flag value.
|
||||
# This gives a *-cells assignment like below.
|
||||
pwm-cells:
|
||||
- channel # name of first cell
|
||||
- period # name of second cell
|
||||
|
||||
# If the specifier is empty (e.g. '#clock-cells = <0>'), then *-cells can
|
||||
# either be omitted (recommended) or set to an empty array. Note that an empty
|
||||
# array is specified as e.g. 'clock-cells: []' in YAML.
|
||||
|
||||
# As a special case, all *-gpio properties map to the key 'gpio-cells',
|
||||
# regardless of prefix
|
||||
gpio-cells:
|
||||
- pin
|
||||
- flags
|
||||
# For the latest version:
|
||||
# https://docs.zephyrproject.org/latest/guides/dts/bindings.html
|
||||
|
|
Loading…
Reference in a new issue