Lines Matching +full:gpios +full:- +full:clear +full:- +full:reg
3 # SPDX-License-Identifier: BSD-3-Clause
17 but a binding can also come from a 'child-binding:' key in the binding for the
23 The top-level entry points for the library are the EDT and Binding classes.
31 # --------------------
47 # - Consider using @property for APIs that don't need parameters. It makes
51 # - Think about the data type of the thing you're exposing. Exposing something
55 # - Avoid get_*() prefixes on functions. Name them after the thing they return
60 # - Don't expose dtlib stuff directly.
62 # - Add documentation for any new APIs you add.
108 The free-form description of the binding, or None.
115 using 'child-binding:' with no compatible.
128 gpio-cells:
129 - pin
130 - flags
161 are multiple levels of 'child-binding' descriptions in the binding.
201 with open(path, encoding="utf-8") as f:
212 if "child-binding" in raw:
213 if not isinstance(raw["child-binding"], dict):
214 _err(f"malformed 'child-binding:' in {self.path}, "
218 raw=raw["child-binding"],
233 if key.endswith("-cells"):
234 self.specifier2cells[key[:-len("-cells")]] = val
236 def __repr__(self) -> str:
245 def description(self) -> Optional[str]:
250 def compatible(self) -> Optional[str]:
255 def bus(self) -> Union[None, str, List[str]]:
260 def buses(self) -> List[str]:
268 def on_bus(self) -> Optional[str]:
270 return self.raw.get('on-bus')
272 def _merge_includes(self, raw: dict, binding_path: Optional[str]) -> dict:
304 allowlist = elem.pop('property-allowlist', None)
305 blocklist = elem.pop('property-blocklist', None)
306 child_filter = elem.pop('child-binding', None)
324 "and optional 'property-allowlist' or "
325 f"'property-blocklist' keys, but got: {elem}")
339 def _load_raw(self, fname: str) -> dict:
350 with open(path, encoding="utf-8") as f:
366 f"field in {self.path} - "
378 # Allowed top-level keys. The 'include' key should have been
380 ok_top = {"description", "compatible", "bus", "on-bus",
381 "properties", "child-binding"}
385 "#cells": "expected *-cells syntax",
387 "child-bus": "use 'bus: <bus>' instead",
388 "parent": "use 'on-bus: <bus>' instead",
389 "parent-bus": "use 'on-bus: <bus>' instead",
390 "sub-node": "use 'child-binding' instead",
398 if key not in ok_top and not key.endswith("-cells"):
400 "expected one of {', '.join(ok_top)}, or *-cells")
416 if ("on-bus" in raw
417 and not isinstance(raw["on-bus"], str)):
418 _err(f"malformed 'on-bus:' value in {self.path}, "
424 if key.endswith("-cells"):
430 def _check_properties(self) -> None:
440 "specifier-space"}
494 The free-form description of the property as a string, or None.
503 A property must have string or string-array type and an "enum:" in its
505 unique after converting all non-alphanumeric characters to underscores
512 non-alphanumeric characters to underscores.
535 def __repr__(self) -> str:
539 def path(self) -> Optional[str]:
544 def type(self) -> str:
549 def description(self) -> Optional[str]:
554 def enum(self) -> Optional[list]:
559 def enum_tokenizable(self) -> bool:
562 if self.type not in {'string', 'string-array'} or self.enum is None:
576 def enum_upper_tokenizable(self) -> bool:
589 def const(self) -> Union[None, int, List[int], str, List[str]]:
594 def default(self) -> Union[None, int, List[int], str, List[str]]:
599 def required(self) -> bool:
604 def deprecated(self) -> bool:
609 def specifier_space(self) -> Optional[str]:
611 return self._raw.get("specifier-space")
627 'compound' currently do not get Property instances, as it's not clear
643 - For 'type: int/array/string/string-array', 'val' is what you'd expect
646 - For 'type: uint8-array', 'val' is a bytes object
648 - For 'type: phandle' and 'type: path', 'val' is the pointed-to Node
651 - For 'type: phandles', 'val' is a list of the pointed-to Node
654 - For 'type: phandle-array', 'val' is a list of ControllerAndData
671 The value of the property as a list of tokens, i.e. with non-alphanumeric
685 def name(self) -> str:
690 def description(self) -> Optional[str]:
695 def type(self) -> str:
700 def val_as_tokens(self) -> List[str]:
709 def enum_indices(self) -> Optional[List[int]]:
727 The name of the register as given in the 'reg-names' property, or None if
728 there is no 'reg-names' property
732 if #address-cells is zero. Any 'ranges' properties are taken into account.
759 child's #address-cells equals 0.
766 parent's #address-cells equals 0.
774 child's #size-cells equals 0.
788 Represents an entry in an 'interrupts' or 'type: phandle-array' property
789 value, e.g. <&ctrl-1 4 0> in
791 cs-gpios = <&ctrl-1 4 0 &ctrl-2 3 4>;
803 A dictionary that maps names from the *-cells key in the binding for the
811 'interrupt-names'/'gpio-names'/'pwm-names'/etc., or None if there is no
812 *-names property
828 e.g. pinctrl-0 or pinctrl-1.
833 The Node instance the pinctrl-* property is on
836 The name of the configuration, as given in pinctrl-names, or None if
837 there is no pinctrl-names property
840 Like 'name', but with non-alphanumeric characters converted to underscores.
846 pinctrl-0 = <&state_1 &state_2>;
862 with some interpretation of devicetree properties. There's a one-to-one
874 An integer with the ...@<unit-address> portion of the node name,
876 the node name has no unit-address portion. PCI devices use a different
909 A non-negative integer value such that the value for a Node is
927 True if the node has a 'read-only' property, and False otherwise
961 A list of PinCtrl objects for the pinctrl-<index> properties on the
963 pinctrl-<index> properties.
989 Documentation/devicetree/bindings/spi/spi-controller.yaml in the Linux kernel.
992 A list of ControllerAndData objects for the GPIOs hogged by the node. The
993 list is empty if the node does not hog any GPIOs. Only relevant for GPIO hog
1022 self.dep_ordinal: int = -1
1036 def name(self) -> str:
1041 def unit_addr(self) -> Optional[int]:
1053 _err(f"{self!r} has non-hex unit address")
1058 def description(self) -> Optional[str]:
1065 def path(self) -> str:
1070 def label(self) -> Optional[str]:
1077 def labels(self) -> List[str]:
1082 def parent(self) -> Optional['Node']:
1087 def children(self) -> Dict[str, 'Node']:
1095 def child_index(self, node) -> int:
1112 def required_by(self) -> List['Node']:
1117 def depends_on(self) -> List['Node']:
1122 def status(self) -> str:
1137 def read_only(self) -> bool:
1139 return "read-only" in self._node.props
1142 def matching_compat(self) -> Optional[str]:
1149 def binding_path(self) -> Optional[str]:
1156 def aliases(self) -> List[str]:
1162 def buses(self) -> List[str]:
1169 def on_buses(self) -> List[str]:
1175 def flash_controller(self) -> 'Node':
1179 # /flash-controller@4001E000/flash@0/partitions/partition@fc000. We go
1182 # For the case of 'soc-nv-flash', we assume the controller is the
1189 if controller.matching_compat == "soc-nv-flash":
1196 def spi_cs_gpio(self) -> Optional[ControllerAndData]:
1201 and "cs-gpios" in self.bus_node.props):
1205 _err(f"{self!r} needs a 'reg' property, to look up the "
1208 parent_cs_lst = self.bus_node.props["cs-gpios"].val
1212 # cs-gpios is indexed by the unit address
1219 "is >= number of cs-gpios in "
1228 def gpio_hogs(self) -> List[ControllerAndData]:
1231 if "gpio-hog" not in self.props:
1234 if not self.parent or not "gpio-controller" in self.parent.props:
1237 if not "#gpio-cells" in self.parent._node.props:
1238 _err(f"GPIO hog {self!r} parent node lacks #gpio-cells")
1240 n_cells = self.parent._node.props["#gpio-cells"].to_num()
1243 for item in _slice(self._node, "gpios", 4*n_cells,
1244 f"4*(<#gpio-cells> (= {n_cells})"):
1254 def has_child_binding(self) -> bool:
1256 True if the node's binding contains a child-binding definition, False
1262 def is_pci_device(self) -> bool:
1266 def __repr__(self) -> str:
1273 def _init_binding(self) -> None:
1313 # nesting with 'child-binding:'.
1323 def _binding_from_properties(self) -> None:
1339 pp["type"] = "uint8-array"
1347 pp["type"] = "string-array"
1353 pp["type"] = "phandle-array"
1365 def _binding_from_parent(self) -> Optional[Binding]:
1366 # Returns the binding from 'child-binding:' in the parent node's
1382 ) -> Optional['Node']:
1390 # Treat 'fixed-partitions' as if they are not on any bus. The reason is
1392 # bus be None means we'll always match the binding for fixed-partitions
1393 # also this means want processing the fixed-partitions node we wouldn't
1395 if support_fixed_partitions_on_any_bus and "fixed-partitions" in self.compats:
1407 ) -> None:
1408 # Initializes all properties that require cross-references to other
1418 err_on_deprecated: bool = False) -> None:
1443 err_on_deprecated: bool) -> None:
1473 # Skip properties that start with '#', like '#size-cells', and mapping
1474 # properties like 'gpio-map'/'interrupt-map'
1475 if name[0] == "#" or name.endswith("-map"):
1485 ) -> PropertyValType:
1528 if prop_type == "uint8-array":
1549 if prop_type == "uint8-array":
1555 if prop_type == "string-array":
1564 if prop_type == "phandle-array":
1565 # This type is a bit high-level for dtlib as it involves
1566 # information from bindings and *-names properties, so there's no
1587 def _check_undeclared_props(self) -> None:
1590 "interrupt-parent", "interrupts-extended", "device_type"}
1594 if (prop_name.endswith("-controller")
1607 def _init_ranges(self) -> None:
1616 raw_child_address_cells = node.props.get("#address-cells")
1622 raw_child_size_cells = node.props.get("#size-cells")
1628 # Number of cells for one translation 3-tuple in 'ranges'
1636 f"<#address-cells> = {child_address_cells}, "
1637 f"<#address-cells for parent> = {parent_address_cells} and "
1638 f"<#size-cells> = {child_size_cells}")
1641 f"4*(<#address-cells> (= {child_address_cells}) + "
1642 "<#address-cells for parent> "
1644 f"<#size-cells> (= {child_size_cells}))"):
1669 def _init_regs(self) -> None:
1676 if "reg" not in node.props:
1682 for raw_reg in _slice(node, "reg", 4*(address_cells + size_cells),
1683 f"4*(<#address-cells> (= {address_cells}) + "
1684 f"<#size-cells> (= {size_cells}))"):
1695 _err(f"zero-sized 'reg' in {self._node!r} seems meaningless "
1696 "(maybe you want a size of one or #size-cells = 0 "
1702 _add_names(node, "reg", self.regs)
1704 def _init_pinctrls(self) -> None:
1705 # Initializes self.pinctrls from any pinctrl-<index> properties
1709 # pinctrl-<index> properties
1711 if re.match("pinctrl-[0-9]+", name)]
1717 if prop.name != "pinctrl-" + str(i):
1718 _err(f"missing 'pinctrl-{i}' property on {node!r} "
1719 "- indices should be contiguous and start from zero")
1732 def _init_interrupts(self) -> None:
1753 ) -> List[Optional[ControllerAndData]]:
1760 # #<specifier_space>-cells = <size>;
1773 # #pwm-cells = <2>;
1777 # #pwm-cells = <1>;
1780 # These values can be given names using the <specifier_space>-names:
1785 # <specifier_space>-names = "...", "...", ...
1789 # An index is None if the underlying phandle-array element is
1793 if prop.name.endswith("gpios"):
1794 # There's some slight special-casing for *-gpios properties in that
1795 # e.g. foo-gpios still maps to #gpio-cells rather than
1796 # #foo-gpio-cells
1799 # Strip -s. We've already checked that property names end in -s
1801 specifier_space = prop.name[:-1]
1832 ) -> Dict[str, int]:
1833 # Returns a dictionary that maps <basename>-cells names given in the
1844 # Treat no *-cells in the binding the same as an empty *-cells, so
1845 # that bindings don't have to have e.g. an empty 'clock-cells:' for
1846 # '#clock-cells = <0>'.
1851 _err(f"unexpected '{basename}-cells:' length in binding for "
1852 f"{controller._node!r} - {len(cell_names)} "
1905 and processing /delete-node/ and /delete-property/, as a string
1944 If True, a warning is logged if a node has a 'reg' property where
1953 If True, set the Node.bus for 'fixed-partitions' compatible nodes
1954 to None. This allows 'fixed-partitions' binding to match regardless
1955 of the bus the 'fixed-partition' is under.
1966 exempt set of grandfathered-in cases will cause warnings.
2016 def _finish_init(self) -> None:
2028 def get_node(self, path: str) -> Node:
2039 def chosen_nodes(self) -> Dict[str, Node]:
2058 def chosen_node(self, name: str) -> Optional[Node]:
2066 def dts_source(self) -> str:
2069 def __repr__(self) -> str:
2073 def __deepcopy__(self, memo) -> 'EDT':
2095 def scc_order(self) -> List[List[Node]]:
2101 def _process_properties_r(self, root_node: Node, props_node: Node) -> None:
2111 # 'phandles', or 'phandle-array' property values.
2120 elif prop.type == 'phandle-array':
2144 def _process_properties(self, node: Node) -> None:
2151 def _init_graph(self) -> None:
2170 def _init_compat2binding(self) -> None:
2195 with open(binding_path, encoding="utf-8") as f:
2230 dt_compats: Set[str]) -> Optional[Binding]:
2252 def _register_binding(self, binding: Binding) -> None:
2254 # 'compatible:'/'on-bus:' combo
2263 msg += f" and 'on-bus: {binding.on_bus}'"
2269 def _init_nodes(self) -> None:
2296 _LOG.warning("unit address and first address in 'reg' "
2300 def _init_luts(self) -> None:
2316 # The regular expression comes from dt-schema.
2317 compat_re = r'^[a-zA-Z][a-zA-Z0-9,+\-._]+$'
2350 def _check(self) -> None:
2351 # Tree-wide checks and warnings.
2361 f"in binding '{binding.path}' has non-tokenizable enum "
2382 # is a list, but add an assert for future-proofing.
2386 # This is also just for future-proofing.
2391 ignore_errors: bool = False) -> List[Binding]:
2413 "Exception raised for devicetree- and binding-related errors"
2420 def load_vendor_prefixes_txt(vendor_prefixes: str) -> Dict[str, str]:
2421 """Load a vendor-prefixes.txt file and return a dict
2425 with open(vendor_prefixes, 'r', encoding='utf-8') as f:
2446 def _dt_compats(dt: DT) -> Set[str]:
2456 def _binding_paths(bindings_dirs: List[str]) -> List[str]:
2481 binding_path: Optional[str]) -> None:
2482 # Check that an 'include:' named 'name' with property-allowlist
2483 # 'allowlist', property-blocklist 'blocklist', and
2484 # child-binding filter 'child_filter' has valid structure.
2492 "should not specify both 'property-allowlist:' "
2493 "and 'property-blocklist:'")
2498 child_copy.pop('property-allowlist', None))
2500 child_copy.pop('property-blocklist', None))
2502 child_copy.pop('child-binding', None))
2508 f"'child-binding': {child_copy}")
2512 "should not specify both 'property-allowlist:' and "
2513 "'property-blocklist:' in a 'child-binding:'")
2522 binding_path: Optional[str]) -> None:
2524 # 'raw["child-binding"]', if they exist, according to
2530 child_binding = raw.get('child-binding')
2533 child_filter.get('property-allowlist'),
2534 child_filter.get('property-blocklist'),
2536 child_filter = child_filter.get('child-binding')
2537 child_binding = child_binding.get('child-binding')
2543 binding_path: Optional[str]) -> None:
2547 _check_prop_filter('property-allowlist', allowlist, binding_path)
2548 _check_prop_filter('property-blocklist', blocklist, binding_path)
2564 binding_path: Optional[str]) -> None:
2565 # Ensure an include: ... property-allowlist or property-blocklist
2588 # which might help keep bindings well-organized.
2595 # 'from_dict', and 'binding_path' is the path to the top-level binding.
2622 check_required: bool) -> bool:
2658 binding_path: Optional[str]) -> None:
2660 # 'const:' and # 'specifier-space:' for the property named 'prop_name'
2670 ok_types = {"boolean", "int", "array", "uint8-array", "string",
2671 "string-array", "phandle", "phandles", "phandle-array",
2679 if "specifier-space" in options and prop_type != "phandle-array":
2680 _err(f"'specifier-space' in 'properties: {prop_name}' "
2681 f"has type '{prop_type}', expected 'phandle-array'")
2683 if prop_type == "phandle-array":
2684 if not prop_name.endswith("s") and not "specifier-space" in options:
2686 f"has type 'phandle-array' and its name does not end in 's', "
2687 f"but no 'specifier-space' was provided.")
2691 const_types = {"int", "array", "uint8-array", "string", "string-array"}
2703 "phandle-array", "path"}:
2708 def ok_default() -> bool:
2717 # array, uint8-array, or string-array
2726 if (prop_type == "uint8-array"
2731 # string-array
2740 def _translate(addr: int, node: dtlib_Node) -> int:
2754 # Treat this the same as a 'range' that explicitly does a one-to-one
2758 # Gives the size of each component in a translation 3-tuple in 'ranges'
2763 # Number of cells for one translation 3-tuple in 'ranges'
2767 f"4*(<#address-cells> (= {child_address_cells}) + "
2768 "<#address-cells for parent> "
2770 f"<#size-cells> (= {child_size_cells}))"):
2782 return _translate(parent_addr + addr - child_addr, node.parent)
2788 def _add_names(node: dtlib_Node, names_ident: str, objs: Any) -> None:
2789 # Helper for registering names from <foo>-names properties.
2794 # names-ident:
2795 # The <foo> part of <foo>-names, e.g. "reg" for "reg-names"
2800 full_names_ident = names_ident + "-names"
2819 def _interrupt_parent(start_node: dtlib_Node) -> dtlib_Node:
2820 # Returns the node pointed at by the closest 'interrupt-parent', searching
2827 if "interrupt-parent" in node.props:
2828 return node.props["interrupt-parent"].to_node()
2832 f"nor any of its parents has an 'interrupt-parent' property")
2835 def _interrupts(node: dtlib_Node) -> List[Tuple[dtlib_Node, bytes]]:
2838 # interrupt (possibly after mapping through an 'interrupt-map'), and <data>
2842 if "interrupts-extended" in node.props:
2843 prop = node.props["interrupts-extended"]
2848 _err(f"node '{node.path}' interrupts-extended property "
2855 # Treat 'interrupts' as a special case of 'interrupts-extended', with
2863 "4*<#interrupt-cells>")]
2872 ) -> Tuple[dtlib_Node, bytes]:
2874 # 'child_spec' through any 'interrupt-map' properties. Returns a
2877 if "interrupt-controller" in parent.props:
2881 # Used for parents pointed at by 'interrupt-map'. We can't use
2882 # _address_cells(), because it's the #address-cells property on 'node'
2885 address_cells = node.props.get("#address-cells")
2887 _err(f"missing #address-cells on {node!r} "
2888 "(while handling interrupt-map)")
2892 # Can't use _address_cells() here, because it's the #address-cells
2909 ) -> Tuple[dtlib_Node, bytes]:
2911 # mapping through any '<basename>-map' (e.g. gpio-map) properties. See
2915 prop_name = f"#{basename}-cells"
2921 # Do not require <prefix>-controller for anything but interrupts for now
2933 ) -> Tuple[dtlib_Node, bytes]:
2934 # Common code for mapping through <prefix>-map properties, e.g.
2935 # interrupt-map and gpio-map.
2944 # The "receiver", e.g. a node with 'interrupt-map = <...>' or
2945 # 'interrupt-controller' (no mapping)
2949 # e.g. <1 2> for 'foo-gpios = <&gpio1 1 2>'.
2952 # Function called on a parent specified in a *-map property to get the
2953 # length of the parent specifier (data after phandle in *-map), in cells
2957 # to have a <prefix>-controller property.
2959 map_prop = parent.props.get(prefix + "-map")
2961 if require_controller and prefix + "-controller" not in parent.props:
2962 _err(f"expected '{prefix}-controller' property on {parent!r} "
2982 # Parent specified in *-map
2993 # Got one *-map row. Check if it matches the child data.
2995 # Handle *-map-pass-thru
3012 ) -> bytes:
3013 # Common code for handling <prefix>-mask properties, e.g. interrupt-mask.
3016 mask_prop = parent.props.get(prefix + "-map-mask")
3023 _err(f"{child!r}: expected '{prefix}-mask' in {parent!r} "
3035 ) -> bytes:
3036 # Common code for handling <prefix>-map-thru properties, e.g.
3037 # interrupt-pass-thru.
3040 # The parent data from the matched entry in the <prefix>-map property
3044 pass_thru_prop = parent.props.get(prefix + "-map-pass-thru")
3046 # No pass-thru
3051 _err(f"{child!r}: expected '{prefix}-map-pass-thru' in {parent!r} "
3058 return res[-len(parent_spec):]
3061 def _raw_unit_addr(node: dtlib_Node) -> bytes:
3062 # _map_interrupt() helper. Returns the unit address (derived from 'reg' and
3063 # #address-cells) as a raw 'bytes'
3065 if 'reg' not in node.props:
3066 _err(f"{node!r} lacks 'reg' property "
3067 "(needed for 'interrupt-map' unit address lookup)")
3071 if len(node.props['reg'].value) < addr_len:
3072 _err(f"{node!r} has too short 'reg' property "
3073 "(while doing 'interrupt-map' unit address lookup)")
3075 return node.props['reg'].value[:addr_len]
3078 def _and(b1: bytes, b2: bytes) -> bytes:
3088 def _or(b1: bytes, b2: bytes) -> bytes:
3098 def _not(b: bytes) -> bytes:
3108 ) -> List[Optional[Tuple[dtlib_Node, bytes]]]:
3117 # The <name> part of the #<name>-cells property to look for on the nodes
3118 # the phandles point to, e.g. "gpio" for #gpio-cells.
3124 full_n_cells_name = f"#{n_cells_name}-cells"
3138 # Unspecified phandle-array element. This is valid; a 0
3156 def _address_cells(node: dtlib_Node) -> int:
3157 # Returns the #address-cells setting for 'node', giving the number of <u32>
3158 # cells used to encode the address in the 'reg' property
3162 if "#address-cells" in node.parent.props:
3163 return node.parent.props["#address-cells"].to_num()
3167 def _size_cells(node: dtlib_Node) -> int:
3168 # Returns the #size-cells setting for 'node', giving the number of <u32>
3169 # cells used to encode the size in the 'reg' property
3173 if "#size-cells" in node.parent.props:
3174 return node.parent.props["#size-cells"].to_num()
3178 def _interrupt_cells(node: dtlib_Node) -> int:
3179 # Returns the #interrupt-cells property value on 'node', erroring out if
3180 # 'node' has no #interrupt-cells property
3182 if "#interrupt-cells" not in node.props:
3183 _err(f"{node!r} lacks #interrupt-cells")
3184 return node.props["#interrupt-cells"].to_num()
3190 size_hint: str) -> List[bytes]:
3194 def _check_dt(dt: DT) -> None:
3196 # anything-goes except for very special properties like phandle, but in
3202 ok_status = {"ok", "okay", "disabled", "reserved", "fail", "fail-sss"}
3226 def _err(msg) -> NoReturn:
3232 # Regular expression for non-alphanumeric-or-underscore characters.
3236 def str_as_token(val: str) -> str:
3263 "compatible": "string-array",
3266 "reg": "array",
3267 "reg-names": "string-array",
3270 "interrupts-extended": "compound",
3271 "interrupt-names": "string-array",
3272 "interrupt-controller": "boolean",
3275 _STATUS_ENUM: List[str] = "ok okay disabled reserved fail fail-sss".split()
3279 ) -> Dict[str, Union[str, bool, List[str]]]: