linux/Documentation/devicetree/bindings/example-schema.yaml
Rob Herring 00ce8a8000 dt-bindings: Add a writing DT schemas how-to and annotated example
Add a how-to doc on writing DT schema documentation. This gives a
description of each section and details on how to validate the DT schema
file. The DT schema are written using json-schema vocabulary in a YAML
encoded document. Using jsonschema gives us access to existing tooling.
A YAML encoding gives us something easy to edit. The example is
annotated to help explain what each section does.

This example is just the tip of the iceberg, but is it the part most
developers writing bindings will interact with. Backing all this up
are meta-schema (to validate the binding schemas), some DT core schema,
YAML encoded DT output with dtc, and a small number of python scripts to
run validation.

Cc: Mark Rutland <mark.rutland@arm.com>
Cc: devicetree@vger.kernel.org
Signed-off-by: Rob Herring <robh@kernel.org>
2018-12-13 09:41:49 -06:00

171 lines
5.4 KiB
YAML

# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
# Copyright 2018 Linaro Ltd.
%YAML 1.2
---
# All the top-level keys are standard json-schema keywords except for
# 'maintainers' and 'select'
# $id is a unique idenifier based on the filename. There may or may not be a
# file present at the URL.
$id: "http://devicetree.org/schemas/example-schema.yaml#"
# $schema is the meta-schema this schema should be validated with.
$schema: "http://devicetree.org/meta-schemas/core.yaml#"
title: An example schema annotated with jsonschema details
maintainers:
- Rob Herring <robh@kernel.org>
description: |
A more detailed multi-line description of the binding.
Details about the hardware device and any links to datasheets can go here.
Literal blocks are marked with the '|' at the beginning. The end is marked by
indentation less than the first line of the literal block. Lines also cannot
begin with a tab character.
select: false
# 'select' is a schema applied to a DT node to determine if this binding
# schema should be applied to the node. It is optional and by default the
# possible compatible strings are extracted and used to match.
# In this case, a 'false' schema will never match.
properties:
# A dictionary of DT properties for this binding schema
compatible:
# More complicated schema can use oneOf (XOR), anyOf (OR), or allOf (AND)
# to handle different conditions.
# In this case, it's needed to handle a variable number of values as there
# isn't another way to express a constraint of the last string value.
# The boolean schema must be a list of schemas.
oneOf:
- items:
# items is a list of possible values for the property. The number of
# values is determined by the number of elements in the list.
# Order in lists is significant, order in dicts is not
# Must be one of the 1st enums followed by the 2nd enum
#
# Each element in items should be 'enum' or 'const'
- enum:
- vendor,soc4-ip
- vendor,soc3-ip
- vendor,soc2-ip
- enum:
- vendor,soc1-ip
# additionalItems being false is implied
# minItems/maxItems equal to 2 is implied
- items:
# 'const' is just a special case of an enum with a single possible value
- const: vendor,soc1-ip
reg:
# The core schema already checks that reg values are numbers, so device
# specific schema don't need to do those checks.
# The description of each element defines the order and implicitly defines
# the number of reg entries.
items:
- description: core registers
- description: aux registers
# minItems/maxItems equal to 2 is implied
reg-names:
# The core schema enforces this is a string array
items:
- const: core
- const: aux
clocks:
# Cases that have only a single entry just need to express that with maxItems
maxItems: 1
description: bus clock
clock-names:
items:
- const: bus
interrupts:
# Either 1 or 2 interrupts can be present
minItems: 1
maxItems: 2
items:
- description: tx or combined interrupt
- description: rx interrupt
description:
A variable number of interrupts warrants a description of what conditions
affect the number of interrupts. Otherwise, descriptions on standard
properties are not necessary.
interrupt-names:
# minItems must be specified here because the default would be 2
minItems: 1
maxItems: 2
items:
- const: tx irq
- const: rx irq
# Property names starting with '#' must be quoted
'#interrupt-cells':
# A simple case where the value must always be '2'.
# The core schema handles that this must be a single integer.
const: 2
interrupt-controller: true
# The core checks this is a boolean, so just have to list it here to be
# valid for this binding.
clock-frequency:
# The type is set in the core schema. Per device schema only need to set
# constraints on the possible values.
minimum: 100
maximum: 400000
# The value that should be used if the property is not present
default: 200
foo-gpios:
maxItems: 1
description: A connection of the 'foo' gpio line.
vendor,int-property:
description: Vendor specific properties must have a description
# 'allOf' is the json-schema way of subclassing a schema. Here the base
# type schema is referenced and then additional constraints on the values
# are added.
allOf:
- $ref: /schemas/types.yaml#/definitions/uint32
- enum: [2, 4, 6, 8, 10]
vendor,bool-property:
description: Vendor specific properties must have a description
# boolean properties is one case where the json-schema 'type' keyword
# can be used directly
type: boolean
vendor,string-array-property:
description: Vendor specific properties should reference a type in the
core schema.
allOf:
- $ref: /schemas/types.yaml#/definitions/string-array
- items:
- enum: [ foo, bar ]
- enum: [ baz, boo ]
required:
- compatible
- reg
- interrupts
- interrupt-controller
examples:
# Examples are now compiled with dtc
- |
node@1000 {
compatible = "vendor,soc4-ip", "vendor,soc1-ip";
reg = <0x1000 0x80>,
<0x3000 0x80>;
reg-names = "core", "aux";
interrupts = <10>;
interrupt-controller;
};