Skip to content

Commit 613fd2b

Browse files
committed
devicetree: Add DT_CHILD_BY_REG_ADDR
Allow fetching child node identifiers by reg address. Signed-off-by: Pieter De Gendt <pieter.degendt@basalte.be>
1 parent 474d068 commit 613fd2b

File tree

2 files changed

+65
-0
lines changed

2 files changed

+65
-0
lines changed

include/zephyr/devicetree.h

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -435,6 +435,41 @@
435435
*/
436436
#define DT_CHILD(node_id, child) UTIL_CAT(node_id, DT_S_PREFIX(child))
437437

438+
/**
439+
* @brief Get a node identifier for a child node by a reg address
440+
*
441+
* Example devicetree fragment:
442+
*
443+
* @code{.dts}
444+
* / {
445+
* soc-label: soc {
446+
* serial1: serial@40001000 {
447+
* status = "okay";
448+
* current-speed = <115200>;
449+
* ...
450+
* };
451+
* };
452+
* };
453+
* @endcode
454+
*
455+
* Example usage with DT_PROP() to get the status of the
456+
* `serial@40001000` node:
457+
*
458+
* @code{.c}
459+
* #define SOC_NODE DT_NODELABEL(soc_label)
460+
* DT_PROP(DT_CHILD_BY_REG_ADDR(SOC_NODE, 0, 40001000), status) // "okay"
461+
* @endcode
462+
*
463+
*
464+
* @param node_id node identifier
465+
* @param idx Register address index for the child node.
466+
* @param addr Register address for the child node. Can be hexadecimal (prefix with 0x) or decimal
467+
*
468+
* @return node identifier for the child node with the reg address at a specified index
469+
*/
470+
#define DT_CHILD_BY_REG_ADDR(node_id, idx, addr) \
471+
DT_CAT5(node_id, _CHILD_REG_IDX_, idx, _ADDR_, addr)
472+
438473
/**
439474
* @brief Get a node identifier for a status `okay` node with a compatible
440475
*
@@ -4066,6 +4101,20 @@
40664101
#define DT_INST_CHILD(inst, child) \
40674102
DT_CHILD(DT_DRV_INST(inst), child)
40684103

4104+
/**
4105+
* @brief Get a node identifier for a child node by a reg address of DT_DRV_INST(inst)
4106+
*
4107+
* @param inst instance number
4108+
* @param idx Register address index for the child node.
4109+
* @param addr Register address for the child node. Can be hexadecimal (prefix with 0x) or decimal
4110+
*
4111+
* @return node identifier for the child node with the reg address at a specified index
4112+
*
4113+
* @see DT_CHILD_BY_REG_ADDR
4114+
*/
4115+
#define DT_INST_CHILD_BY_REG_ADDR(inst, idx, addr) \
4116+
DT_CHILD_BY_REG_ADDR(DT_DRV_INST(inst), idx, addr)
4117+
40694118
/**
40704119
* @brief Get the number of child nodes of a given node
40714120
*

scripts/dts/gen_defines.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -484,6 +484,22 @@ def write_children(node: edtlib.Node) -> None:
484484

485485
out_dt_define(f"{node.z_path_id}_CHILD_NUM_STATUS_OKAY", ok_nodes_num)
486486

487+
child_reg_addrs = {}
488+
for child in node.children.values():
489+
# Provide a way to query child nodes
490+
for idx, reg in enumerate(child.regs):
491+
if reg.addr is not None:
492+
child_reg_addrs.setdefault((idx, reg.addr), []).append(child)
493+
494+
for (idx, addr), children in child_reg_addrs.items():
495+
if len(children) > 1:
496+
# Duplicate addresses for different children, skip
497+
continue
498+
499+
# Decimal and hexadecimal variants
500+
out_dt_define(f"{node.z_path_id}_CHILD_REG_IDX_{idx}_ADDR_{addr}", f"DT_{children[0].z_path_id}")
501+
out_dt_define(f"{node.z_path_id}_CHILD_REG_IDX_{idx}_ADDR_{hex(addr)}", f"DT_{children[0].z_path_id}")
502+
487503
out_dt_define(f"{node.z_path_id}_FOREACH_CHILD(fn)",
488504
" ".join(f"fn(DT_{child.z_path_id})" for child in
489505
node.children.values()))

0 commit comments

Comments
 (0)