Line data Source code
1 1 : /*
2 : * SPDX-License-Identifier: Apache-2.0
3 : * Copyright (c) 2020 Nordic Semiconductor
4 : * Copyright (c) 2020, Linaro Ltd.
5 : *
6 : * Not a generated file. Feel free to modify.
7 : */
8 :
9 : /**
10 : * @file
11 : * @brief Devicetree main header
12 : *
13 : * API for accessing the current application's devicetree macros.
14 : */
15 :
16 : #ifndef ZEPHYR_INCLUDE_DEVICETREE_H_
17 : #define ZEPHYR_INCLUDE_DEVICETREE_H_
18 :
19 : #include <zephyr/devicetree_generated.h>
20 : #include <zephyr/irq_multilevel.h>
21 :
22 : #if !defined(_LINKER) && !defined(_ASMLANGUAGE)
23 : #include <stdint.h>
24 : #endif
25 :
26 : #include <zephyr/sys/util.h>
27 :
28 : /**
29 : * @brief devicetree.h API
30 : * @defgroup devicetree Devicetree
31 : * @since 2.2
32 : * @version 1.2.0
33 : * @{
34 : * @}
35 : */
36 :
37 : /*
38 : * Property suffixes
39 : * -----------------
40 : *
41 : * These are the optional parts that come after the _P_<property>
42 : * part in DT_N_<path-id>_P_<property-id> macros, or the "prop-suf"
43 : * nonterminal in the DT guide's macros.bnf file.
44 : *
45 : * Before adding new ones, check this list to avoid conflicts. If any
46 : * are missing from this list, please add them. It should be complete.
47 : *
48 : * _ENUM_IDX: property's value as an index into bindings enum
49 : * _ENUM_VAL_<val>_EXISTS property's value as a token exists
50 : * _EXISTS: property is defined
51 : * _FOREACH_PROP_ELEM: helper for "iterating" over values in the property
52 : * _FOREACH_PROP_ELEM_VARGS: foreach functions with variable number of arguments
53 : * _IDX_<i>: logical index into property
54 : * _IDX_<i>_EXISTS: logical index into property is defined
55 : * _IDX_<i>_PH: phandle array's phandle by index (or phandle, phandles)
56 : * _IDX_<i>_STRING_TOKEN: string array element value as a token
57 : * _IDX_<i>_STRING_UPPER_TOKEN: string array element value as a uppercased token
58 : * _IDX <i>_STRING_UNQUOTED: string array element value as a sequence of tokens, with no quotes
59 : * _IDX_<i>_VAL_<val>: phandle array's specifier value by index
60 : * _IDX_<i>_VAL_<val>_EXISTS: cell value exists, by index
61 : * _LEN: property logical length
62 : * _NAME_<name>_PH: phandle array's phandle by name
63 : * _NAME_<name>_VAL_<val>: phandle array's property specifier by name
64 : * _NAME_<name>_VAL_<val>_EXISTS: cell value exists, by name
65 : * _STRING_TOKEN: string property's value as a token
66 : * _STRING_UPPER_TOKEN: like _STRING_TOKEN, but uppercased
67 : * _STRING_UNQUOTED: string property's value as a sequence of tokens, with no quotes
68 : */
69 :
70 : /**
71 : * @defgroup devicetree-generic-id Node identifiers and helpers
72 : * @ingroup devicetree
73 : * @{
74 : */
75 :
76 : /**
77 : * @brief Name for an invalid node identifier
78 : *
79 : * This supports cases where factored macros can be invoked from paths where
80 : * devicetree data may or may not be available. It is a preprocessor identifier
81 : * that does not match any valid devicetree node identifier.
82 : */
83 1 : #define DT_INVALID_NODE _
84 :
85 : /**
86 : * @brief Node identifier for the root node in the devicetree
87 : */
88 1 : #define DT_ROOT DT_N
89 :
90 : /**
91 : * @brief Get a node identifier for a devicetree path
92 : *
93 : * @note This macro returns a node identifier from path components. To get
94 : * a path string from a node identifier, use DT_NODE_PATH() instead.
95 : *
96 : * The arguments to this macro are the names of non-root nodes in the
97 : * tree required to reach the desired node, starting from the root.
98 : * Non-alphanumeric characters in each name must be converted to
99 : * underscores to form valid C tokens, and letters must be lowercased.
100 : *
101 : * Example devicetree fragment:
102 : *
103 : * @code{.dts}
104 : * / {
105 : * soc {
106 : * serial1: serial@40001000 {
107 : * status = "okay";
108 : * current-speed = <115200>;
109 : * ...
110 : * };
111 : * };
112 : * };
113 : * @endcode
114 : *
115 : * You can use `DT_PATH(soc, serial_40001000)` to get a node identifier
116 : * for the `serial@40001000` node. Node labels like `serial1` cannot be
117 : * used as DT_PATH() arguments; use DT_NODELABEL() for those instead.
118 : *
119 : * Example usage with DT_PROP() to get the `current-speed` property:
120 : *
121 : * @code{.c}
122 : * DT_PROP(DT_PATH(soc, serial_40001000), current_speed) // 115200
123 : * @endcode
124 : *
125 : * (The `current-speed` property is also in `lowercase-and-underscores`
126 : * form when used with this API.)
127 : *
128 : * When determining arguments to DT_PATH():
129 : *
130 : * - the first argument corresponds to a child node of the root (`soc` above)
131 : * - a second argument corresponds to a child of the first argument
132 : * (`serial_40001000` above, from the node name `serial@40001000`
133 : * after lowercasing and changing `@` to `_`)
134 : * - and so on for deeper nodes in the desired node's path
135 : *
136 : * @param ... lowercase-and-underscores node names along the node's path,
137 : * with each name given as a separate argument
138 : * @return node identifier for the node with that path
139 : */
140 1 : #define DT_PATH(...) DT_PATH_INTERNAL(__VA_ARGS__)
141 :
142 : /**
143 : * @brief Get a node identifier for a node label
144 : *
145 : * Convert non-alphanumeric characters in the node label to
146 : * underscores to form valid C tokens, and lowercase all letters. Note
147 : * that node labels are not the same thing as label properties.
148 : *
149 : * Example devicetree fragment:
150 : *
151 : * @code{.dts}
152 : * serial1: serial@40001000 {
153 : * label = "UART_0";
154 : * status = "okay";
155 : * current-speed = <115200>;
156 : * ...
157 : * };
158 : * @endcode
159 : *
160 : * The only node label in this example is `serial1`.
161 : *
162 : * The string `UART_0` is *not* a node label; it's the value of a
163 : * property named label.
164 : *
165 : * You can use `DT_NODELABEL(serial1)` to get a node identifier for the
166 : * `serial@40001000` node. Example usage with DT_PROP() to get the
167 : * current-speed property:
168 : *
169 : * @code{.c}
170 : * DT_PROP(DT_NODELABEL(serial1), current_speed) // 115200
171 : * @endcode
172 : *
173 : * Another example devicetree fragment:
174 : *
175 : * @code{.dts}
176 : * cpu@0 {
177 : * L2_0: l2-cache {
178 : * cache-level = <2>;
179 : * ...
180 : * };
181 : * };
182 : * @endcode
183 : *
184 : * Example usage to get the cache-level property:
185 : *
186 : * @code{.c}
187 : * DT_PROP(DT_NODELABEL(l2_0), cache_level) // 2
188 : * @endcode
189 : *
190 : * Notice how `L2_0` in the devicetree is lowercased to `l2_0` in the
191 : * DT_NODELABEL() argument.
192 : *
193 : * @param label lowercase-and-underscores node label name
194 : * @return node identifier for the node with that label
195 : */
196 1 : #define DT_NODELABEL(label) DT_CAT(DT_N_NODELABEL_, label)
197 :
198 : /**
199 : * @brief Get a node identifier from /aliases
200 : *
201 : * This macro's argument is a property of the `/aliases` node. It
202 : * returns a node identifier for the node which is aliased. Convert
203 : * non-alphanumeric characters in the alias property to underscores to
204 : * form valid C tokens, and lowercase all letters.
205 : *
206 : * Example devicetree fragment:
207 : *
208 : * @code{.dts}
209 : * / {
210 : * aliases {
211 : * my-serial = &serial1;
212 : * };
213 : *
214 : * soc {
215 : * serial1: serial@40001000 {
216 : * status = "okay";
217 : * current-speed = <115200>;
218 : * ...
219 : * };
220 : * };
221 : * };
222 : * @endcode
223 : *
224 : * You can use DT_ALIAS(my_serial) to get a node identifier for the
225 : * `serial@40001000` node. Notice how `my-serial` in the devicetree
226 : * becomes `my_serial` in the DT_ALIAS() argument. Example usage with
227 : * DT_PROP() to get the current-speed property:
228 : *
229 : * @code{.c}
230 : * DT_PROP(DT_ALIAS(my_serial), current_speed) // 115200
231 : * @endcode
232 : *
233 : * @param alias lowercase-and-underscores alias name.
234 : * @return node identifier for the node with that alias
235 : */
236 1 : #define DT_ALIAS(alias) DT_CAT(DT_N_ALIAS_, alias)
237 :
238 : /**
239 : * @brief Test if the devicetree has a given alias
240 : * @param alias_name lowercase-and-underscores devicetree alias name
241 : * @return 1 if the alias exists and refers to a node, 0 otherwise
242 : */
243 1 : #define DT_HAS_ALIAS(alias_name) DT_NODE_EXISTS(DT_ALIAS(alias_name))
244 :
245 : /**
246 : * @brief Get the hash associated with a DT node
247 : *
248 : * Get the hash for the specified node_id. The hash is calculated on the
249 : * full devicetree path of the node.
250 : * @param node_id node identifier
251 : * @return hash value as a preprocessor token
252 : */
253 1 : #define DT_NODE_HASH(node_id) DT_CAT(node_id, _HASH)
254 :
255 : /**
256 : * @brief Get a node identifier for an instance of a compatible
257 : *
258 : * All nodes with a particular compatible property value are assigned
259 : * instance numbers, which are zero-based indexes specific to that
260 : * compatible. You can get a node identifier for these nodes by
261 : * passing DT_INST() an instance number, @p inst, along with the
262 : * lowercase-and-underscores version of the compatible, @p compat.
263 : *
264 : * Instance numbers have the following properties:
265 : *
266 : * - for each compatible, instance numbers start at 0 and are contiguous
267 : * - exactly one instance number is assigned for each node with a compatible,
268 : * **including disabled nodes**
269 : * - enabled nodes (status property is `okay` or missing) are assigned the
270 : * instance numbers starting from 0, and disabled nodes have instance
271 : * numbers which are greater than those of any enabled node
272 : *
273 : * No other guarantees are made. In particular:
274 : *
275 : * - instance numbers **in no way reflect** any numbering scheme that
276 : * might exist in SoC documentation, node labels or unit addresses,
277 : * or properties of the /aliases node (use DT_NODELABEL() or DT_ALIAS()
278 : * for those)
279 : * - there **is no general guarantee** that the same node will have
280 : * the same instance number between builds, even if you are building
281 : * the same application again in the same build directory
282 : *
283 : * Example devicetree fragment:
284 : *
285 : * @code{.dts}
286 : * serial1: serial@40001000 {
287 : * compatible = "vnd,soc-serial";
288 : * status = "disabled";
289 : * current-speed = <9600>;
290 : * ...
291 : * };
292 : *
293 : * serial2: serial@40002000 {
294 : * compatible = "vnd,soc-serial";
295 : * status = "okay";
296 : * current-speed = <57600>;
297 : * ...
298 : * };
299 : *
300 : * serial3: serial@40003000 {
301 : * compatible = "vnd,soc-serial";
302 : * current-speed = <115200>;
303 : * ...
304 : * };
305 : * @endcode
306 : *
307 : * Assuming no other nodes in the devicetree have compatible
308 : * `"vnd,soc-serial"`, that compatible has nodes with instance numbers
309 : * 0, 1, and 2.
310 : *
311 : * The nodes `serial@40002000` and `serial@40003000` are both enabled, so
312 : * their instance numbers are 0 and 1, but no guarantees are made
313 : * regarding which node has which instance number.
314 : *
315 : * Since `serial@40001000` is the only disabled node, it has instance
316 : * number 2, since disabled nodes are assigned the largest instance
317 : * numbers. Therefore:
318 : *
319 : * @code{.c}
320 : * // Could be 57600 or 115200. There is no way to be sure:
321 : * // either serial@40002000 or serial@40003000 could
322 : * // have instance number 0, so this could be the current-speed
323 : * // property of either of those nodes.
324 : * DT_PROP(DT_INST(0, vnd_soc_serial), current_speed)
325 : *
326 : * // Could be 57600 or 115200, for the same reason.
327 : * // If the above expression expands to 57600, then
328 : * // this expands to 115200, and vice-versa.
329 : * DT_PROP(DT_INST(1, vnd_soc_serial), current_speed)
330 : *
331 : * // 9600, because there is only one disabled node, and
332 : * // disabled nodes are "at the end" of the instance
333 : * // number "list".
334 : * DT_PROP(DT_INST(2, vnd_soc_serial), current_speed)
335 : * @endcode
336 : *
337 : * Notice how `"vnd,soc-serial"` in the devicetree becomes `vnd_soc_serial`
338 : * (without quotes) in the DT_INST() arguments. (As usual, `current-speed`
339 : * in the devicetree becomes `current_speed` as well.)
340 : *
341 : * Nodes whose `compatible` property has multiple values are assigned
342 : * independent instance numbers for each compatible.
343 : *
344 : * @param inst instance number for compatible @p compat
345 : * @param compat lowercase-and-underscores compatible, without quotes
346 : * @return node identifier for the node with that instance number and
347 : * compatible
348 : */
349 1 : #define DT_INST(inst, compat) UTIL_CAT(DT_N_INST, DT_DASH(inst, compat))
350 :
351 : /**
352 : * @brief Get a node identifier for a parent node
353 : *
354 : * Example devicetree fragment:
355 : *
356 : * @code{.dts}
357 : * parent: parent-node {
358 : * child: child-node {
359 : * ...
360 : * };
361 : * };
362 : * @endcode
363 : *
364 : * The following are equivalent ways to get the same node identifier:
365 : *
366 : * @code{.c}
367 : * DT_NODELABEL(parent)
368 : * DT_PARENT(DT_NODELABEL(child))
369 : * @endcode
370 : *
371 : * @param node_id node identifier
372 : * @return a node identifier for the node's parent
373 : */
374 1 : #define DT_PARENT(node_id) DT_CAT(node_id, _PARENT)
375 :
376 : /**
377 : * @brief Get a node identifier for a grandparent node
378 : *
379 : * Example devicetree fragment:
380 : *
381 : * @code{.dts}
382 : * gparent: grandparent-node {
383 : * parent: parent-node {
384 : * child: child-node { ... }
385 : * };
386 : * };
387 : * @endcode
388 : *
389 : * The following are equivalent ways to get the same node identifier:
390 : *
391 : * @code{.c}
392 : * DT_GPARENT(DT_NODELABEL(child))
393 : * DT_PARENT(DT_PARENT(DT_NODELABEL(child))
394 : * @endcode
395 : *
396 : * @param node_id node identifier
397 : * @return a node identifier for the node's parent's parent
398 : */
399 1 : #define DT_GPARENT(node_id) DT_PARENT(DT_PARENT(node_id))
400 :
401 : /**
402 : * @brief Get a node identifier for a child node
403 : *
404 : * Example devicetree fragment:
405 : *
406 : * @code{.dts}
407 : * / {
408 : * soc-label: soc {
409 : * serial1: serial@40001000 {
410 : * status = "okay";
411 : * current-speed = <115200>;
412 : * ...
413 : * };
414 : * };
415 : * };
416 : * @endcode
417 : *
418 : * Example usage with DT_PROP() to get the status of the
419 : * `serial@40001000` node:
420 : *
421 : * @code{.c}
422 : * #define SOC_NODE DT_NODELABEL(soc_label)
423 : * DT_PROP(DT_CHILD(SOC_NODE, serial_40001000), status) // "okay"
424 : * @endcode
425 : *
426 : * Node labels like `serial1` cannot be used as the @p child argument
427 : * to this macro. Use DT_NODELABEL() for that instead.
428 : *
429 : * You can also use DT_FOREACH_CHILD() to iterate over node
430 : * identifiers for all of a node's children.
431 : *
432 : * @param node_id node identifier
433 : * @param child lowercase-and-underscores child node name
434 : * @return node identifier for the node with the name referred to by 'child'
435 : */
436 1 : #define DT_CHILD(node_id, child) UTIL_CAT(node_id, DT_S_PREFIX(child))
437 :
438 : /**
439 : * @brief Get a node identifier for a status `okay` node with a compatible
440 : *
441 : * Use this if you want to get an arbitrary enabled node with a given
442 : * compatible, and you do not care which one you get. If any enabled
443 : * nodes with the given compatible exist, a node identifier for one
444 : * of them is returned. Otherwise, @ref DT_INVALID_NODE is returned.
445 : *
446 : * Example devicetree fragment:
447 : *
448 : * @code{.dts}
449 : * node-a {
450 : * compatible = "vnd,device";
451 : * status = "okay";
452 : * };
453 : *
454 : * node-b {
455 : * compatible = "vnd,device";
456 : * status = "okay";
457 : * };
458 : *
459 : * node-c {
460 : * compatible = "vnd,device";
461 : * status = "disabled";
462 : * };
463 : * @endcode
464 : *
465 : * Example usage:
466 : *
467 : * @code{.c}
468 : * DT_COMPAT_GET_ANY_STATUS_OKAY(vnd_device)
469 : * @endcode
470 : *
471 : * This expands to a node identifier for either `node-a` or `node-b`.
472 : * It will not expand to a node identifier for `node-c`, because that
473 : * node does not have status `okay`.
474 : *
475 : * @param compat lowercase-and-underscores compatible, without quotes
476 : * @return node identifier for a node with that compatible, or
477 : * @ref DT_INVALID_NODE
478 : */
479 1 : #define DT_COMPAT_GET_ANY_STATUS_OKAY(compat) \
480 : COND_CODE_1(DT_HAS_COMPAT_STATUS_OKAY(compat), \
481 : (DT_INST(0, compat)), \
482 : (DT_INVALID_NODE))
483 :
484 : /**
485 : * @brief Get a devicetree node's full path as a string literal
486 : *
487 : * This returns the path to a node from a node identifier. To get a
488 : * node identifier from path components instead, use DT_PATH().
489 : *
490 : * Example devicetree fragment:
491 : *
492 : * @code{.dts}
493 : * / {
494 : * soc {
495 : * node: my-node@12345678 { ... };
496 : * };
497 : * };
498 : * @endcode
499 : *
500 : * Example usage:
501 : *
502 : * @code{.c}
503 : * DT_NODE_PATH(DT_NODELABEL(node)) // "/soc/my-node@12345678"
504 : * DT_NODE_PATH(DT_PATH(soc)) // "/soc"
505 : * DT_NODE_PATH(DT_ROOT) // "/"
506 : * @endcode
507 : *
508 : * @param node_id node identifier
509 : * @return the node's full path in the devicetree
510 : */
511 1 : #define DT_NODE_PATH(node_id) DT_CAT(node_id, _PATH)
512 :
513 : /**
514 : * @brief Get a devicetree node's name with unit-address as a string literal
515 : *
516 : * This returns the node name and unit-address from a node identifier.
517 : *
518 : * Example devicetree fragment:
519 : *
520 : * @code{.dts}
521 : * / {
522 : * soc {
523 : * node: my-node@12345678 { ... };
524 : * };
525 : * };
526 : * @endcode
527 : *
528 : * Example usage:
529 : *
530 : * @code{.c}
531 : * DT_NODE_FULL_NAME(DT_NODELABEL(node)) // "my-node@12345678"
532 : * @endcode
533 : *
534 : * @param node_id node identifier
535 : * @return the node's name with unit-address as a string in the devicetree
536 : */
537 1 : #define DT_NODE_FULL_NAME(node_id) DT_CAT(node_id, _FULL_NAME)
538 :
539 : /**
540 : * @brief Get the node's full name, including the unit-address, as an unquoted
541 : * sequence of tokens
542 : *
543 : * This macro returns removed "the quotes" from the node's full name.
544 : *
545 : * Example devicetree fragment:
546 : *
547 : * @code{.dts}
548 : * / {
549 : * soc {
550 : * node: my-node@12345678 { ... };
551 : * };
552 : * };
553 : * @endcode
554 : *
555 : * Example usage:
556 : *
557 : * @code{.c}
558 : * DT_NODE_FULL_NAME_UNQUOTED(DT_NODELABEL(node)) // my-node@12345678
559 : * @endcode
560 : *
561 : * @param node_id node identifier
562 : * @return the node's full name with unit-address as a sequence of tokens,
563 : * with no quotes
564 : */
565 1 : #define DT_NODE_FULL_NAME_UNQUOTED(node_id) DT_CAT(node_id, _FULL_NAME_UNQUOTED)
566 :
567 : /**
568 : * @brief Get the node's full name, including the unit-address, as a token.
569 : *
570 : * This macro returns removed "the quotes" from the node's full name and
571 : * converting any non-alphanumeric characters to underscores.
572 : *
573 : * Example devicetree fragment:
574 : *
575 : * @code{.dts}
576 : * / {
577 : * soc {
578 : * node: my-node@12345678 { ... };
579 : * };
580 : * };
581 : * @endcode
582 : *
583 : * Example usage:
584 : *
585 : * @code{.c}
586 : * DT_NODE_FULL_NAME_TOKEN(DT_NODELABEL(node)) // my_node_12345678
587 : * @endcode
588 : *
589 : * @param node_id node identifier
590 : * @return the node's full name with unit-address as a token, i.e. without any quotes
591 : * and with special characters converted to underscores
592 : */
593 1 : #define DT_NODE_FULL_NAME_TOKEN(node_id) DT_CAT(node_id, _FULL_NAME_TOKEN)
594 :
595 : /**
596 : * @brief Like DT_NODE_FULL_NAME_TOKEN(), but uppercased.
597 : *
598 : * This macro returns removed "the quotes" from the node's full name,
599 : * converting any non-alphanumeric characters to underscores, and
600 : * capitalizing the result.
601 : *
602 : * Example devicetree fragment:
603 : *
604 : * @code{.dts}
605 : * / {
606 : * soc {
607 : * node: my-node@12345678 { ... };
608 : * };
609 : * };
610 : * @endcode
611 : *
612 : * Example usage:
613 : *
614 : * @code{.c}
615 : * DT_NODE_FULL_NAME_UPPER_TOKEN(DT_NODELABEL(node)) // MY_NODE_12345678
616 : * @endcode
617 : *
618 : * @param node_id node identifier
619 : * @return the node's full name with unit-address as an uppercased token,
620 : * i.e. without any quotes and with special characters converted
621 : * to underscores
622 : */
623 1 : #define DT_NODE_FULL_NAME_UPPER_TOKEN(node_id) DT_CAT(node_id, _FULL_NAME_UPPER_TOKEN)
624 :
625 : /**
626 : * @brief Get a devicetree node's index into its parent's list of children
627 : *
628 : * Indexes are zero-based.
629 : *
630 : * It is an error to use this macro with the root node.
631 : *
632 : * Example devicetree fragment:
633 : *
634 : * @code{.dts}
635 : * parent {
636 : * c1: child-1 {};
637 : * c2: child-2 {};
638 : * };
639 : * @endcode
640 : *
641 : * Example usage:
642 : *
643 : * @code{.c}
644 : * DT_NODE_CHILD_IDX(DT_NODELABEL(c1)) // 0
645 : * DT_NODE_CHILD_IDX(DT_NODELABEL(c2)) // 1
646 : * @endcode
647 : *
648 : * @param node_id node identifier
649 : * @return the node's index in its parent node's list of children
650 : */
651 1 : #define DT_NODE_CHILD_IDX(node_id) DT_CAT(node_id, _CHILD_IDX)
652 :
653 : /**
654 : * @brief Get the number of child nodes of a given node
655 : *
656 : * @param node_id a node identifier
657 : * @return Number of child nodes
658 : */
659 1 : #define DT_CHILD_NUM(node_id) DT_CAT(node_id, _CHILD_NUM)
660 :
661 :
662 : /**
663 : * @brief Get the number of child nodes of a given node
664 : * which child nodes' status are okay
665 : *
666 : * @param node_id a node identifier
667 : * @return Number of child nodes which status are okay
668 : */
669 1 : #define DT_CHILD_NUM_STATUS_OKAY(node_id) \
670 : DT_CAT(node_id, _CHILD_NUM_STATUS_OKAY)
671 :
672 : /**
673 : * @brief Do @p node_id1 and @p node_id2 refer to the same node?
674 : *
675 : * Both @p node_id1 and @p node_id2 must be node identifiers for nodes
676 : * that exist in the devicetree (if unsure, you can check with
677 : * DT_NODE_EXISTS()).
678 : *
679 : * The expansion evaluates to 0 or 1, but may not be a literal integer
680 : * 0 or 1.
681 : *
682 : * @internal
683 : * Implementation note: distinct nodes have distinct node identifiers.
684 : * See include/zephyr/devicetree/ordinals.h.
685 : * @endinternal
686 : *
687 : * @param node_id1 first node identifier
688 : * @param node_id2 second node identifier
689 : * @return an expression that evaluates to 1 if the node identifiers
690 : * refer to the same node, and evaluates to 0 otherwise
691 : */
692 1 : #define DT_SAME_NODE(node_id1, node_id2) \
693 : IS_EQ(DT_DEP_ORD(node_id1), DT_DEP_ORD(node_id2))
694 :
695 : /**
696 : * @brief Get a devicetree node's node labels as an array of strings
697 : *
698 : * Example devicetree fragment:
699 : *
700 : * @code{.dts}
701 : * foo: bar: node@deadbeef {};
702 : * @endcode
703 : *
704 : * Example usage:
705 : *
706 : * @code{.c}
707 : * DT_NODELABEL_STRING_ARRAY(DT_NODELABEL(foo))
708 : * @endcode
709 : *
710 : * This expands to:
711 : *
712 : * @code{.c}
713 : * { "foo", "bar", }
714 : * @endcode
715 : *
716 : * @param node_id node identifier
717 : * @return an array initializer for an array of the node's node labels as strings
718 : */
719 1 : #define DT_NODELABEL_STRING_ARRAY(node_id) \
720 : { DT_FOREACH_NODELABEL(node_id, DT_NODELABEL_STRING_ARRAY_ENTRY_INTERNAL) }
721 :
722 : /**
723 : * @}
724 : */
725 :
726 : /**
727 : * @defgroup devicetree-generic-prop Property accessors
728 : * @ingroup devicetree
729 : * @{
730 : */
731 :
732 : /**
733 : * @brief Get a devicetree property value
734 : *
735 : * For properties whose bindings have the following types, this macro
736 : * expands to:
737 : *
738 : * - string: a string literal
739 : * - boolean: `0` if the property is false, or `1` if it is true
740 : * - int: the property's value as an integer literal
741 : * - array, uint8-array, string-array: an initializer expression in braces,
742 : * whose elements are integer or string literals (like `{0, 1, 2}`,
743 : * `{"hello", "world"}`, etc.)
744 : * - phandle: a node identifier for the node with that phandle
745 : *
746 : * A property's type is usually defined by its binding. In some
747 : * special cases, it has an assumed type defined by the devicetree
748 : * specification even when no binding is available: `compatible` has
749 : * type string-array, `status` has type string, and
750 : * `interrupt-controller` has type boolean.
751 : *
752 : * For other properties or properties with unknown type due to a
753 : * missing binding, behavior is undefined.
754 : *
755 : * For usage examples, see DT_PATH(), DT_ALIAS(), DT_NODELABEL(),
756 : * and DT_INST() above.
757 : *
758 : * @param node_id node identifier
759 : * @param prop lowercase-and-underscores property name
760 : * @return a representation of the property's value
761 : */
762 1 : #define DT_PROP(node_id, prop) DT_CAT3(node_id, _P_, prop)
763 :
764 : /**
765 : * @brief Get a property's logical length
766 : *
767 : * Here, "length" is a number of elements, which may differ from the
768 : * property's size in bytes.
769 : *
770 : * The return value depends on the property's type:
771 : *
772 : * - for types array, string-array, and uint8-array, this expands
773 : * to the number of elements in the array
774 : * - for type phandles, this expands to the number of phandles
775 : * - for type phandle-array, this expands to the number of
776 : * phandle and specifier blocks in the property
777 : * - for type phandle, this expands to 1 (so that a phandle
778 : * can be treated as a degenerate case of phandles with length 1)
779 : * - for type string, this expands to 1 (so that a string can be
780 : * treated as a degenerate case of string-array with length 1)
781 : *
782 : * These properties are handled as special cases:
783 : *
784 : * - reg property: use `DT_NUM_REGS(node_id)` instead
785 : * - interrupts property: use `DT_NUM_IRQS(node_id)` instead
786 : *
787 : * It is an error to use this macro with the `ranges`, `dma-ranges`, `reg`
788 : * or `interrupts` properties.
789 : *
790 : * For other properties, behavior is undefined.
791 : *
792 : * @param node_id node identifier
793 : * @param prop a lowercase-and-underscores property with a logical length
794 : * @return the property's length
795 : */
796 1 : #define DT_PROP_LEN(node_id, prop) DT_CAT4(node_id, _P_, prop, _LEN)
797 :
798 : /**
799 : * @brief Like DT_PROP_LEN(), but with a fallback to @p default_value
800 : *
801 : * If the property is defined (as determined by DT_NODE_HAS_PROP()),
802 : * this expands to DT_PROP_LEN(node_id, prop). The @p default_value
803 : * parameter is not expanded in this case.
804 : *
805 : * Otherwise, this expands to @p default_value.
806 : *
807 : * @param node_id node identifier
808 : * @param prop a lowercase-and-underscores property with a logical length
809 : * @param default_value a fallback value to expand to
810 : * @return the property's length or the given default value
811 : */
812 1 : #define DT_PROP_LEN_OR(node_id, prop, default_value) \
813 : COND_CODE_1(DT_NODE_HAS_PROP(node_id, prop), \
814 : (DT_PROP_LEN(node_id, prop)), (default_value))
815 :
816 : /**
817 : * @brief Is index @p idx valid for an array type property?
818 : *
819 : * If this returns 1, then DT_PROP_BY_IDX(node_id, prop, idx) or
820 : * DT_PHA_BY_IDX(node_id, prop, idx, ...) are valid at index @p idx.
821 : * If it returns 0, it is an error to use those macros with that index.
822 : *
823 : * These properties are handled as special cases:
824 : *
825 : * - `reg` property: use DT_REG_HAS_IDX(node_id, idx) instead
826 : * - `interrupts` property: use DT_IRQ_HAS_IDX(node_id, idx) instead
827 : *
828 : * It is an error to use this macro with the `reg` or `interrupts` properties.
829 : *
830 : * @param node_id node identifier
831 : * @param prop a lowercase-and-underscores property with a logical length
832 : * @param idx index to check
833 : * @return An expression which evaluates to 1 if @p idx is a valid index
834 : * into the given property, and 0 otherwise.
835 : */
836 1 : #define DT_PROP_HAS_IDX(node_id, prop, idx) \
837 : IS_ENABLED(DT_CAT6(node_id, _P_, prop, _IDX_, idx, _EXISTS))
838 :
839 : /**
840 : * @brief Is name @p name available in a `foo-names` property?
841 : *
842 : * This property is handled as special case:
843 : *
844 : * - `interrupts` property: use DT_IRQ_HAS_NAME(node_id, idx) instead
845 : *
846 : * It is an error to use this macro with the `interrupts` property.
847 : *
848 : * Example devicetree fragment:
849 : *
850 : * @code{.dts}
851 : * nx: node-x {
852 : * foos = <&bar xx yy>, <&baz xx zz>;
853 : * foo-names = "event", "error";
854 : * status = "okay";
855 : * };
856 : * @endcode
857 : *
858 : * Example usage:
859 : *
860 : * @code{.c}
861 : * DT_PROP_HAS_NAME(DT_NODELABEL(nx), foos, event) // 1
862 : * DT_PROP_HAS_NAME(DT_NODELABEL(nx), foos, failure) // 0
863 : * @endcode
864 : *
865 : * @param node_id node identifier
866 : * @param prop a lowercase-and-underscores `prop-names` type property
867 : * @param name a lowercase-and-underscores name to check
868 : * @return An expression which evaluates to 1 if "name" is an available
869 : * name into the given property, and 0 otherwise.
870 : */
871 1 : #define DT_PROP_HAS_NAME(node_id, prop, name) \
872 : IS_ENABLED(DT_CAT6(node_id, _P_, prop, _NAME_, name, _EXISTS))
873 :
874 : /**
875 : * @brief Get the value at index @p idx in an array type property
876 : *
877 : * It might help to read the argument order as being similar to
878 : * `node->property[index]`.
879 : *
880 : * The return value depends on the property's type:
881 : *
882 : * - for types array, string-array, uint8-array, and phandles,
883 : * this expands to the idx-th array element as an
884 : * integer, string literal, integer, and node identifier
885 : * respectively
886 : *
887 : * - for type phandle, idx must be 0 and the expansion is a node
888 : * identifier (this treats phandle like a phandles of length 1)
889 : *
890 : * - for type string, idx must be 0 and the expansion is the
891 : * entire string (this treats string like string-array of length 1)
892 : *
893 : * These properties are handled as special cases:
894 : *
895 : * - `reg`: use DT_REG_ADDR_BY_IDX() or DT_REG_SIZE_BY_IDX() instead
896 : * - `interrupts`: use DT_IRQ_BY_IDX()
897 : * - `ranges`: use DT_NUM_RANGES()
898 : * - `dma-ranges`: it is an error to use this property with
899 : * DT_PROP_BY_IDX()
900 : *
901 : * For properties of other types, behavior is undefined.
902 : *
903 : * @param node_id node identifier
904 : * @param prop lowercase-and-underscores property name
905 : * @param idx the index to get
906 : * @return a representation of the idx-th element of the property
907 : */
908 1 : #define DT_PROP_BY_IDX(node_id, prop, idx) \
909 : DT_CAT5(node_id, _P_, prop, _IDX_, idx)
910 :
911 : /**
912 : * @brief Get the last element of an array type property
913 : *
914 : * @param node_id node identifier
915 : * @param prop lowercase-and-underscores property name
916 : *
917 : * @return a representation of the last element of the property
918 : */
919 1 : #define DT_PROP_LAST(node_id, prop) \
920 : DT_PROP_BY_IDX(node_id, prop, UTIL_DEC(DT_PROP_LEN(node_id, prop)))
921 :
922 : /**
923 : * @brief Like DT_PROP(), but with a fallback to @p default_value
924 : *
925 : * If the value exists, this expands to DT_PROP(node_id, prop).
926 : * The @p default_value parameter is not expanded in this case.
927 : *
928 : * Otherwise, this expands to @p default_value.
929 : *
930 : * @param node_id node identifier
931 : * @param prop lowercase-and-underscores property name
932 : * @param default_value a fallback value to expand to
933 : * @return the property's value or @p default_value
934 : */
935 1 : #define DT_PROP_OR(node_id, prop, default_value) \
936 : COND_CODE_1(DT_NODE_HAS_PROP(node_id, prop), \
937 : (DT_PROP(node_id, prop)), (default_value))
938 :
939 : /**
940 : * @brief Get a property array value's index into its enumeration values
941 : *
942 : * The return values start at zero.
943 : *
944 : * Example devicetree fragment:
945 : *
946 : * @code{.dts}
947 : * some_node: some-node {
948 : * compat = "vend,enum-string-array";
949 : * foos =
950 : * <&phandle val1>,
951 : * <&phandle val2>,
952 : * <&phandle val3>;
953 : * foo-names = "default", "option3", "option1";
954 : * };
955 : * @endcode
956 : *
957 : * Example bindings fragment:
958 : *
959 : * @code{.yaml}
960 : * compatible: vend,enum-string-array
961 : * properties:
962 : * foos:
963 : * type: phandle-array
964 : * description: |
965 : * Explanation about what this phandle-array exactly is for.
966 : *
967 : * foo-names:
968 : * type: string-array
969 : * description: |
970 : * Some explanation about the available options
971 : * default: explain default
972 : * option1: explain option1
973 : * option2: explain option2
974 : * option3: explain option3
975 : * enum:
976 : * - default
977 : * - option1
978 : * - option2
979 : * - option3
980 : * @endcode
981 : *
982 : * Example usage:
983 : *
984 : * @code{.c}
985 : * DT_ENUM_IDX_BY_IDX(DT_NODELABEL(some_node), foo_names, 0) // 0
986 : * DT_ENUM_IDX_BY_IDX(DT_NODELABEL(some_node), foo_names, 2) // 1
987 : * @endcode
988 : *
989 : * @param node_id node identifier
990 : * @param prop lowercase-and-underscores property name
991 : * @param idx the index to get
992 : * @return zero-based index of the property's value in its enum: list
993 : */
994 1 : #define DT_ENUM_IDX_BY_IDX(node_id, prop, idx) \
995 : DT_CAT6(node_id, _P_, prop, _IDX_, idx, _ENUM_IDX)
996 :
997 : /**
998 : * @brief Equivalent to @ref DT_ENUM_IDX_BY_IDX(node_id, prop, 0).
999 : * @param node_id node identifier
1000 : * @param prop lowercase-and-underscores property name
1001 : * @return zero-based index of the property's value in its enum: list
1002 : */
1003 1 : #define DT_ENUM_IDX(node_id, prop) DT_ENUM_IDX_BY_IDX(node_id, prop, 0)
1004 :
1005 : /**
1006 : * @brief Like DT_ENUM_IDX_BY_IDX(), but with a fallback to a default enum index
1007 : *
1008 : * If the value exists, this expands to its zero based index value thanks to
1009 : * DT_ENUM_IDX_BY_IDX(node_id, prop, idx).
1010 : *
1011 : * Otherwise, this expands to provided default index enum value.
1012 : *
1013 : * @param node_id node identifier
1014 : * @param prop lowercase-and-underscores property name
1015 : * @param idx the index to get
1016 : * @param default_idx_value a fallback index value to expand to
1017 : * @return zero-based index of the property's value in its enum if present,
1018 : * default_idx_value otherwise
1019 : */
1020 1 : #define DT_ENUM_IDX_BY_IDX_OR(node_id, prop, idx, default_idx_value) \
1021 : COND_CODE_1(DT_PROP_HAS_IDX(node_id, prop, idx), \
1022 : (DT_ENUM_IDX_BY_IDX(node_id, prop, idx)), (default_idx_value))
1023 :
1024 : /**
1025 : * @brief Equivalent to DT_ENUM_IDX_BY_IDX_OR(node_id, prop, 0, default_idx_value).
1026 : * @param node_id node identifier
1027 : * @param prop lowercase-and-underscores property name
1028 : * @param default_idx_value a fallback index value to expand to
1029 : * @return zero-based index of the property's value in its enum if present,
1030 : * default_idx_value otherwise
1031 : */
1032 1 : #define DT_ENUM_IDX_OR(node_id, prop, default_idx_value) \
1033 : DT_ENUM_IDX_BY_IDX_OR(node_id, prop, 0, default_idx_value)
1034 :
1035 : /**
1036 : * @brief Does a node enumeration property array have a given value?
1037 : *
1038 : * @param node_id node identifier
1039 : * @param prop lowercase-and-underscores property name
1040 : * @param idx the index to get
1041 : * @param value lowercase-and-underscores enumeration value
1042 : * @return 1 if the node property has the value @a value, 0 otherwise.
1043 : */
1044 1 : #define DT_ENUM_HAS_VALUE_BY_IDX(node_id, prop, idx, value) \
1045 : IS_ENABLED(DT_CAT8(node_id, _P_, prop, _IDX_, idx, _ENUM_VAL_, value, _EXISTS))
1046 :
1047 : /**
1048 : * @brief Does a node enumeration property have a given value?
1049 : * @param node_id node identifier
1050 : * @param prop lowercase-and-underscores property name
1051 : * @param value lowercase-and-underscores enumeration value
1052 : * @return 1 if the node property has the value @a value, 0 otherwise.
1053 : */
1054 1 : #define DT_ENUM_HAS_VALUE(node_id, prop, value) \
1055 : IS_ENABLED(DT_CAT6(node_id, _P_, prop, _ENUM_VAL_, value, _EXISTS))
1056 :
1057 : /**
1058 : * @brief Get a string property's value as a token.
1059 : *
1060 : * This removes "the quotes" from a string property's value,
1061 : * converting any non-alphanumeric characters to underscores. This can
1062 : * be useful, for example, when programmatically using the value to
1063 : * form a C variable or code.
1064 : *
1065 : * DT_STRING_TOKEN() can only be used for properties with string type.
1066 : *
1067 : * It is an error to use DT_STRING_TOKEN() in other circumstances.
1068 : *
1069 : * Example devicetree fragment:
1070 : *
1071 : * @code{.dts}
1072 : * n1: node-1 {
1073 : * prop = "foo";
1074 : * };
1075 : * n2: node-2 {
1076 : * prop = "FOO";
1077 : * }
1078 : * n3: node-3 {
1079 : * prop = "123 foo";
1080 : * };
1081 : * @endcode
1082 : *
1083 : * Example bindings fragment:
1084 : *
1085 : * @code{.yaml}
1086 : * properties:
1087 : * prop:
1088 : * type: string
1089 : * @endcode
1090 : *
1091 : * Example usage:
1092 : *
1093 : * @code{.c}
1094 : * DT_STRING_TOKEN(DT_NODELABEL(n1), prop) // foo
1095 : * DT_STRING_TOKEN(DT_NODELABEL(n2), prop) // FOO
1096 : * DT_STRING_TOKEN(DT_NODELABEL(n3), prop) // 123_foo
1097 : * @endcode
1098 : *
1099 : * Notice how:
1100 : *
1101 : * - Unlike C identifiers, the property values may begin with a
1102 : * number. It's the user's responsibility not to use such values as
1103 : * the name of a C identifier.
1104 : *
1105 : * - The uppercased `"FOO"` in the DTS remains `FOO` as a token. It is
1106 : * *not* converted to `foo`.
1107 : *
1108 : * - The whitespace in the DTS `"123 foo"` string is converted to
1109 : * `123_foo` as a token.
1110 : *
1111 : * @param node_id node identifier
1112 : * @param prop lowercase-and-underscores property name
1113 : * @return the value of @p prop as a token, i.e. without any quotes
1114 : * and with special characters converted to underscores
1115 : */
1116 1 : #define DT_STRING_TOKEN(node_id, prop) \
1117 : DT_CAT4(node_id, _P_, prop, _STRING_TOKEN)
1118 :
1119 : /**
1120 : * @brief Like DT_STRING_TOKEN(), but with a fallback to @p default_value
1121 : *
1122 : * If the value exists, this expands to DT_STRING_TOKEN(node_id, prop).
1123 : * The @p default_value parameter is not expanded in this case.
1124 : *
1125 : * Otherwise, this expands to @p default_value.
1126 : *
1127 : * @param node_id node identifier
1128 : * @param prop lowercase-and-underscores property name
1129 : * @param default_value a fallback value to expand to
1130 : * @return the property's value as a token, or @p default_value
1131 : */
1132 1 : #define DT_STRING_TOKEN_OR(node_id, prop, default_value) \
1133 : COND_CODE_1(DT_NODE_HAS_PROP(node_id, prop), \
1134 : (DT_STRING_TOKEN(node_id, prop)), (default_value))
1135 :
1136 : /**
1137 : * @brief Like DT_STRING_TOKEN(), but uppercased.
1138 : *
1139 : * This removes "the quotes" from a string property's value,
1140 : * converting any non-alphanumeric characters to underscores, and
1141 : * capitalizing the result. This can be useful, for example, when
1142 : * programmatically using the value to form a C variable or code.
1143 : *
1144 : * DT_STRING_UPPER_TOKEN() can only be used for properties with string type.
1145 : *
1146 : * It is an error to use DT_STRING_UPPER_TOKEN() in other circumstances.
1147 : *
1148 : * Example devicetree fragment:
1149 : *
1150 : * @code{.dts}
1151 : * n1: node-1 {
1152 : * prop = "foo";
1153 : * };
1154 : * n2: node-2 {
1155 : * prop = "123 foo";
1156 : * };
1157 : * @endcode
1158 : *
1159 : * Example bindings fragment:
1160 : *
1161 : * @code{.yaml}
1162 : * properties:
1163 : * prop:
1164 : * type: string
1165 : *
1166 : * @endcode
1167 : *
1168 : * Example usage:
1169 : *
1170 : * @code{.c}
1171 : * DT_STRING_UPPER_TOKEN(DT_NODELABEL(n1), prop) // FOO
1172 : * DT_STRING_UPPER_TOKEN(DT_NODELABEL(n2), prop) // 123_FOO
1173 : * @endcode
1174 : *
1175 : * Notice how:
1176 : *
1177 : * - Unlike C identifiers, the property values may begin with a
1178 : * number. It's the user's responsibility not to use such values as
1179 : * the name of a C identifier.
1180 : *
1181 : * - The lowercased `"foo"` in the DTS becomes `FOO` as a token, i.e.
1182 : * it is uppercased.
1183 : *
1184 : * - The whitespace in the DTS `"123 foo"` string is converted to
1185 : * `123_FOO` as a token, i.e. it is uppercased and whitespace becomes
1186 : * an underscore.
1187 : *
1188 : * @param node_id node identifier
1189 : * @param prop lowercase-and-underscores property name
1190 : * @return the value of @p prop as an uppercased token, i.e. without
1191 : * any quotes and with special characters converted to underscores
1192 : */
1193 1 : #define DT_STRING_UPPER_TOKEN(node_id, prop) \
1194 : DT_CAT4(node_id, _P_, prop, _STRING_UPPER_TOKEN)
1195 :
1196 : /**
1197 : * @brief Like DT_STRING_UPPER_TOKEN(), but with a fallback to @p default_value
1198 : *
1199 : * If the value exists, this expands to DT_STRING_UPPER_TOKEN(node_id, prop).
1200 : * The @p default_value parameter is not expanded in this case.
1201 : *
1202 : * Otherwise, this expands to @p default_value.
1203 : *
1204 : * @param node_id node identifier
1205 : * @param prop lowercase-and-underscores property name
1206 : * @param default_value a fallback value to expand to
1207 : * @return the property's value as an uppercased token,
1208 : * or @p default_value
1209 : */
1210 1 : #define DT_STRING_UPPER_TOKEN_OR(node_id, prop, default_value) \
1211 : COND_CODE_1(DT_NODE_HAS_PROP(node_id, prop), \
1212 : (DT_STRING_UPPER_TOKEN(node_id, prop)), (default_value))
1213 :
1214 : /**
1215 : * @brief Get a string property's value as an unquoted sequence of tokens
1216 : *
1217 : * This removes "the quotes" from string-valued properties.
1218 : * That can be useful, for example,
1219 : * when defining floating point values as a string in devicetree
1220 : * that you would like to use to initialize a float or double variable in C.
1221 : *
1222 : * DT_STRING_UNQUOTED() can only be used for properties with string type.
1223 : *
1224 : * It is an error to use DT_STRING_UNQUOTED() in other circumstances.
1225 : *
1226 : * Example devicetree fragment:
1227 : *
1228 : * n1: node-1 {
1229 : * prop = "12.7";
1230 : * };
1231 : * n2: node-2 {
1232 : * prop = "0.5";
1233 : * }
1234 : * n3: node-3 {
1235 : * prop = "A B C";
1236 : * };
1237 : *
1238 : * Example bindings fragment:
1239 : *
1240 : * properties:
1241 : * prop:
1242 : * type: string
1243 : *
1244 : * Example usage:
1245 : *
1246 : * DT_STRING_UNQUOTED(DT_NODELABEL(n1), prop) // 12.7
1247 : * DT_STRING_UNQUOTED(DT_NODELABEL(n2), prop) // 0.5
1248 : * DT_STRING_UNQUOTED(DT_NODELABEL(n3), prop) // A B C
1249 : *
1250 : * @param node_id node identifier
1251 : * @param prop lowercase-and-underscores property name
1252 : * @return the property's value as a sequence of tokens, with no quotes
1253 : */
1254 1 : #define DT_STRING_UNQUOTED(node_id, prop) \
1255 : DT_CAT4(node_id, _P_, prop, _STRING_UNQUOTED)
1256 :
1257 : /**
1258 : * @brief Like DT_STRING_UNQUOTED(), but with a fallback to @p default_value
1259 : *
1260 : * If the value exists, this expands to DT_STRING_UNQUOTED(node_id, prop).
1261 : * The @p default_value parameter is not expanded in this case.
1262 : *
1263 : * Otherwise, this expands to @p default_value.
1264 : *
1265 : * @param node_id node identifier
1266 : * @param prop lowercase-and-underscores property name
1267 : * @param default_value a fallback value to expand to
1268 : * @return the property's value as a sequence of tokens, with no quotes,
1269 : * or @p default_value
1270 : */
1271 1 : #define DT_STRING_UNQUOTED_OR(node_id, prop, default_value) \
1272 : COND_CODE_1(DT_NODE_HAS_PROP(node_id, prop), \
1273 : (DT_STRING_UNQUOTED(node_id, prop)), (default_value))
1274 :
1275 : /**
1276 : * @brief Get an element out of a string-array property as a token.
1277 : *
1278 : * This removes "the quotes" from an element in the array, and converts
1279 : * non-alphanumeric characters to underscores. That can be useful, for example,
1280 : * when programmatically using the value to form a C variable or code.
1281 : *
1282 : * DT_STRING_TOKEN_BY_IDX() can only be used for properties with
1283 : * string-array type.
1284 : *
1285 : * It is an error to use DT_STRING_TOKEN_BY_IDX() in other circumstances.
1286 : *
1287 : * Example devicetree fragment:
1288 : *
1289 : * @code{.dts}
1290 : * n1: node-1 {
1291 : * prop = "f1", "F2";
1292 : * };
1293 : * n2: node-2 {
1294 : * prop = "123 foo", "456 FOO";
1295 : * };
1296 : * @endcode
1297 : *
1298 : * Example bindings fragment:
1299 : *
1300 : * @code{.yaml}
1301 : * properties:
1302 : * prop:
1303 : * type: string-array
1304 : * @endcode
1305 : *
1306 : * Example usage:
1307 : *
1308 : * @code{.c}
1309 : * DT_STRING_TOKEN_BY_IDX(DT_NODELABEL(n1), prop, 0) // f1
1310 : * DT_STRING_TOKEN_BY_IDX(DT_NODELABEL(n1), prop, 1) // F2
1311 : * DT_STRING_TOKEN_BY_IDX(DT_NODELABEL(n2), prop, 0) // 123_foo
1312 : * DT_STRING_TOKEN_BY_IDX(DT_NODELABEL(n2), prop, 1) // 456_FOO
1313 : * @endcode
1314 : *
1315 : * For more information, see @ref DT_STRING_TOKEN.
1316 : *
1317 : * @param node_id node identifier
1318 : * @param prop lowercase-and-underscores property name
1319 : * @param idx the index to get
1320 : * @return the element in @p prop at index @p idx as a token
1321 : */
1322 1 : #define DT_STRING_TOKEN_BY_IDX(node_id, prop, idx) \
1323 : DT_CAT6(node_id, _P_, prop, _IDX_, idx, _STRING_TOKEN)
1324 :
1325 : /**
1326 : * @brief Like DT_STRING_TOKEN_BY_IDX(), but uppercased.
1327 : *
1328 : * This removes "the quotes" and capitalizes an element in the array, and
1329 : * converts non-alphanumeric characters to underscores. That can be useful, for
1330 : * example, when programmatically using the value to form a C variable or code.
1331 : *
1332 : * DT_STRING_UPPER_TOKEN_BY_IDX() can only be used for properties with
1333 : * string-array type.
1334 : *
1335 : * It is an error to use DT_STRING_UPPER_TOKEN_BY_IDX() in other circumstances.
1336 : *
1337 : * Example devicetree fragment:
1338 : *
1339 : * @code{.dts}
1340 : * n1: node-1 {
1341 : * prop = "f1", "F2";
1342 : * };
1343 : * n2: node-2 {
1344 : * prop = "123 foo", "456 FOO";
1345 : * };
1346 : * @endcode
1347 : *
1348 : * Example bindings fragment:
1349 : *
1350 : * @code{.yaml}
1351 : * properties:
1352 : * prop:
1353 : * type: string-array
1354 : * @endcode
1355 : *
1356 : * Example usage:
1357 : *
1358 : * @code{.c}
1359 : * DT_STRING_UPPER_TOKEN_BY_IDX(DT_NODELABEL(n1), prop, 0) // F1
1360 : * DT_STRING_UPPER_TOKEN_BY_IDX(DT_NODELABEL(n1), prop, 1) // F2
1361 : * DT_STRING_UPPER_TOKEN_BY_IDX(DT_NODELABEL(n2), prop, 0) // 123_FOO
1362 : * DT_STRING_UPPER_TOKEN_BY_IDX(DT_NODELABEL(n2), prop, 1) // 456_FOO
1363 : * @endcode
1364 : *
1365 : * For more information, see @ref DT_STRING_UPPER_TOKEN.
1366 : *
1367 : * @param node_id node identifier
1368 : * @param prop lowercase-and-underscores property name
1369 : * @param idx the index to get
1370 : * @return the element in @p prop at index @p idx as an uppercased token
1371 : */
1372 1 : #define DT_STRING_UPPER_TOKEN_BY_IDX(node_id, prop, idx) \
1373 : DT_CAT6(node_id, _P_, prop, _IDX_, idx, _STRING_UPPER_TOKEN)
1374 :
1375 : /**
1376 : * @brief Get a string array item value as an unquoted sequence of tokens.
1377 : *
1378 : * This removes "the quotes" from string-valued item.
1379 : * That can be useful, for example,
1380 : * when defining floating point values as a string in devicetree
1381 : * that you would like to use to initialize a float or double variable in C.
1382 : *
1383 : * DT_STRING_UNQUOTED_BY_IDX() can only be used for properties with
1384 : * string-array type.
1385 : *
1386 : * It is an error to use DT_STRING_UNQUOTED_BY_IDX() in other circumstances.
1387 : *
1388 : * Example devicetree fragment:
1389 : *
1390 : * n1: node-1 {
1391 : * prop = "12.7", "34.1";
1392 : * };
1393 : * n2: node-2 {
1394 : * prop = "A B", "C D";
1395 : * }
1396 : *
1397 : * Example bindings fragment:
1398 : *
1399 : * properties:
1400 : * prop:
1401 : * type: string-array
1402 : *
1403 : * Example usage:
1404 : *
1405 : * DT_STRING_UNQUOTED_BY_IDX(DT_NODELABEL(n1), prop, 0) // 12.7
1406 : * DT_STRING_UNQUOTED_BY_IDX(DT_NODELABEL(n1), prop, 1) // 34.1
1407 : * DT_STRING_UNQUOTED_BY_IDX(DT_NODELABEL(n2), prop, 0) // A B
1408 : * DT_STRING_UNQUOTED_BY_IDX(DT_NODELABEL(n2), prop, 1) // C D
1409 : *
1410 : * @param node_id node identifier
1411 : * @param prop lowercase-and-underscores property name
1412 : * @param idx the index to get
1413 : * @return the property's value as a sequence of tokens, with no quotes
1414 : */
1415 1 : #define DT_STRING_UNQUOTED_BY_IDX(node_id, prop, idx) \
1416 : DT_CAT6(node_id, _P_, prop, _IDX_, idx, _STRING_UNQUOTED)
1417 :
1418 : /*
1419 : * phandle properties
1420 : *
1421 : * These are special-cased to manage the impedance mismatch between
1422 : * phandles, which are just uint32_t node properties that only make sense
1423 : * within the tree itself, and C values.
1424 : */
1425 :
1426 : /**
1427 : * @brief Get a property value from a phandle in a property.
1428 : *
1429 : * This is a shorthand for:
1430 : *
1431 : * @code{.c}
1432 : * DT_PROP(DT_PHANDLE_BY_IDX(node_id, phs, idx), prop)
1433 : * @endcode
1434 : *
1435 : * That is, @p prop is a property of the phandle's node, not a
1436 : * property of @p node_id.
1437 : *
1438 : * Example devicetree fragment:
1439 : *
1440 : * @code{.dts}
1441 : * n1: node-1 {
1442 : * foo = <&n2 &n3>;
1443 : * };
1444 : *
1445 : * n2: node-2 {
1446 : * bar = <42>;
1447 : * };
1448 : *
1449 : * n3: node-3 {
1450 : * baz = <43>;
1451 : * };
1452 : * @endcode
1453 : *
1454 : * Example usage:
1455 : *
1456 : * @code{.c}
1457 : * #define N1 DT_NODELABEL(n1)
1458 : *
1459 : * DT_PROP_BY_PHANDLE_IDX(N1, foo, 0, bar) // 42
1460 : * DT_PROP_BY_PHANDLE_IDX(N1, foo, 1, baz) // 43
1461 : * @endcode
1462 : *
1463 : * @param node_id node identifier
1464 : * @param phs lowercase-and-underscores property with type `phandle`,
1465 : * `phandles`, or `phandle-array`
1466 : * @param idx logical index into @p phs, which must be zero if @p phs
1467 : * has type `phandle`
1468 : * @param prop lowercase-and-underscores property of the phandle's node
1469 : * @return the property's value
1470 : */
1471 1 : #define DT_PROP_BY_PHANDLE_IDX(node_id, phs, idx, prop) \
1472 : DT_PROP(DT_PHANDLE_BY_IDX(node_id, phs, idx), prop)
1473 :
1474 : /**
1475 : * @brief Like DT_PROP_BY_PHANDLE_IDX(), but with a fallback to
1476 : * @p default_value.
1477 : *
1478 : * If the value exists, this expands to DT_PROP_BY_PHANDLE_IDX(node_id, phs,
1479 : * idx, prop). The @p default_value parameter is not expanded in this
1480 : * case.
1481 : *
1482 : * Otherwise, this expands to @p default_value.
1483 : *
1484 : * @param node_id node identifier
1485 : * @param phs lowercase-and-underscores property with type `phandle`,
1486 : * `phandles`, or `phandle-array`
1487 : * @param idx logical index into @p phs, which must be zero if @p phs
1488 : * has type `phandle`
1489 : * @param prop lowercase-and-underscores property of the phandle's node
1490 : * @param default_value a fallback value to expand to
1491 : * @return the property's value
1492 : */
1493 1 : #define DT_PROP_BY_PHANDLE_IDX_OR(node_id, phs, idx, prop, default_value) \
1494 : DT_PROP_OR(DT_PHANDLE_BY_IDX(node_id, phs, idx), prop, default_value)
1495 :
1496 : /**
1497 : * @brief Get a property value from a phandle's node
1498 : *
1499 : * This is equivalent to DT_PROP_BY_PHANDLE_IDX(node_id, ph, 0, prop).
1500 : *
1501 : * @param node_id node identifier
1502 : * @param ph lowercase-and-underscores property of @p node_id
1503 : * with type `phandle`
1504 : * @param prop lowercase-and-underscores property of the phandle's node
1505 : * @return the property's value
1506 : */
1507 1 : #define DT_PROP_BY_PHANDLE(node_id, ph, prop) \
1508 : DT_PROP_BY_PHANDLE_IDX(node_id, ph, 0, prop)
1509 :
1510 : /**
1511 : * @brief Get a phandle-array specifier cell value at an index
1512 : *
1513 : * It might help to read the argument order as being similar to
1514 : * `node->phandle_array[index].cell`. That is, the cell value is in
1515 : * the @p pha property of @p node_id, inside the specifier at index
1516 : * @p idx.
1517 : *
1518 : * Example devicetree fragment:
1519 : *
1520 : * @code{.dts}
1521 : * gpio0: gpio@abcd1234 {
1522 : * #gpio-cells = <2>;
1523 : * };
1524 : *
1525 : * gpio1: gpio@1234abcd {
1526 : * #gpio-cells = <2>;
1527 : * };
1528 : *
1529 : * led: led_0 {
1530 : * gpios = <&gpio0 17 0x1>, <&gpio1 5 0x3>;
1531 : * };
1532 : * @endcode
1533 : *
1534 : * Bindings fragment for the `gpio0` and `gpio1` nodes:
1535 : *
1536 : * @code{.yaml}
1537 : * gpio-cells:
1538 : * - pin
1539 : * - flags
1540 : * @endcode
1541 : *
1542 : * Above, `gpios` has two elements:
1543 : *
1544 : * - index 0 has specifier <17 0x1>, so its `pin` cell is 17, and its
1545 : * `flags` cell is 0x1
1546 : * - index 1 has specifier <5 0x3>, so `pin` is 5 and `flags` is 0x3
1547 : *
1548 : * Example usage:
1549 : *
1550 : * @code{.c}
1551 : * #define LED DT_NODELABEL(led)
1552 : *
1553 : * DT_PHA_BY_IDX(LED, gpios, 0, pin) // 17
1554 : * DT_PHA_BY_IDX(LED, gpios, 1, flags) // 0x3
1555 : * @endcode
1556 : *
1557 : * @param node_id node identifier
1558 : * @param pha lowercase-and-underscores property with type `phandle-array`
1559 : * @param idx logical index into @p pha
1560 : * @param cell lowercase-and-underscores cell name within the specifier
1561 : * at @p pha index @p idx
1562 : * @return the cell's value
1563 : */
1564 1 : #define DT_PHA_BY_IDX(node_id, pha, idx, cell) \
1565 : DT_CAT7(node_id, _P_, pha, _IDX_, idx, _VAL_, cell)
1566 :
1567 : /**
1568 : * @brief Like DT_PHA_BY_IDX(), but with a fallback to @p default_value.
1569 : *
1570 : * If the value exists, this expands to DT_PHA_BY_IDX(node_id, pha,
1571 : * idx, cell). The @p default_value parameter is not expanded in this
1572 : * case.
1573 : *
1574 : * Otherwise, this expands to @p default_value.
1575 : *
1576 : * @internal
1577 : * Implementation note: the _IDX_##idx##_VAL_##cell##_EXISTS macros are
1578 : * defined, so it's safe to use DT_PROP_OR() here, because that uses an
1579 : * IS_ENABLED() on the _EXISTS macro.
1580 : * @endinternal
1581 : *
1582 : * @param node_id node identifier
1583 : * @param pha lowercase-and-underscores property with type `phandle-array`
1584 : * @param idx logical index into @p pha
1585 : * @param cell lowercase-and-underscores cell name within the specifier
1586 : * at @p pha index @p idx
1587 : * @param default_value a fallback value to expand to
1588 : * @return the cell's value or @p default_value
1589 : */
1590 1 : #define DT_PHA_BY_IDX_OR(node_id, pha, idx, cell, default_value) \
1591 : DT_PROP_OR(node_id, DT_CAT5(pha, _IDX_, idx, _VAL_, cell), default_value)
1592 :
1593 : /**
1594 : * @brief Equivalent to DT_PHA_BY_IDX(node_id, pha, 0, cell)
1595 : * @param node_id node identifier
1596 : * @param pha lowercase-and-underscores property with type `phandle-array`
1597 : * @param cell lowercase-and-underscores cell name
1598 : * @return the cell's value
1599 : */
1600 1 : #define DT_PHA(node_id, pha, cell) DT_PHA_BY_IDX(node_id, pha, 0, cell)
1601 :
1602 : /**
1603 : * @brief Like DT_PHA(), but with a fallback to @p default_value
1604 : *
1605 : * If the value exists, this expands to DT_PHA(node_id, pha, cell).
1606 : * The @p default_value parameter is not expanded in this case.
1607 : *
1608 : * Otherwise, this expands to @p default_value.
1609 : *
1610 : * @param node_id node identifier
1611 : * @param pha lowercase-and-underscores property with type `phandle-array`
1612 : * @param cell lowercase-and-underscores cell name
1613 : * @param default_value a fallback value to expand to
1614 : * @return the cell's value or @p default_value
1615 : */
1616 1 : #define DT_PHA_OR(node_id, pha, cell, default_value) \
1617 : DT_PHA_BY_IDX_OR(node_id, pha, 0, cell, default_value)
1618 :
1619 : /**
1620 : * @brief Get a value within a phandle-array specifier by name
1621 : *
1622 : * This is like DT_PHA_BY_IDX(), except it treats @p pha as a structure
1623 : * where each array element has a name.
1624 : *
1625 : * It might help to read the argument order as being similar to
1626 : * `node->phandle_struct.name.cell`. That is, the cell value is in the
1627 : * @p pha property of @p node_id, treated as a data structure where
1628 : * each array element has a name.
1629 : *
1630 : * Example devicetree fragment:
1631 : *
1632 : * @code{.dts}
1633 : * n: node {
1634 : * io-channels = <&adc1 10>, <&adc2 20>;
1635 : * io-channel-names = "SENSOR", "BANDGAP";
1636 : * };
1637 : * @endcode
1638 : *
1639 : * Bindings fragment for the "adc1" and "adc2" nodes:
1640 : *
1641 : * @code{.yaml}
1642 : * io-channel-cells:
1643 : * - input
1644 : * @endcode
1645 : *
1646 : * Example usage:
1647 : *
1648 : * @code{.c}
1649 : * DT_PHA_BY_NAME(DT_NODELABEL(n), io_channels, sensor, input) // 10
1650 : * DT_PHA_BY_NAME(DT_NODELABEL(n), io_channels, bandgap, input) // 20
1651 : * @endcode
1652 : *
1653 : * @param node_id node identifier
1654 : * @param pha lowercase-and-underscores property with type `phandle-array`
1655 : * @param name lowercase-and-underscores name of a specifier in @p pha
1656 : * @param cell lowercase-and-underscores cell name in the named specifier
1657 : * @return the cell's value
1658 : */
1659 1 : #define DT_PHA_BY_NAME(node_id, pha, name, cell) \
1660 : DT_CAT7(node_id, _P_, pha, _NAME_, name, _VAL_, cell)
1661 :
1662 : /**
1663 : * @brief Like DT_PHA_BY_NAME(), but with a fallback to @p default_value
1664 : *
1665 : * If the value exists, this expands to DT_PHA_BY_NAME(node_id, pha,
1666 : * name, cell). The @p default_value parameter is not expanded in this case.
1667 : *
1668 : * Otherwise, this expands to @p default_value.
1669 : *
1670 : * @internal
1671 : * Implementation note: the `_NAME_##name##_VAL_##cell##_EXISTS` macros are
1672 : * defined, so it's safe to use DT_PROP_OR() here, because that uses an
1673 : * IS_ENABLED() on the `_EXISTS` macro.
1674 : * @endinternal
1675 : *
1676 : * @param node_id node identifier
1677 : * @param pha lowercase-and-underscores property with type `phandle-array`
1678 : * @param name lowercase-and-underscores name of a specifier in @p pha
1679 : * @param cell lowercase-and-underscores cell name in the named specifier
1680 : * @param default_value a fallback value to expand to
1681 : * @return the cell's value or @p default_value
1682 : */
1683 1 : #define DT_PHA_BY_NAME_OR(node_id, pha, name, cell, default_value) \
1684 : DT_PROP_OR(node_id, DT_CAT5(pha, _NAME_, name, _VAL_, cell), default_value)
1685 :
1686 : /**
1687 : * @brief Get a phandle's node identifier from a phandle array by @p name
1688 : *
1689 : * It might help to read the argument order as being similar to
1690 : * `node->phandle_struct.name.phandle`. That is, the phandle array is
1691 : * treated as a structure with named elements. The return value is
1692 : * the node identifier for a phandle inside the structure.
1693 : *
1694 : * Example devicetree fragment:
1695 : *
1696 : * @code{.dts}
1697 : * adc1: adc@abcd1234 {
1698 : * foobar = "ADC_1";
1699 : * };
1700 : *
1701 : * adc2: adc@1234abcd {
1702 : * foobar = "ADC_2";
1703 : * };
1704 : *
1705 : * n: node {
1706 : * io-channels = <&adc1 10>, <&adc2 20>;
1707 : * io-channel-names = "SENSOR", "BANDGAP";
1708 : * };
1709 : * @endcode
1710 : *
1711 : * Above, "io-channels" has two elements:
1712 : *
1713 : * - the element named `"SENSOR"` has phandle `&adc1`
1714 : * - the element named `"BANDGAP"` has phandle `&adc2`
1715 : *
1716 : * Example usage:
1717 : *
1718 : * @code{.c}
1719 : * #define NODE DT_NODELABEL(n)
1720 : *
1721 : * DT_PROP(DT_PHANDLE_BY_NAME(NODE, io_channels, sensor), foobar) // "ADC_1"
1722 : * DT_PROP(DT_PHANDLE_BY_NAME(NODE, io_channels, bandgap), foobar) // "ADC_2"
1723 : * @endcode
1724 : *
1725 : * Notice how devicetree properties and names are lowercased, and
1726 : * non-alphanumeric characters are converted to underscores.
1727 : *
1728 : * @param node_id node identifier
1729 : * @param pha lowercase-and-underscores property with type `phandle-array`
1730 : * @param name lowercase-and-underscores name of an element in @p pha
1731 : * @return a node identifier for the node with that phandle
1732 : */
1733 1 : #define DT_PHANDLE_BY_NAME(node_id, pha, name) \
1734 : DT_CAT6(node_id, _P_, pha, _NAME_, name, _PH)
1735 :
1736 : /**
1737 : * @brief Get a node identifier for a phandle in a property.
1738 : *
1739 : * When a node's value at a logical index contains a phandle, this
1740 : * macro returns a node identifier for the node with that phandle.
1741 : *
1742 : * Therefore, if @p prop has type `phandle`, @p idx must be zero. (A
1743 : * `phandle` type is treated as a `phandles` with a fixed length of
1744 : * 1).
1745 : *
1746 : * Example devicetree fragment:
1747 : *
1748 : * @code{.dts}
1749 : * n1: node-1 {
1750 : * foo = <&n2 &n3>;
1751 : * };
1752 : *
1753 : * n2: node-2 { ... };
1754 : * n3: node-3 { ... };
1755 : * @endcode
1756 : *
1757 : * Above, `foo` has type phandles and has two elements:
1758 : *
1759 : * - index 0 has phandle `&n2`, which is `node-2`'s phandle
1760 : * - index 1 has phandle `&n3`, which is `node-3`'s phandle
1761 : *
1762 : * Example usage:
1763 : *
1764 : * @code{.c}
1765 : * #define N1 DT_NODELABEL(n1)
1766 : *
1767 : * DT_PHANDLE_BY_IDX(N1, foo, 0) // node identifier for node-2
1768 : * DT_PHANDLE_BY_IDX(N1, foo, 1) // node identifier for node-3
1769 : * @endcode
1770 : *
1771 : * Behavior is analogous for phandle-arrays.
1772 : *
1773 : * @internal
1774 : * Implementation note: using DT_CAT6 above defers concatenation until
1775 : * after expansion of each parameter. This is important when 'idx' is
1776 : * expandable to a number, but it isn't one "yet".
1777 : * @endinternal
1778 : *
1779 : * @param node_id node identifier
1780 : * @param prop lowercase-and-underscores property name in @p node_id
1781 : * with type `phandle`, `phandles` or `phandle-array`
1782 : * @param idx index into @p prop
1783 : * @return node identifier for the node with the phandle at that index
1784 : */
1785 1 : #define DT_PHANDLE_BY_IDX(node_id, prop, idx) \
1786 : DT_CAT6(node_id, _P_, prop, _IDX_, idx, _PH)
1787 :
1788 : /**
1789 : * @brief Get a node identifier for a phandle property's value
1790 : *
1791 : * This is equivalent to DT_PHANDLE_BY_IDX(node_id, prop, 0). Its primary
1792 : * benefit is readability when @p prop has type `phandle`.
1793 : *
1794 : * @param node_id node identifier
1795 : * @param prop lowercase-and-underscores property of @p node_id
1796 : * with type `phandle`
1797 : * @return a node identifier for the node pointed to by "ph"
1798 : */
1799 1 : #define DT_PHANDLE(node_id, prop) DT_PHANDLE_BY_IDX(node_id, prop, 0)
1800 :
1801 : /**
1802 : * @}
1803 : */
1804 :
1805 : /**
1806 : * @defgroup devicetree-ranges-prop ranges property
1807 : * @ingroup devicetree
1808 : * @{
1809 : */
1810 :
1811 : /**
1812 : * @brief Get the number of range blocks in the ranges property
1813 : *
1814 : * Use this instead of DT_PROP_LEN(node_id, ranges).
1815 : *
1816 : * Example devicetree fragment:
1817 : *
1818 : * @code{.dts}
1819 : * pcie0: pcie@0 {
1820 : * compatible = "pcie-controller";
1821 : * reg = <0 1>;
1822 : * #address-cells = <3>;
1823 : * #size-cells = <2>;
1824 : *
1825 : * ranges = <0x1000000 0 0 0 0x3eff0000 0 0x10000>,
1826 : * <0x2000000 0 0x10000000 0 0x10000000 0 0x2eff0000>,
1827 : * <0x3000000 0x80 0 0x80 0 0x80 0>;
1828 : * };
1829 : *
1830 : * other: other@1 {
1831 : * reg = <1 1>;
1832 : *
1833 : * ranges = <0x0 0x0 0x0 0x3eff0000 0x10000>,
1834 : * <0x0 0x10000000 0x0 0x10000000 0x2eff0000>;
1835 : * };
1836 : * @endcode
1837 : *
1838 : * Example usage:
1839 : *
1840 : * @code{.c}
1841 : * DT_NUM_RANGES(DT_NODELABEL(pcie0)) // 3
1842 : * DT_NUM_RANGES(DT_NODELABEL(other)) // 2
1843 : * @endcode
1844 : *
1845 : * @param node_id node identifier
1846 : */
1847 1 : #define DT_NUM_RANGES(node_id) DT_CAT(node_id, _RANGES_NUM)
1848 :
1849 : /**
1850 : * @brief Is @p idx a valid range block index?
1851 : *
1852 : * If this returns 1, then DT_RANGES_CHILD_BUS_ADDRESS_BY_IDX(node_id, idx),
1853 : * DT_RANGES_PARENT_BUS_ADDRESS_BY_IDX(node_id, idx) or
1854 : * DT_RANGES_LENGTH_BY_IDX(node_id, idx) are valid.
1855 : * For DT_RANGES_CHILD_BUS_FLAGS_BY_IDX(node_id, idx) the return value
1856 : * of DT_RANGES_HAS_CHILD_BUS_FLAGS_AT_IDX(node_id, idx) will indicate
1857 : * validity.
1858 : * If it returns 0, it is an error to use those macros with index @p idx,
1859 : * including DT_RANGES_CHILD_BUS_FLAGS_BY_IDX(node_id, idx).
1860 : *
1861 : * Example devicetree fragment:
1862 : *
1863 : * @code{.dts}
1864 : * pcie0: pcie@0 {
1865 : * compatible = "pcie-controller";
1866 : * reg = <0 1>;
1867 : * #address-cells = <3>;
1868 : * #size-cells = <2>;
1869 : *
1870 : * ranges = <0x1000000 0 0 0 0x3eff0000 0 0x10000>,
1871 : * <0x2000000 0 0x10000000 0 0x10000000 0 0x2eff0000>,
1872 : * <0x3000000 0x80 0 0x80 0 0x80 0>;
1873 : * };
1874 : *
1875 : * other: other@1 {
1876 : * reg = <1 1>;
1877 : *
1878 : * ranges = <0x0 0x0 0x0 0x3eff0000 0x10000>,
1879 : * <0x0 0x10000000 0x0 0x10000000 0x2eff0000>;
1880 : * };
1881 : * @endcode
1882 : *
1883 : * Example usage:
1884 : *
1885 : * @code{.c}
1886 : * DT_RANGES_HAS_IDX(DT_NODELABEL(pcie0), 0) // 1
1887 : * DT_RANGES_HAS_IDX(DT_NODELABEL(pcie0), 1) // 1
1888 : * DT_RANGES_HAS_IDX(DT_NODELABEL(pcie0), 2) // 1
1889 : * DT_RANGES_HAS_IDX(DT_NODELABEL(pcie0), 3) // 0
1890 : * DT_RANGES_HAS_IDX(DT_NODELABEL(other), 0) // 1
1891 : * DT_RANGES_HAS_IDX(DT_NODELABEL(other), 1) // 1
1892 : * DT_RANGES_HAS_IDX(DT_NODELABEL(other), 2) // 0
1893 : * DT_RANGES_HAS_IDX(DT_NODELABEL(other), 3) // 0
1894 : * @endcode
1895 : *
1896 : * @param node_id node identifier
1897 : * @param idx index to check
1898 : * @return 1 if @p idx is a valid register block index,
1899 : * 0 otherwise.
1900 : */
1901 1 : #define DT_RANGES_HAS_IDX(node_id, idx) \
1902 : IS_ENABLED(DT_CAT4(node_id, _RANGES_IDX_, idx, _EXISTS))
1903 :
1904 : /**
1905 : * @brief Does a ranges property have child bus flags at index?
1906 : *
1907 : * If this returns 1, then DT_RANGES_CHILD_BUS_FLAGS_BY_IDX(node_id, idx) is valid.
1908 : * If it returns 0, it is an error to use this macro with index @p idx.
1909 : * This macro only returns 1 for PCIe buses (i.e. nodes whose bindings specify they
1910 : * are "pcie" bus nodes.)
1911 : *
1912 : * Example devicetree fragment:
1913 : *
1914 : * @code{.dts}
1915 : * parent {
1916 : * #address-cells = <2>;
1917 : *
1918 : * pcie0: pcie@0 {
1919 : * compatible = "pcie-controller";
1920 : * reg = <0 0 1>;
1921 : * #address-cells = <3>;
1922 : * #size-cells = <2>;
1923 : *
1924 : * ranges = <0x1000000 0 0 0 0x3eff0000 0 0x10000>,
1925 : * <0x2000000 0 0x10000000 0 0x10000000 0 0x2eff0000>,
1926 : * <0x3000000 0x80 0 0x80 0 0x80 0>;
1927 : * };
1928 : *
1929 : * other: other@1 {
1930 : * reg = <0 1 1>;
1931 : *
1932 : * ranges = <0x0 0x0 0x0 0x3eff0000 0x10000>,
1933 : * <0x0 0x10000000 0x0 0x10000000 0x2eff0000>;
1934 : * };
1935 : * };
1936 : * @endcode
1937 : *
1938 : * Example usage:
1939 : *
1940 : * @code{.c}
1941 : * DT_RANGES_HAS_CHILD_BUS_FLAGS_AT_IDX(DT_NODELABEL(pcie0), 0) // 1
1942 : * DT_RANGES_HAS_CHILD_BUS_FLAGS_AT_IDX(DT_NODELABEL(pcie0), 1) // 1
1943 : * DT_RANGES_HAS_CHILD_BUS_FLAGS_AT_IDX(DT_NODELABEL(pcie0), 2) // 1
1944 : * DT_RANGES_HAS_CHILD_BUS_FLAGS_AT_IDX(DT_NODELABEL(pcie0), 3) // 0
1945 : * DT_RANGES_HAS_CHILD_BUS_FLAGS_AT_IDX(DT_NODELABEL(other), 0) // 0
1946 : * DT_RANGES_HAS_CHILD_BUS_FLAGS_AT_IDX(DT_NODELABEL(other), 1) // 0
1947 : * DT_RANGES_HAS_CHILD_BUS_FLAGS_AT_IDX(DT_NODELABEL(other), 2) // 0
1948 : * DT_RANGES_HAS_CHILD_BUS_FLAGS_AT_IDX(DT_NODELABEL(other), 3) // 0
1949 : * @endcode
1950 : *
1951 : * @param node_id node identifier
1952 : * @param idx logical index into the ranges array
1953 : * @return 1 if @p idx is a valid child bus flags index,
1954 : * 0 otherwise.
1955 : */
1956 1 : #define DT_RANGES_HAS_CHILD_BUS_FLAGS_AT_IDX(node_id, idx) \
1957 : IS_ENABLED(DT_CAT4(node_id, _RANGES_IDX_, idx, _VAL_CHILD_BUS_FLAGS_EXISTS))
1958 :
1959 : /**
1960 : * @brief Get the ranges property child bus flags at index
1961 : *
1962 : * When the node is a PCIe bus, the Child Bus Address has an extra cell used to store some
1963 : * flags, thus this cell is extracted from the Child Bus Address as Child Bus Flags field.
1964 : *
1965 : * Example devicetree fragments:
1966 : *
1967 : * @code{.dts}
1968 : * parent {
1969 : * #address-cells = <2>;
1970 : *
1971 : * pcie0: pcie@0 {
1972 : * compatible = "pcie-controller";
1973 : * reg = <0 0 1>;
1974 : * #address-cells = <3>;
1975 : * #size-cells = <2>;
1976 : *
1977 : * ranges = <0x1000000 0 0 0 0x3eff0000 0 0x10000>,
1978 : * <0x2000000 0 0x10000000 0 0x10000000 0 0x2eff0000>,
1979 : * <0x3000000 0x80 0 0x80 0 0x80 0>;
1980 : * };
1981 : * };
1982 : * @endcode
1983 : *
1984 : * Example usage:
1985 : *
1986 : * @code{.c}
1987 : * DT_RANGES_CHILD_BUS_FLAGS_BY_IDX(DT_NODELABEL(pcie0), 0) // 0x1000000
1988 : * DT_RANGES_CHILD_BUS_FLAGS_BY_IDX(DT_NODELABEL(pcie0), 1) // 0x2000000
1989 : * DT_RANGES_CHILD_BUS_FLAGS_BY_IDX(DT_NODELABEL(pcie0), 2) // 0x3000000
1990 : * @endcode
1991 : *
1992 : * @param node_id node identifier
1993 : * @param idx logical index into the ranges array
1994 : * @returns range child bus flags field at idx
1995 : */
1996 1 : #define DT_RANGES_CHILD_BUS_FLAGS_BY_IDX(node_id, idx) \
1997 : DT_CAT4(node_id, _RANGES_IDX_, idx, _VAL_CHILD_BUS_FLAGS)
1998 :
1999 : /**
2000 : * @brief Get the ranges property child bus address at index
2001 : *
2002 : * When the node is a PCIe bus, the Child Bus Address has an extra cell used to store some
2003 : * flags, thus this cell is removed from the Child Bus Address.
2004 : *
2005 : * Example devicetree fragments:
2006 : *
2007 : * @code{.dts}
2008 : * parent {
2009 : * #address-cells = <2>;
2010 : *
2011 : * pcie0: pcie@0 {
2012 : * compatible = "pcie-controller";
2013 : * reg = <0 0 1>;
2014 : * #address-cells = <3>;
2015 : * #size-cells = <2>;
2016 : *
2017 : * ranges = <0x1000000 0 0 0 0x3eff0000 0 0x10000>,
2018 : * <0x2000000 0 0x10000000 0 0x10000000 0 0x2eff0000>,
2019 : * <0x3000000 0x80 0 0x80 0 0x80 0>;
2020 : * };
2021 : *
2022 : * other: other@1 {
2023 : * reg = <0 1 1>;
2024 : *
2025 : * ranges = <0x0 0x0 0x0 0x3eff0000 0x10000>,
2026 : * <0x0 0x10000000 0x0 0x10000000 0x2eff0000>;
2027 : * };
2028 : * };
2029 : * @endcode
2030 : *
2031 : * Example usage:
2032 : *
2033 : * @code{.c}
2034 : * DT_RANGES_CHILD_BUS_ADDRESS_BY_IDX(DT_NODELABEL(pcie0), 0) // 0
2035 : * DT_RANGES_CHILD_BUS_ADDRESS_BY_IDX(DT_NODELABEL(pcie0), 1) // 0x10000000
2036 : * DT_RANGES_CHILD_BUS_ADDRESS_BY_IDX(DT_NODELABEL(pcie0), 2) // 0x8000000000
2037 : * DT_RANGES_CHILD_BUS_ADDRESS_BY_IDX(DT_NODELABEL(other), 0) // 0
2038 : * DT_RANGES_CHILD_BUS_ADDRESS_BY_IDX(DT_NODELABEL(other), 1) // 0x10000000
2039 : * @endcode
2040 : *
2041 : * @param node_id node identifier
2042 : * @param idx logical index into the ranges array
2043 : * @returns range child bus address field at idx
2044 : */
2045 1 : #define DT_RANGES_CHILD_BUS_ADDRESS_BY_IDX(node_id, idx) \
2046 : DT_CAT4(node_id, _RANGES_IDX_, idx, _VAL_CHILD_BUS_ADDRESS)
2047 :
2048 : /**
2049 : * @brief Get the ranges property parent bus address at index
2050 : *
2051 : * Similarly to DT_RANGES_CHILD_BUS_ADDRESS_BY_IDX(), this properly accounts
2052 : * for child bus flags cells when the node is a PCIe bus.
2053 : *
2054 : * Example devicetree fragment:
2055 : *
2056 : * @code{.dts}
2057 : * parent {
2058 : * #address-cells = <2>;
2059 : *
2060 : * pcie0: pcie@0 {
2061 : * compatible = "pcie-controller";
2062 : * reg = <0 0 1>;
2063 : * #address-cells = <3>;
2064 : * #size-cells = <2>;
2065 : *
2066 : * ranges = <0x1000000 0 0 0 0x3eff0000 0 0x10000>,
2067 : * <0x2000000 0 0x10000000 0 0x10000000 0 0x2eff0000>,
2068 : * <0x3000000 0x80 0 0x80 0 0x80 0>;
2069 : * };
2070 : *
2071 : * other: other@1 {
2072 : * reg = <0 1 1>;
2073 : *
2074 : * ranges = <0x0 0x0 0x0 0x3eff0000 0x10000>,
2075 : * <0x0 0x10000000 0x0 0x10000000 0x2eff0000>;
2076 : * };
2077 : * };
2078 : * @endcode
2079 : *
2080 : * Example usage:
2081 : *
2082 : * @code{.c}
2083 : * DT_RANGES_PARENT_BUS_ADDRESS_BY_IDX(DT_NODELABEL(pcie0), 0) // 0x3eff0000
2084 : * DT_RANGES_PARENT_BUS_ADDRESS_BY_IDX(DT_NODELABEL(pcie0), 1) // 0x10000000
2085 : * DT_RANGES_PARENT_BUS_ADDRESS_BY_IDX(DT_NODELABEL(pcie0), 2) // 0x8000000000
2086 : * DT_RANGES_PARENT_BUS_ADDRESS_BY_IDX(DT_NODELABEL(other), 0) // 0x3eff0000
2087 : * DT_RANGES_PARENT_BUS_ADDRESS_BY_IDX(DT_NODELABEL(other), 1) // 0x10000000
2088 : * @endcode
2089 : *
2090 : * @param node_id node identifier
2091 : * @param idx logical index into the ranges array
2092 : * @returns range parent bus address field at idx
2093 : */
2094 1 : #define DT_RANGES_PARENT_BUS_ADDRESS_BY_IDX(node_id, idx) \
2095 : DT_CAT4(node_id, _RANGES_IDX_, idx, _VAL_PARENT_BUS_ADDRESS)
2096 :
2097 : /**
2098 : * @brief Get the ranges property length at index
2099 : *
2100 : * Similarly to DT_RANGES_CHILD_BUS_ADDRESS_BY_IDX(), this properly accounts
2101 : * for child bus flags cells when the node is a PCIe bus.
2102 : *
2103 : * Example devicetree fragment:
2104 : *
2105 : * @code{.dts}
2106 : * parent {
2107 : * #address-cells = <2>;
2108 : *
2109 : * pcie0: pcie@0 {
2110 : * compatible = "pcie-controller";
2111 : * reg = <0 0 1>;
2112 : * #address-cells = <3>;
2113 : * #size-cells = <2>;
2114 : *
2115 : * ranges = <0x1000000 0 0 0 0x3eff0000 0 0x10000>,
2116 : * <0x2000000 0 0x10000000 0 0x10000000 0 0x2eff0000>,
2117 : * <0x3000000 0x80 0 0x80 0 0x80 0>;
2118 : * };
2119 : *
2120 : * other: other@1 {
2121 : * reg = <0 1 1>;
2122 : *
2123 : * ranges = <0x0 0x0 0x0 0x3eff0000 0x10000>,
2124 : * <0x0 0x10000000 0x0 0x10000000 0x2eff0000>;
2125 : * };
2126 : * };
2127 : * @endcode
2128 : *
2129 : * Example usage:
2130 : *
2131 : * @code{.c}
2132 : * DT_RANGES_LENGTH_BY_IDX(DT_NODELABEL(pcie0), 0) // 0x10000
2133 : * DT_RANGES_LENGTH_BY_IDX(DT_NODELABEL(pcie0), 1) // 0x2eff0000
2134 : * DT_RANGES_LENGTH_BY_IDX(DT_NODELABEL(pcie0), 2) // 0x8000000000
2135 : * DT_RANGES_LENGTH_BY_IDX(DT_NODELABEL(other), 0) // 0x10000
2136 : * DT_RANGES_LENGTH_BY_IDX(DT_NODELABEL(other), 1) // 0x2eff0000
2137 : * @endcode
2138 : *
2139 : * @param node_id node identifier
2140 : * @param idx logical index into the ranges array
2141 : * @returns range length field at idx
2142 : */
2143 1 : #define DT_RANGES_LENGTH_BY_IDX(node_id, idx) \
2144 : DT_CAT4(node_id, _RANGES_IDX_, idx, _VAL_LENGTH)
2145 :
2146 : /**
2147 : * @brief Invokes @p fn for each entry of @p node_id ranges property
2148 : *
2149 : * The macro @p fn must take two parameters, @p node_id which will be the node
2150 : * identifier of the node with the ranges property and @p idx the index of
2151 : * the ranges block.
2152 : *
2153 : * Example devicetree fragment:
2154 : *
2155 : * @code{.dts}
2156 : * n: node@0 {
2157 : * reg = <0 0 1>;
2158 : *
2159 : * ranges = <0x0 0x0 0x0 0x3eff0000 0x10000>,
2160 : * <0x0 0x10000000 0x0 0x10000000 0x2eff0000>;
2161 : * };
2162 : * @endcode
2163 : *
2164 : * Example usage:
2165 : *
2166 : * @code{.c}
2167 : * #define RANGE_LENGTH(node_id, idx) DT_RANGES_LENGTH_BY_IDX(node_id, idx),
2168 : *
2169 : * const uint64_t *ranges_length[] = {
2170 : * DT_FOREACH_RANGE(DT_NODELABEL(n), RANGE_LENGTH)
2171 : * };
2172 : * @endcode
2173 : *
2174 : * This expands to:
2175 : *
2176 : * @code{.c}
2177 : * const char *ranges_length[] = {
2178 : * 0x10000, 0x2eff0000,
2179 : * };
2180 : * @endcode
2181 : *
2182 : * @param node_id node identifier
2183 : * @param fn macro to invoke
2184 : */
2185 1 : #define DT_FOREACH_RANGE(node_id, fn) \
2186 : DT_CAT(node_id, _FOREACH_RANGE)(fn)
2187 :
2188 : /**
2189 : * @}
2190 : */
2191 :
2192 : /**
2193 : * @defgroup devicetree-generic-vendor Vendor and model name helpers
2194 : * @ingroup devicetree
2195 : * @{
2196 : */
2197 :
2198 : /**
2199 : * @brief Get the vendor at index @p idx as a string literal
2200 : *
2201 : * The vendor is a string extracted from vendor prefixes if an entry exists
2202 : * that matches the node's compatible prefix. There may be as many as one
2203 : * vendor prefixes file per directory in DTS_ROOT.
2204 : *
2205 : * Example vendor-prefixes.txt:
2206 : *
2207 : * vnd A stand-in for a real vendor
2208 : * zephyr Zephyr-specific binding
2209 : *
2210 : * Example devicetree fragment:
2211 : *
2212 : * @code{.dts}
2213 : * n1: node-1 {
2214 : * compatible = "vnd,model1", "gpio", "zephyr,model2";
2215 : * };
2216 : * @endcode
2217 : *
2218 : * Example usage:
2219 : *
2220 : * @code{.c}
2221 : * DT_NODE_VENDOR_BY_IDX(DT_NODELABEL(n1), 0) // "A stand-in for a real vendor"
2222 : * DT_NODE_VENDOR_BY_IDX(DT_NODELABEL(n1), 2) // "Zephyr-specific binding"
2223 : * @endcode
2224 : *
2225 : * Notice that the compatible at index 1 doesn't match any entries in the
2226 : * vendor prefix file and therefore index 1 is not a valid vendor index. Use
2227 : * DT_NODE_VENDOR_HAS_IDX(node_id, idx) to determine if an index is valid.
2228 : *
2229 : * @param node_id node identifier
2230 : * @param idx index of the vendor to return
2231 : * @return string literal of the idx-th vendor
2232 : */
2233 1 : #define DT_NODE_VENDOR_BY_IDX(node_id, idx) \
2234 : DT_CAT3(node_id, _COMPAT_VENDOR_IDX_, idx)
2235 :
2236 : /**
2237 : * @brief Does a node's compatible property have a vendor at an index?
2238 : *
2239 : * If this returns 1, then DT_NODE_VENDOR_BY_IDX(node_id, idx) is valid. If it
2240 : * returns 0, it is an error to use DT_NODE_VENDOR_BY_IDX(node_id, idx) with
2241 : * index @p idx.
2242 : *
2243 : * @param node_id node identifier
2244 : * @param idx index of the vendor to check
2245 : * @return 1 if @p idx is a valid vendor index,
2246 : * 0 otherwise.
2247 : */
2248 1 : #define DT_NODE_VENDOR_HAS_IDX(node_id, idx) \
2249 : IS_ENABLED(DT_CAT4(node_id, _COMPAT_VENDOR_IDX_, idx, _EXISTS))
2250 :
2251 : /**
2252 : * @brief Like DT_NODE_VENDOR_BY_IDX(), but with a fallback to default_value.
2253 : *
2254 : * If the value exists, this expands to DT_NODE_VENDOR_BY_IDX(node_id, idx).
2255 : * The default_value parameter is not expanded in this case.
2256 : *
2257 : * Otherwise, this expands to default_value.
2258 : *
2259 : * @param node_id node identifier
2260 : * @param idx index of the vendor to return
2261 : * @return string literal of the idx-th vendor
2262 : * @param default_value a fallback value to expand to
2263 : * @return string literal of the idx-th vendor or "default_value"
2264 : */
2265 1 : #define DT_NODE_VENDOR_BY_IDX_OR(node_id, idx, default_value) \
2266 : COND_CODE_1(DT_NODE_VENDOR_HAS_IDX(node_id, idx), \
2267 : (DT_NODE_VENDOR_BY_IDX(node_id, idx)), (default_value))
2268 :
2269 : /**
2270 : * @brief Get the node's (only) vendor as a string literal
2271 : *
2272 : * Equivalent to DT_NODE_VENDOR_BY_IDX_OR(node_id, 0, default_value).
2273 : *
2274 : * @param node_id node identifier
2275 : * @param default_value a fallback value to expand to
2276 : */
2277 1 : #define DT_NODE_VENDOR_OR(node_id, default_value) \
2278 : DT_NODE_VENDOR_BY_IDX_OR(node_id, 0, default_value)
2279 :
2280 : /**
2281 : * @brief Get the model at index "idx" as a string literal
2282 : *
2283 : * The model is a string extracted from the compatible after the vendor prefix.
2284 : *
2285 : * Example vendor-prefixes.txt:
2286 : *
2287 : * vnd A stand-in for a real vendor
2288 : * zephyr Zephyr-specific binding
2289 : *
2290 : * Example devicetree fragment:
2291 : *
2292 : * n1: node-1 {
2293 : * compatible = "vnd,model1", "gpio", "zephyr,model2";
2294 : * };
2295 : *
2296 : * Example usage:
2297 : *
2298 : * DT_NODE_MODEL_BY_IDX(DT_NODELABEL(n1), 0) // "model1"
2299 : * DT_NODE_MODEL_BY_IDX(DT_NODELABEL(n1), 2) // "model2"
2300 : *
2301 : * Notice that the compatible at index 1 doesn't match any entries in the
2302 : * vendor prefix file and therefore index 1 is not a valid model index. Use
2303 : * DT_NODE_MODEL_HAS_IDX(node_id, idx) to determine if an index is valid.
2304 : *
2305 : * @param node_id node identifier
2306 : * @param idx index of the model to return
2307 : * @return string literal of the idx-th model
2308 : */
2309 1 : #define DT_NODE_MODEL_BY_IDX(node_id, idx) \
2310 : DT_CAT3(node_id, _COMPAT_MODEL_IDX_, idx)
2311 :
2312 : /**
2313 : * @brief Does a node's compatible property have a model at an index?
2314 : *
2315 : * If this returns 1, then DT_NODE_MODEL_BY_IDX(node_id, idx) is valid. If it
2316 : * returns 0, it is an error to use DT_NODE_MODEL_BY_IDX(node_id, idx) with
2317 : * index "idx".
2318 : *
2319 : * @param node_id node identifier
2320 : * @param idx index of the model to check
2321 : * @return 1 if "idx" is a valid model index,
2322 : * 0 otherwise.
2323 : */
2324 1 : #define DT_NODE_MODEL_HAS_IDX(node_id, idx) \
2325 : IS_ENABLED(DT_CAT4(node_id, _COMPAT_MODEL_IDX_, idx, _EXISTS))
2326 :
2327 : /**
2328 : * @brief Like DT_NODE_MODEL_BY_IDX(), but with a fallback to default_value.
2329 : *
2330 : * If the value exists, this expands to DT_NODE_MODEL_BY_IDX(node_id, idx).
2331 : * The default_value parameter is not expanded in this case.
2332 : *
2333 : * Otherwise, this expands to default_value.
2334 : *
2335 : * @param node_id node identifier
2336 : * @param idx index of the model to return
2337 : * @return string literal of the idx-th model
2338 : * @param default_value a fallback value to expand to
2339 : * @return string literal of the idx-th model or "default_value"
2340 : */
2341 1 : #define DT_NODE_MODEL_BY_IDX_OR(node_id, idx, default_value) \
2342 : COND_CODE_1(DT_NODE_MODEL_HAS_IDX(node_id, idx), \
2343 : (DT_NODE_MODEL_BY_IDX(node_id, idx)), (default_value))
2344 :
2345 : /**
2346 : * @brief Get the node's (only) model as a string literal
2347 : *
2348 : * Equivalent to DT_NODE_MODEL_BY_IDX_OR(node_id, 0, default_value).
2349 : *
2350 : * @param node_id node identifier
2351 : * @param default_value a fallback value to expand to
2352 : */
2353 1 : #define DT_NODE_MODEL_OR(node_id, default_value) \
2354 : DT_NODE_MODEL_BY_IDX_OR(node_id, 0, default_value)
2355 :
2356 : /**
2357 : * @}
2358 : */
2359 :
2360 : /**
2361 : * @defgroup devicetree-reg-prop reg property
2362 : * @ingroup devicetree
2363 : * @{
2364 : */
2365 :
2366 : /**
2367 : * @brief Get the number of register blocks in the reg property
2368 : *
2369 : * Use this instead of DT_PROP_LEN(node_id, reg).
2370 : * @param node_id node identifier
2371 : * @return Number of register blocks in the node's "reg" property.
2372 : */
2373 1 : #define DT_NUM_REGS(node_id) DT_CAT(node_id, _REG_NUM)
2374 :
2375 : /**
2376 : * @brief Is @p idx a valid register block index?
2377 : *
2378 : * If this returns 1, then DT_REG_ADDR_BY_IDX(node_id, idx) or
2379 : * DT_REG_SIZE_BY_IDX(node_id, idx) are valid.
2380 : * If it returns 0, it is an error to use those macros with index @p idx.
2381 : * @param node_id node identifier
2382 : * @param idx index to check
2383 : * @return 1 if @p idx is a valid register block index,
2384 : * 0 otherwise.
2385 : */
2386 1 : #define DT_REG_HAS_IDX(node_id, idx) \
2387 : IS_ENABLED(DT_CAT4(node_id, _REG_IDX_, idx, _EXISTS))
2388 :
2389 : /**
2390 : * @brief Is @p name a valid register block name?
2391 : *
2392 : * If this returns 1, then DT_REG_ADDR_BY_NAME(node_id, name) or
2393 : * DT_REG_SIZE_BY_NAME(node_id, name) are valid.
2394 : * If it returns 0, it is an error to use those macros with name @p name.
2395 : * @param node_id node identifier
2396 : * @param name name to check
2397 : * @return 1 if @p name is a valid register block name,
2398 : * 0 otherwise.
2399 : */
2400 1 : #define DT_REG_HAS_NAME(node_id, name) \
2401 : IS_ENABLED(DT_CAT4(node_id, _REG_NAME_, name, _EXISTS))
2402 :
2403 : /**
2404 : * @brief Get the base raw address of the register block at index @p idx
2405 : *
2406 : * Get the base address of the register block at index @p idx without any
2407 : * type suffix. This can be used to index other devicetree properties, use the
2408 : * non _RAW macros for assigning values in actual code.
2409 : *
2410 : * @param node_id node identifier
2411 : * @param idx index of the register whose address to return
2412 : * @return address of the idx-th register block
2413 : */
2414 1 : #define DT_REG_ADDR_BY_IDX_RAW(node_id, idx) \
2415 : DT_CAT4(node_id, _REG_IDX_, idx, _VAL_ADDRESS)
2416 :
2417 : /**
2418 : * @brief Get a node's (only) register block raw address
2419 : *
2420 : * Get a node's only register block address without any type suffix. This can
2421 : * be used to index other devicetree properties, use the non _RAW macros for
2422 : * assigning values in actual code.
2423 : *
2424 : * Equivalent to DT_REG_ADDR_BY_IDX_RAW(node_id, 0).
2425 : * @param node_id node identifier
2426 : * @return node's register block address
2427 : */
2428 1 : #define DT_REG_ADDR_RAW(node_id) \
2429 : DT_REG_ADDR_BY_IDX_RAW(node_id, 0)
2430 :
2431 : /**
2432 : * @brief Get the base address of the register block at index @p idx
2433 : * @param node_id node identifier
2434 : * @param idx index of the register whose address to return
2435 : * @return address of the idx-th register block
2436 : */
2437 1 : #define DT_REG_ADDR_BY_IDX(node_id, idx) \
2438 : DT_U32_C(DT_REG_ADDR_BY_IDX_RAW(node_id, idx))
2439 :
2440 : /**
2441 : * @brief Get the size of the register block at index @p idx
2442 : *
2443 : * This is the size of an individual register block, not the total
2444 : * number of register blocks in the property; use DT_NUM_REGS() for
2445 : * that.
2446 : *
2447 : * @param node_id node identifier
2448 : * @param idx index of the register whose size to return
2449 : * @return size of the idx-th register block
2450 : */
2451 1 : #define DT_REG_SIZE_BY_IDX(node_id, idx) \
2452 : DT_U32_C(DT_CAT4(node_id, _REG_IDX_, idx, _VAL_SIZE))
2453 :
2454 : /**
2455 : * @brief Get a node's (only) register block address
2456 : *
2457 : * Equivalent to DT_REG_ADDR_BY_IDX(node_id, 0).
2458 : * @param node_id node identifier
2459 : * @return node's register block address
2460 : */
2461 1 : #define DT_REG_ADDR(node_id) DT_REG_ADDR_BY_IDX(node_id, 0)
2462 :
2463 : /**
2464 : * @brief 64-bit version of DT_REG_ADDR()
2465 : *
2466 : * This macro version adds the appropriate suffix for 64-bit unsigned
2467 : * integer literals.
2468 : * Note that this macro is equivalent to DT_REG_ADDR() in linker/ASM context.
2469 : *
2470 : * @param node_id node identifier
2471 : * @return node's register block address
2472 : */
2473 1 : #define DT_REG_ADDR_U64(node_id) DT_U64_C(DT_REG_ADDR_BY_IDX_RAW(node_id, 0))
2474 :
2475 : /**
2476 : * @brief Get a node's (only) register block size
2477 : *
2478 : * Equivalent to DT_REG_SIZE_BY_IDX(node_id, 0).
2479 : * @param node_id node identifier
2480 : * @return node's only register block's size
2481 : */
2482 1 : #define DT_REG_SIZE(node_id) DT_REG_SIZE_BY_IDX(node_id, 0)
2483 :
2484 : /**
2485 : * @brief Get a register block's base address by name
2486 : * @param node_id node identifier
2487 : * @param name lowercase-and-underscores register specifier name
2488 : * @return address of the register block specified by name
2489 : */
2490 1 : #define DT_REG_ADDR_BY_NAME(node_id, name) \
2491 : DT_U32_C(DT_CAT4(node_id, _REG_NAME_, name, _VAL_ADDRESS))
2492 :
2493 : /**
2494 : * @brief Like DT_REG_ADDR_BY_NAME(), but with a fallback to @p default_value
2495 : * @param node_id node identifier
2496 : * @param name lowercase-and-underscores register specifier name
2497 : * @param default_value a fallback value to expand to
2498 : * @return address of the register block specified by name if present,
2499 : * @p default_value otherwise
2500 : */
2501 1 : #define DT_REG_ADDR_BY_NAME_OR(node_id, name, default_value) \
2502 : COND_CODE_1(DT_REG_HAS_NAME(node_id, name), \
2503 : (DT_REG_ADDR_BY_NAME(node_id, name)), (default_value))
2504 :
2505 : /**
2506 : * @brief 64-bit version of DT_REG_ADDR_BY_NAME()
2507 : *
2508 : * This macro version adds the appropriate suffix for 64-bit unsigned
2509 : * integer literals.
2510 : * Note that this macro is equivalent to DT_REG_ADDR_BY_NAME() in
2511 : * linker/ASM context.
2512 : *
2513 : * @param node_id node identifier
2514 : * @param name lowercase-and-underscores register specifier name
2515 : * @return address of the register block specified by name
2516 : */
2517 1 : #define DT_REG_ADDR_BY_NAME_U64(node_id, name) \
2518 : DT_U64_C(DT_CAT4(node_id, _REG_NAME_, name, _VAL_ADDRESS))
2519 :
2520 : /**
2521 : * @brief Get a register block's size by name
2522 : * @param node_id node identifier
2523 : * @param name lowercase-and-underscores register specifier name
2524 : * @return size of the register block specified by name
2525 : */
2526 1 : #define DT_REG_SIZE_BY_NAME(node_id, name) \
2527 : DT_U32_C(DT_CAT4(node_id, _REG_NAME_, name, _VAL_SIZE))
2528 :
2529 : /**
2530 : * @brief Like DT_REG_SIZE_BY_NAME(), but with a fallback to @p default_value
2531 : * @param node_id node identifier
2532 : * @param name lowercase-and-underscores register specifier name
2533 : * @param default_value a fallback value to expand to
2534 : * @return size of the register block specified by name if present,
2535 : * @p default_value otherwise
2536 : */
2537 1 : #define DT_REG_SIZE_BY_NAME_OR(node_id, name, default_value) \
2538 : COND_CODE_1(DT_REG_HAS_NAME(node_id, name), \
2539 : (DT_REG_SIZE_BY_NAME(node_id, name)), (default_value))
2540 :
2541 :
2542 : /**
2543 : * @}
2544 : */
2545 :
2546 : /**
2547 : * @defgroup devicetree-interrupts-prop interrupts property
2548 : * @ingroup devicetree
2549 : * @{
2550 : */
2551 :
2552 : /**
2553 : * @brief Get the number of interrupt sources for the node
2554 : *
2555 : * Use this instead of DT_PROP_LEN(node_id, interrupts).
2556 : *
2557 : * @param node_id node identifier
2558 : * @return Number of interrupt specifiers in the node's "interrupts" property.
2559 : */
2560 1 : #define DT_NUM_IRQS(node_id) DT_CAT(node_id, _IRQ_NUM)
2561 :
2562 : /**
2563 : * @brief Get the number of node labels that a node has
2564 : *
2565 : * Example devicetree fragment:
2566 : *
2567 : * @code{.dts}
2568 : * / {
2569 : * foo {};
2570 : * bar: bar@1000 {};
2571 : * baz: baz2: baz@2000 {};
2572 : * };
2573 : * @endcode
2574 : *
2575 : * Example usage:
2576 : *
2577 : * @code{.c}
2578 : * DT_NUM_NODELABELS(DT_PATH(foo)) // 0
2579 : * DT_NUM_NODELABELS(DT_NODELABEL(bar)) // 1
2580 : * DT_NUM_NODELABELS(DT_NODELABEL(baz)) // 2
2581 : * @endcode
2582 : *
2583 : * @param node_id node identifier
2584 : * @return number of node labels that the node has
2585 : */
2586 1 : #define DT_NUM_NODELABELS(node_id) DT_CAT(node_id, _NODELABEL_NUM)
2587 :
2588 : /**
2589 : * @brief Get the interrupt level for the node
2590 : *
2591 : * @param node_id node identifier
2592 : * @return interrupt level
2593 : */
2594 1 : #define DT_IRQ_LEVEL(node_id) DT_CAT(node_id, _IRQ_LEVEL)
2595 :
2596 : /**
2597 : * @brief Is @p idx a valid interrupt index?
2598 : *
2599 : * If this returns 1, then DT_IRQ_BY_IDX(node_id, idx) is valid.
2600 : * If it returns 0, it is an error to use that macro with this index.
2601 : * @param node_id node identifier
2602 : * @param idx index to check
2603 : * @return 1 if the idx is valid for the interrupt property
2604 : * 0 otherwise.
2605 : */
2606 1 : #define DT_IRQ_HAS_IDX(node_id, idx) \
2607 : IS_ENABLED(DT_CAT4(node_id, _IRQ_IDX_, idx, _EXISTS))
2608 :
2609 : /**
2610 : * @brief Does an interrupts property have a named cell specifier at an index?
2611 : * If this returns 1, then DT_IRQ_BY_IDX(node_id, idx, cell) is valid.
2612 : * If it returns 0, it is an error to use that macro.
2613 : * @param node_id node identifier
2614 : * @param idx index to check
2615 : * @param cell named cell value whose existence to check
2616 : * @return 1 if the named cell exists in the interrupt specifier at index idx
2617 : * 0 otherwise.
2618 : */
2619 1 : #define DT_IRQ_HAS_CELL_AT_IDX(node_id, idx, cell) \
2620 : IS_ENABLED(DT_CAT6(node_id, _IRQ_IDX_, idx, _VAL_, cell, _EXISTS))
2621 :
2622 : /**
2623 : * @brief Equivalent to DT_IRQ_HAS_CELL_AT_IDX(node_id, 0, cell)
2624 : * @param node_id node identifier
2625 : * @param cell named cell value whose existence to check
2626 : * @return 1 if the named cell exists in the interrupt specifier at index 0
2627 : * 0 otherwise.
2628 : */
2629 1 : #define DT_IRQ_HAS_CELL(node_id, cell) DT_IRQ_HAS_CELL_AT_IDX(node_id, 0, cell)
2630 :
2631 : /**
2632 : * @brief Does an interrupts property have a named specifier value at an index?
2633 : * If this returns 1, then DT_IRQ_BY_NAME(node_id, name, cell) is valid.
2634 : * If it returns 0, it is an error to use that macro.
2635 : * @param node_id node identifier
2636 : * @param name lowercase-and-underscores interrupt specifier name
2637 : * @return 1 if "name" is a valid named specifier
2638 : * 0 otherwise.
2639 : */
2640 1 : #define DT_IRQ_HAS_NAME(node_id, name) \
2641 : IS_ENABLED(DT_CAT4(node_id, _IRQ_NAME_, name, _VAL_irq_EXISTS))
2642 :
2643 : /**
2644 : * @brief Get a value within an interrupt specifier at an index
2645 : *
2646 : * It might help to read the argument order as being similar to
2647 : * "node->interrupts[index].cell".
2648 : *
2649 : * This can be used to get information about an individual interrupt
2650 : * when a device generates more than one.
2651 : *
2652 : * Example devicetree fragment:
2653 : *
2654 : * @code{.dts}
2655 : * my-serial: serial@abcd1234 {
2656 : * interrupts = < 33 0 >, < 34 1 >;
2657 : * };
2658 : * @endcode
2659 : *
2660 : * Assuming the node's interrupt domain has "#interrupt-cells = <2>;" and
2661 : * the individual cells in each interrupt specifier are named "irq" and
2662 : * "priority" by the node's binding, here are some examples:
2663 : *
2664 : * #define SERIAL DT_NODELABEL(my_serial)
2665 : *
2666 : * Example usage Value
2667 : * ------------- -----
2668 : * DT_IRQ_BY_IDX(SERIAL, 0, irq) 33
2669 : * DT_IRQ_BY_IDX(SERIAL, 0, priority) 0
2670 : * DT_IRQ_BY_IDX(SERIAL, 1, irq, 34
2671 : * DT_IRQ_BY_IDX(SERIAL, 1, priority) 1
2672 : *
2673 : * @param node_id node identifier
2674 : * @param idx logical index into the interrupt specifier array
2675 : * @param cell cell name specifier
2676 : * @return the named value at the specifier given by the index
2677 : */
2678 1 : #define DT_IRQ_BY_IDX(node_id, idx, cell) \
2679 : DT_CAT5(node_id, _IRQ_IDX_, idx, _VAL_, cell)
2680 :
2681 : /**
2682 : * @brief Get a value within an interrupt specifier by name
2683 : *
2684 : * It might help to read the argument order as being similar to
2685 : * `node->interrupts.name.cell`.
2686 : *
2687 : * This can be used to get information about an individual interrupt
2688 : * when a device generates more than one, if the bindings give each
2689 : * interrupt specifier a name.
2690 : *
2691 : * @param node_id node identifier
2692 : * @param name lowercase-and-underscores interrupt specifier name
2693 : * @param cell cell name specifier
2694 : * @return the named value at the specifier given by the index
2695 : */
2696 1 : #define DT_IRQ_BY_NAME(node_id, name, cell) \
2697 : DT_CAT5(node_id, _IRQ_NAME_, name, _VAL_, cell)
2698 :
2699 : /**
2700 : * @brief Get an interrupt specifier's value
2701 : * Equivalent to DT_IRQ_BY_IDX(node_id, 0, cell).
2702 : * @param node_id node identifier
2703 : * @param cell cell name specifier
2704 : * @return the named value at that index
2705 : */
2706 1 : #define DT_IRQ(node_id, cell) DT_IRQ_BY_IDX(node_id, 0, cell)
2707 :
2708 : /**
2709 : * @brief Get an interrupt specifier's interrupt controller by index
2710 : *
2711 : * @code{.dts}
2712 : * gpio0: gpio0 {
2713 : * interrupt-controller;
2714 : * #interrupt-cells = <2>;
2715 : * };
2716 : *
2717 : * foo: foo {
2718 : * interrupt-parent = <&gpio0>;
2719 : * interrupts = <1 1>, <2 2>;
2720 : * };
2721 : *
2722 : * bar: bar {
2723 : * interrupts-extended = <&gpio0 3 3>, <&pic0 4>;
2724 : * };
2725 : *
2726 : * pic0: pic0 {
2727 : * interrupt-controller;
2728 : * #interrupt-cells = <1>;
2729 : *
2730 : * qux: qux {
2731 : * interrupts = <5>, <6>;
2732 : * interrupt-names = "int1", "int2";
2733 : * };
2734 : * };
2735 : * @endcode
2736 : *
2737 : * Example usage:
2738 : *
2739 : * DT_IRQ_INTC_BY_IDX(DT_NODELABEL(foo), 0) // &gpio0
2740 : * DT_IRQ_INTC_BY_IDX(DT_NODELABEL(foo), 1) // &gpio0
2741 : * DT_IRQ_INTC_BY_IDX(DT_NODELABEL(bar), 0) // &gpio0
2742 : * DT_IRQ_INTC_BY_IDX(DT_NODELABEL(bar), 1) // &pic0
2743 : * DT_IRQ_INTC_BY_IDX(DT_NODELABEL(qux), 0) // &pic0
2744 : * DT_IRQ_INTC_BY_IDX(DT_NODELABEL(qux), 1) // &pic0
2745 : *
2746 : * @param node_id node identifier
2747 : * @param idx interrupt specifier's index
2748 : * @return node_id of interrupt specifier's interrupt controller
2749 : */
2750 1 : #define DT_IRQ_INTC_BY_IDX(node_id, idx) \
2751 : DT_CAT4(node_id, _IRQ_IDX_, idx, _CONTROLLER)
2752 :
2753 : /**
2754 : * @brief Get an interrupt specifier's interrupt controller by name
2755 : *
2756 : * @code{.dts}
2757 : * gpio0: gpio0 {
2758 : * interrupt-controller;
2759 : * #interrupt-cells = <2>;
2760 : * };
2761 : *
2762 : * foo: foo {
2763 : * interrupt-parent = <&gpio0>;
2764 : * interrupts = <1 1>, <2 2>;
2765 : * interrupt-names = "int1", "int2";
2766 : * };
2767 : *
2768 : * bar: bar {
2769 : * interrupts-extended = <&gpio0 3 3>, <&pic0 4>;
2770 : * interrupt-names = "int1", "int2";
2771 : * };
2772 : *
2773 : * pic0: pic0 {
2774 : * interrupt-controller;
2775 : * #interrupt-cells = <1>;
2776 : *
2777 : * qux: qux {
2778 : * interrupts = <5>, <6>;
2779 : * interrupt-names = "int1", "int2";
2780 : * };
2781 : * };
2782 : * @endcode
2783 : *
2784 : * Example usage:
2785 : *
2786 : * DT_IRQ_INTC_BY_NAME(DT_NODELABEL(foo), int1) // &gpio0
2787 : * DT_IRQ_INTC_BY_NAME(DT_NODELABEL(foo), int2) // &gpio0
2788 : * DT_IRQ_INTC_BY_NAME(DT_NODELABEL(bar), int1) // &gpio0
2789 : * DT_IRQ_INTC_BY_NAME(DT_NODELABEL(bar), int2) // &pic0
2790 : * DT_IRQ_INTC_BY_NAME(DT_NODELABEL(qux), int1) // &pic0
2791 : * DT_IRQ_INTC_BY_NAME(DT_NODELABEL(qux), int2) // &pic0
2792 : *
2793 : * @param node_id node identifier
2794 : * @param name interrupt specifier's name
2795 : * @return node_id of interrupt specifier's interrupt controller
2796 : */
2797 1 : #define DT_IRQ_INTC_BY_NAME(node_id, name) \
2798 : DT_CAT4(node_id, _IRQ_NAME_, name, _CONTROLLER)
2799 :
2800 : /**
2801 : * @brief Get an interrupt specifier's interrupt controller
2802 : * @note Equivalent to DT_IRQ_INTC_BY_IDX(node_id, 0)
2803 : *
2804 : * @code{.dts}
2805 : * gpio0: gpio0 {
2806 : * interrupt-controller;
2807 : * #interrupt-cells = <2>;
2808 : * };
2809 : *
2810 : * foo: foo {
2811 : * interrupt-parent = <&gpio0>;
2812 : * interrupts = <1 1>;
2813 : * };
2814 : *
2815 : * bar: bar {
2816 : * interrupts-extended = <&gpio0 3 3>;
2817 : * };
2818 : *
2819 : * pic0: pic0 {
2820 : * interrupt-controller;
2821 : * #interrupt-cells = <1>;
2822 : *
2823 : * qux: qux {
2824 : * interrupts = <5>;
2825 : * };
2826 : * };
2827 : * @endcode
2828 : *
2829 : * Example usage:
2830 : *
2831 : * DT_IRQ_INTC(DT_NODELABEL(foo)) // &gpio0
2832 : * DT_IRQ_INTC(DT_NODELABEL(bar)) // &gpio0
2833 : * DT_IRQ_INTC(DT_NODELABEL(qux)) // &pic0
2834 : *
2835 : * @param node_id node identifier
2836 : * @return node_id of interrupt specifier's interrupt controller
2837 : * @see DT_IRQ_INTC_BY_IDX()
2838 : */
2839 1 : #define DT_IRQ_INTC(node_id) \
2840 : DT_IRQ_INTC_BY_IDX(node_id, 0)
2841 :
2842 : /**
2843 : * @cond INTERNAL_HIDDEN
2844 : */
2845 :
2846 : /* DT helper macro to encode a node's IRQN to level 1 according to the multi-level scheme */
2847 : #define DT_IRQN_L1_INTERNAL(node_id, idx) DT_IRQ_BY_IDX(node_id, idx, irq)
2848 : /* DT helper macro to encode a node's IRQN to level 2 according to the multi-level scheme */
2849 : #define DT_IRQN_L2_INTERNAL(node_id, idx) \
2850 : (IRQ_TO_L2(DT_IRQN_L1_INTERNAL(node_id, idx)) | \
2851 : DT_IRQ(DT_IRQ_INTC_BY_IDX(node_id, idx), irq))
2852 : /* DT helper macro to encode a node's IRQN to level 3 according to the multi-level scheme */
2853 : #define DT_IRQN_L3_INTERNAL(node_id, idx) \
2854 : (IRQ_TO_L3(DT_IRQN_L1_INTERNAL(node_id, idx)) | \
2855 : IRQ_TO_L2(DT_IRQ(DT_IRQ_INTC_BY_IDX(node_id, idx), irq)) | \
2856 : DT_IRQ(DT_IRQ_INTC(DT_IRQ_INTC_BY_IDX(node_id, idx)), irq))
2857 : /* DT helper macro for the macros above */
2858 : #define DT_IRQN_LVL_INTERNAL(node_id, idx, level) DT_CAT3(DT_IRQN_L, level, _INTERNAL)(node_id, idx)
2859 :
2860 : /**
2861 : * DT helper macro to encode a node's interrupt number according to the Zephyr's multi-level scheme
2862 : * See doc/kernel/services/interrupts.rst for details
2863 : */
2864 : #define DT_MULTI_LEVEL_IRQN_INTERNAL(node_id, idx) \
2865 : DT_IRQN_LVL_INTERNAL(node_id, idx, DT_IRQ_LEVEL(node_id))
2866 :
2867 : /**
2868 : * INTERNAL_HIDDEN @endcond
2869 : */
2870 :
2871 : /**
2872 : * @brief Get the node's Zephyr interrupt number at index
2873 : * If @kconfig{CONFIG_MULTI_LEVEL_INTERRUPTS} is enabled, the interrupt number at index will be
2874 : * multi-level encoded
2875 : * @param node_id node identifier
2876 : * @param idx logical index into the interrupt specifier array
2877 : * @return the Zephyr interrupt number
2878 : */
2879 1 : #define DT_IRQN_BY_IDX(node_id, idx) \
2880 : COND_CODE_1(IS_ENABLED(CONFIG_MULTI_LEVEL_INTERRUPTS), \
2881 : (DT_MULTI_LEVEL_IRQN_INTERNAL(node_id, idx)), \
2882 : (DT_IRQ_BY_IDX(node_id, idx, irq)))
2883 :
2884 : /**
2885 : * @brief Get a node's (only) irq number
2886 : *
2887 : * Equivalent to DT_IRQ(node_id, irq). This is provided as a convenience
2888 : * for the common case where a node generates exactly one interrupt,
2889 : * and the IRQ number is in a cell named `irq`.
2890 : *
2891 : * @param node_id node identifier
2892 : * @return the interrupt number for the node's only interrupt
2893 : */
2894 1 : #define DT_IRQN(node_id) DT_IRQN_BY_IDX(node_id, 0)
2895 :
2896 : /**
2897 : * @}
2898 : */
2899 :
2900 : /**
2901 : * @defgroup devicetree-generic-chosen Chosen nodes
2902 : * @ingroup devicetree
2903 : * @{
2904 : */
2905 :
2906 : /**
2907 : * @brief Get a node identifier for a `/chosen` node property
2908 : *
2909 : * This is only valid to call if `DT_HAS_CHOSEN(prop)` is 1.
2910 : * @param prop lowercase-and-underscores property name for
2911 : * the /chosen node
2912 : * @return a node identifier for the chosen node property
2913 : */
2914 1 : #define DT_CHOSEN(prop) DT_CAT(DT_CHOSEN_, prop)
2915 :
2916 : /**
2917 : * @brief Test if the devicetree has a `/chosen` node
2918 : * @param prop lowercase-and-underscores devicetree property
2919 : * @return 1 if the chosen property exists and refers to a node,
2920 : * 0 otherwise
2921 : */
2922 1 : #define DT_HAS_CHOSEN(prop) IS_ENABLED(DT_CAT3(DT_CHOSEN_, prop, _EXISTS))
2923 :
2924 : /**
2925 : * @}
2926 : */
2927 :
2928 : /**
2929 : * @defgroup devicetree-generic-foreach "For-each" macros
2930 : * @ingroup devicetree
2931 : * @{
2932 : *
2933 : * IMPORTANT: you can't use the DT for-each macros in their own expansions.
2934 : *
2935 : * For example, something like this won't work the way you might expect:
2936 : *
2937 : * @code{.c}
2938 : * #define FOO(node_id) [...] DT_FOREACH_NODE(...) [...]
2939 : * DT_FOREACH_NODE(FOO)
2940 : * @endcode
2941 : *
2942 : * In this example, the C preprocessor won't expand the
2943 : * DT_FOREACH_NODE() macro inside of FOO() while it's already
2944 : * expanding DT_FOREACH_NODE() at the top level of the file.
2945 : *
2946 : * This is true of any macro, not just DT_FOREACH_NODE(). The C
2947 : * language works this way to avoid infinite recursions inside of
2948 : * macro expansions.
2949 : *
2950 : * If you need to "nest" calls to one of these macros, you can work
2951 : * around this preprocessor limitation by using a different, related
2952 : * macro instead, like this:
2953 : *
2954 : * @code{.c}
2955 : * #define BAR(node_id) [...] DT_FOREACH_NODE_VARGS(...) [...]
2956 : * DT_FOREACH_NODE(BAR)
2957 : * @endcode
2958 : *
2959 : * Here, we use DT_FOREACH_NODE_VARGS() "inside" BAR() "inside"
2960 : * DT_FOREACH_NODE(). Because of this, the preprocessor will expand
2961 : * both DT_FOREACH_NODE_VARGS() and DT_FOREACH_NODE() as expected.
2962 : */
2963 :
2964 : /**
2965 : * @brief Invokes @p fn for every node in the tree.
2966 : *
2967 : * The macro @p fn must take one parameter, which will be a node
2968 : * identifier. The macro is expanded once for each node in the tree.
2969 : * The order that nodes are visited in is not specified.
2970 : *
2971 : * @param fn macro to invoke
2972 : */
2973 1 : #define DT_FOREACH_NODE(fn) DT_FOREACH_HELPER(fn)
2974 :
2975 : /**
2976 : * @brief Invokes @p fn for every node in the tree with multiple arguments.
2977 : *
2978 : * The macro @p fn takes multiple arguments. The first should be the node
2979 : * identifier for the node. The remaining are passed-in by the caller.
2980 : *
2981 : * The macro is expanded once for each node in the tree. The order that nodes
2982 : * are visited in is not specified.
2983 : *
2984 : * @param fn macro to invoke
2985 : * @param ... variable number of arguments to pass to @p fn
2986 : */
2987 1 : #define DT_FOREACH_NODE_VARGS(fn, ...) DT_FOREACH_VARGS_HELPER(fn, __VA_ARGS__)
2988 :
2989 : /**
2990 : * @brief Invokes @p fn for every status `okay` node in the tree.
2991 : *
2992 : * The macro @p fn must take one parameter, which will be a node
2993 : * identifier. The macro is expanded once for each node in the tree
2994 : * with status `okay` (as usual, a missing status property is treated
2995 : * as status `okay`). The order that nodes are visited in is not
2996 : * specified.
2997 : *
2998 : * @param fn macro to invoke
2999 : */
3000 1 : #define DT_FOREACH_STATUS_OKAY_NODE(fn) DT_FOREACH_OKAY_HELPER(fn)
3001 :
3002 : /**
3003 : * @brief Invokes @p fn for every status `okay` node in the tree with multiple
3004 : * arguments.
3005 : *
3006 : * The macro @p fn takes multiple arguments. The first should be the node
3007 : * identifier for the node. The remaining are passed-in by the caller.
3008 : *
3009 : * The macro is expanded once for each node in the tree with status `okay` (as
3010 : * usual, a missing status property is treated as status `okay`). The order
3011 : * that nodes are visited in is not specified.
3012 : *
3013 : * @param fn macro to invoke
3014 : * @param ... variable number of arguments to pass to @p fn
3015 : */
3016 1 : #define DT_FOREACH_STATUS_OKAY_NODE_VARGS(fn, ...) DT_FOREACH_OKAY_VARGS_HELPER(fn, __VA_ARGS__)
3017 :
3018 : /**
3019 : * @brief Invokes @p fn for each ancestor of @p node_id
3020 : *
3021 : * The macro @p fn must take one parameter, which will be the identifier
3022 : * of a child node of @p node_id to enable traversal of all ancestor nodes.
3023 : *
3024 : * The ancestor will be iterated over in the same order as they
3025 : * appear in the final devicetree.
3026 : *
3027 : * Example devicetree fragment:
3028 : *
3029 : * @code{.dts}
3030 : * n: node1 {
3031 : * foobar = "foo1";
3032 : *
3033 : * n_2: node2 {
3034 : * foobar = "foo2";
3035 : *
3036 : * n_3: node3 {
3037 : * foobar = "foo3";
3038 : * };
3039 : * };
3040 : * };
3041 : * @endcode
3042 : *
3043 : * Example usage:
3044 : *
3045 : * @code{.c}
3046 : * #define GET_PROP(n) DT_PROP(n, foobar),
3047 : *
3048 : * const char *ancestor_names[] = {
3049 : * DT_FOREACH_ANCESTOR(DT_NODELABEL(n_3), GET_PROP)
3050 : * };
3051 : * @endcode
3052 : *
3053 : * This expands to:
3054 : *
3055 : * @code{.c}
3056 : * const char *ancestor_names[] = {
3057 : * "foo2", "foo1",
3058 : * };
3059 : * @endcode
3060 : *
3061 : * @param node_id node identifier
3062 : * @param fn macro to invoke
3063 : */
3064 1 : #define DT_FOREACH_ANCESTOR(node_id, fn) \
3065 : DT_CAT(node_id, _FOREACH_ANCESTOR)(fn)
3066 :
3067 : /**
3068 : * @brief Invokes @p fn for each child of @p node_id
3069 : *
3070 : * The macro @p fn must take one parameter, which will be the node
3071 : * identifier of a child node of @p node_id.
3072 : *
3073 : * The children will be iterated over in the same order as they
3074 : * appear in the final devicetree.
3075 : *
3076 : * Example devicetree fragment:
3077 : *
3078 : * @code{.dts}
3079 : * n: node {
3080 : * child-1 {
3081 : * foobar = "foo";
3082 : * };
3083 : * child-2 {
3084 : * foobar = "bar";
3085 : * };
3086 : * };
3087 : * @endcode
3088 : *
3089 : * Example usage:
3090 : *
3091 : * @code{.c}
3092 : * #define FOOBAR_AND_COMMA(node_id) DT_PROP(node_id, foobar),
3093 : *
3094 : * const char *child_foobars[] = {
3095 : * DT_FOREACH_CHILD(DT_NODELABEL(n), FOOBAR_AND_COMMA)
3096 : * };
3097 : * @endcode
3098 : *
3099 : * This expands to:
3100 : *
3101 : * @code{.c}
3102 : * const char *child_foobars[] = {
3103 : * "foo", "bar",
3104 : * };
3105 : * @endcode
3106 : *
3107 : * @param node_id node identifier
3108 : * @param fn macro to invoke
3109 : */
3110 1 : #define DT_FOREACH_CHILD(node_id, fn) \
3111 : DT_CAT(node_id, _FOREACH_CHILD)(fn)
3112 :
3113 : /**
3114 : * @brief Invokes @p fn for each child of @p node_id with a separator
3115 : *
3116 : * The macro @p fn must take one parameter, which will be the node
3117 : * identifier of a child node of @p node_id.
3118 : *
3119 : * Example devicetree fragment:
3120 : *
3121 : * @code{.dts}
3122 : * n: node {
3123 : * child-1 {
3124 : * ...
3125 : * };
3126 : * child-2 {
3127 : * ...
3128 : * };
3129 : * };
3130 : * @endcode
3131 : *
3132 : * Example usage:
3133 : *
3134 : * @code{.c}
3135 : * const char *child_names[] = {
3136 : * DT_FOREACH_CHILD_SEP(DT_NODELABEL(n), DT_NODE_FULL_NAME, (,))
3137 : * };
3138 : * @endcode
3139 : *
3140 : * This expands to:
3141 : *
3142 : * @code{.c}
3143 : * const char *child_names[] = {
3144 : * "child-1", "child-2"
3145 : * };
3146 : * @endcode
3147 : *
3148 : * @param node_id node identifier
3149 : * @param fn macro to invoke
3150 : * @param sep Separator (e.g. comma or semicolon). Must be in parentheses;
3151 : * this is required to enable providing a comma as separator.
3152 : */
3153 1 : #define DT_FOREACH_CHILD_SEP(node_id, fn, sep) \
3154 : DT_CAT(node_id, _FOREACH_CHILD_SEP)(fn, sep)
3155 :
3156 : /**
3157 : * @brief Invokes @p fn for each child of @p node_id with multiple arguments
3158 : *
3159 : * The macro @p fn takes multiple arguments. The first should be the node
3160 : * identifier for the child node. The remaining are passed-in by the caller.
3161 : *
3162 : * The children will be iterated over in the same order as they
3163 : * appear in the final devicetree.
3164 : *
3165 : * @param node_id node identifier
3166 : * @param fn macro to invoke
3167 : * @param ... variable number of arguments to pass to @p fn
3168 : *
3169 : * @see DT_FOREACH_CHILD
3170 : */
3171 1 : #define DT_FOREACH_CHILD_VARGS(node_id, fn, ...) \
3172 : DT_CAT(node_id, _FOREACH_CHILD_VARGS)(fn, __VA_ARGS__)
3173 :
3174 : /**
3175 : * @brief Invokes @p fn for each child of @p node_id with separator and multiple
3176 : * arguments.
3177 : *
3178 : * The macro @p fn takes multiple arguments. The first should be the node
3179 : * identifier for the child node. The remaining are passed-in by the caller.
3180 : *
3181 : * @param node_id node identifier
3182 : * @param fn macro to invoke
3183 : * @param sep Separator (e.g. comma or semicolon). Must be in parentheses;
3184 : * this is required to enable providing a comma as separator.
3185 : * @param ... variable number of arguments to pass to @p fn
3186 : *
3187 : * @see DT_FOREACH_CHILD_VARGS
3188 : */
3189 1 : #define DT_FOREACH_CHILD_SEP_VARGS(node_id, fn, sep, ...) \
3190 : DT_CAT(node_id, _FOREACH_CHILD_SEP_VARGS)(fn, sep, __VA_ARGS__)
3191 :
3192 : /**
3193 : * @brief Call @p fn on the child nodes with status `okay`
3194 : *
3195 : * The macro @p fn should take one argument, which is the node
3196 : * identifier for the child node.
3197 : *
3198 : * As usual, both a missing status and an `ok` status are
3199 : * treated as `okay`.
3200 : *
3201 : * The children will be iterated over in the same order as they
3202 : * appear in the final devicetree.
3203 : *
3204 : * @param node_id node identifier
3205 : * @param fn macro to invoke
3206 : */
3207 1 : #define DT_FOREACH_CHILD_STATUS_OKAY(node_id, fn) \
3208 : DT_CAT(node_id, _FOREACH_CHILD_STATUS_OKAY)(fn)
3209 :
3210 : /**
3211 : * @brief Call @p fn on the child nodes with status `okay` with separator
3212 : *
3213 : * The macro @p fn should take one argument, which is the node
3214 : * identifier for the child node.
3215 : *
3216 : * As usual, both a missing status and an `ok` status are
3217 : * treated as `okay`.
3218 : *
3219 : * @param node_id node identifier
3220 : * @param fn macro to invoke
3221 : * @param sep Separator (e.g. comma or semicolon). Must be in parentheses;
3222 : * this is required to enable providing a comma as separator.
3223 : *
3224 : * @see DT_FOREACH_CHILD_STATUS_OKAY
3225 : */
3226 1 : #define DT_FOREACH_CHILD_STATUS_OKAY_SEP(node_id, fn, sep) \
3227 : DT_CAT(node_id, _FOREACH_CHILD_STATUS_OKAY_SEP)(fn, sep)
3228 :
3229 : /**
3230 : * @brief Call @p fn on the child nodes with status `okay` with multiple
3231 : * arguments
3232 : *
3233 : * The macro @p fn takes multiple arguments. The first should be the node
3234 : * identifier for the child node. The remaining are passed-in by the caller.
3235 : *
3236 : * As usual, both a missing status and an `ok` status are
3237 : * treated as `okay`.
3238 : *
3239 : * The children will be iterated over in the same order as they
3240 : * appear in the final devicetree.
3241 : *
3242 : * @param node_id node identifier
3243 : * @param fn macro to invoke
3244 : * @param ... variable number of arguments to pass to @p fn
3245 : *
3246 : * @see DT_FOREACH_CHILD_STATUS_OKAY
3247 : */
3248 1 : #define DT_FOREACH_CHILD_STATUS_OKAY_VARGS(node_id, fn, ...) \
3249 : DT_CAT(node_id, _FOREACH_CHILD_STATUS_OKAY_VARGS)(fn, __VA_ARGS__)
3250 :
3251 : /**
3252 : * @brief Call @p fn on the child nodes with status `okay` with separator and
3253 : * multiple arguments
3254 : *
3255 : * The macro @p fn takes multiple arguments. The first should be the node
3256 : * identifier for the child node. The remaining are passed-in by the caller.
3257 : *
3258 : * As usual, both a missing status and an `ok` status are
3259 : * treated as `okay`.
3260 : *
3261 : * @param node_id node identifier
3262 : * @param fn macro to invoke
3263 : * @param sep Separator (e.g. comma or semicolon). Must be in parentheses;
3264 : * this is required to enable providing a comma as separator.
3265 : * @param ... variable number of arguments to pass to @p fn
3266 : *
3267 : * @see DT_FOREACH_CHILD_SEP_STATUS_OKAY
3268 : */
3269 1 : #define DT_FOREACH_CHILD_STATUS_OKAY_SEP_VARGS(node_id, fn, sep, ...) \
3270 : DT_CAT(node_id, _FOREACH_CHILD_STATUS_OKAY_SEP_VARGS)(fn, sep, __VA_ARGS__)
3271 :
3272 : /**
3273 : * @brief Invokes @p fn for each element in the value of property @p prop.
3274 : *
3275 : * The macro @p fn must take three parameters: fn(node_id, prop, idx).
3276 : * @p node_id and @p prop are the same as what is passed to
3277 : * DT_FOREACH_PROP_ELEM(), and @p idx is the current index into the array.
3278 : * The @p idx values are integer literals starting from 0.
3279 : *
3280 : * The @p prop argument must refer to a property that can be passed to
3281 : * DT_PROP_LEN().
3282 : *
3283 : * Example devicetree fragment:
3284 : *
3285 : * @code{.dts}
3286 : * n: node {
3287 : * my-ints = <1 2 3>;
3288 : * };
3289 : * @endcode
3290 : *
3291 : * Example usage:
3292 : *
3293 : * @code{.c}
3294 : * #define TIMES_TWO(node_id, prop, idx) \
3295 : * (2 * DT_PROP_BY_IDX(node_id, prop, idx)),
3296 : *
3297 : * int array[] = {
3298 : * DT_FOREACH_PROP_ELEM(DT_NODELABEL(n), my_ints, TIMES_TWO)
3299 : * };
3300 : * @endcode
3301 : *
3302 : * This expands to:
3303 : *
3304 : * @code{.c}
3305 : * int array[] = {
3306 : * (2 * 1), (2 * 2), (2 * 3),
3307 : * };
3308 : * @endcode
3309 : *
3310 : * In general, this macro expands to:
3311 : *
3312 : * fn(node_id, prop, 0) fn(node_id, prop, 1) [...] fn(node_id, prop, n-1)
3313 : *
3314 : * where `n` is the number of elements in @p prop, as it would be
3315 : * returned by `DT_PROP_LEN(node_id, prop)`.
3316 : *
3317 : * @param node_id node identifier
3318 : * @param prop lowercase-and-underscores property name
3319 : * @param fn macro to invoke
3320 : * @see DT_PROP_LEN
3321 : */
3322 1 : #define DT_FOREACH_PROP_ELEM(node_id, prop, fn) \
3323 : DT_CAT4(node_id, _P_, prop, _FOREACH_PROP_ELEM)(fn)
3324 :
3325 : /**
3326 : * @brief Invokes @p fn for each element in the value of property @p prop with
3327 : * separator.
3328 : *
3329 : * Example devicetree fragment:
3330 : *
3331 : * @code{.dts}
3332 : * n: node {
3333 : * my-gpios = <&gpioa 0 GPIO_ACTICE_HIGH>,
3334 : * <&gpiob 1 GPIO_ACTIVE_HIGH>;
3335 : * };
3336 : * @endcode
3337 : *
3338 : * Example usage:
3339 : *
3340 : * @code{.c}
3341 : * struct gpio_dt_spec specs[] = {
3342 : * DT_FOREACH_PROP_ELEM_SEP(DT_NODELABEL(n), my_gpios,
3343 : * GPIO_DT_SPEC_GET_BY_IDX, (,))
3344 : * };
3345 : * @endcode
3346 : *
3347 : * This expands as a first step to:
3348 : *
3349 : * @code{.c}
3350 : * struct gpio_dt_spec specs[] = {
3351 : * GPIO_DT_SPEC_GET_BY_IDX(DT_NODELABEL(n), my_gpios, 0),
3352 : * GPIO_DT_SPEC_GET_BY_IDX(DT_NODELABEL(n), my_gpios, 1)
3353 : * };
3354 : * @endcode
3355 : *
3356 : * The @p prop parameter has the same restrictions as the same parameter
3357 : * given to DT_FOREACH_PROP_ELEM().
3358 : *
3359 : * @param node_id node identifier
3360 : * @param prop lowercase-and-underscores property name
3361 : * @param fn macro to invoke
3362 : * @param sep Separator (e.g. comma or semicolon). Must be in parentheses;
3363 : * this is required to enable providing a comma as separator.
3364 : *
3365 : * @see DT_FOREACH_PROP_ELEM
3366 : */
3367 1 : #define DT_FOREACH_PROP_ELEM_SEP(node_id, prop, fn, sep) \
3368 : DT_CAT4(node_id, _P_, prop, _FOREACH_PROP_ELEM_SEP)(fn, sep)
3369 :
3370 : /**
3371 : * @brief Invokes @p fn for each element in the value of property @p prop with
3372 : * multiple arguments.
3373 : *
3374 : * The macro @p fn must take multiple parameters:
3375 : * `fn(node_id, prop, idx, ...)`. @p node_id and @p prop are the same as what
3376 : * is passed to DT_FOREACH_PROP_ELEM(), and @p idx is the current index into
3377 : * the array. The @p idx values are integer literals starting from 0. The
3378 : * remaining arguments are passed-in by the caller.
3379 : *
3380 : * The @p prop parameter has the same restrictions as the same parameter
3381 : * given to DT_FOREACH_PROP_ELEM().
3382 : *
3383 : * @param node_id node identifier
3384 : * @param prop lowercase-and-underscores property name
3385 : * @param fn macro to invoke
3386 : * @param ... variable number of arguments to pass to @p fn
3387 : *
3388 : * @see DT_FOREACH_PROP_ELEM
3389 : */
3390 1 : #define DT_FOREACH_PROP_ELEM_VARGS(node_id, prop, fn, ...) \
3391 : DT_CAT4(node_id, _P_, prop, _FOREACH_PROP_ELEM_VARGS)(fn, __VA_ARGS__)
3392 :
3393 : /**
3394 : * @brief Invokes @p fn for each element in the value of property @p prop with
3395 : * multiple arguments and a separator.
3396 : *
3397 : * The @p prop parameter has the same restrictions as the same parameter
3398 : * given to DT_FOREACH_PROP_ELEM().
3399 : *
3400 : * @param node_id node identifier
3401 : * @param prop lowercase-and-underscores property name
3402 : * @param fn macro to invoke
3403 : * @param sep Separator (e.g. comma or semicolon). Must be in parentheses;
3404 : * this is required to enable providing a comma as separator.
3405 : * @param ... variable number of arguments to pass to fn
3406 : *
3407 : * @see DT_FOREACH_PROP_ELEM_VARGS
3408 : */
3409 1 : #define DT_FOREACH_PROP_ELEM_SEP_VARGS(node_id, prop, fn, sep, ...) \
3410 : DT_CAT4(node_id, _P_, prop, _FOREACH_PROP_ELEM_SEP_VARGS)( \
3411 : fn, sep, __VA_ARGS__)
3412 :
3413 : /**
3414 : * @brief Invokes @p fn for each status `okay` node of a compatible.
3415 : *
3416 : * This macro expands to:
3417 : *
3418 : * fn(node_id_1) fn(node_id_2) ... fn(node_id_n)
3419 : *
3420 : * where each `node_id_<i>` is a node identifier for some node with
3421 : * compatible @p compat and status `okay`. Whitespace is added between
3422 : * expansions as shown above.
3423 : *
3424 : * Example devicetree fragment:
3425 : *
3426 : * @code{.dts}
3427 : * / {
3428 : * a {
3429 : * compatible = "foo";
3430 : * status = "okay";
3431 : * };
3432 : * b {
3433 : * compatible = "foo";
3434 : * status = "disabled";
3435 : * };
3436 : * c {
3437 : * compatible = "foo";
3438 : * };
3439 : * };
3440 : * @endcode
3441 : *
3442 : * Example usage:
3443 : *
3444 : * @code{.c}
3445 : * DT_FOREACH_STATUS_OKAY(foo, DT_NODE_PATH)
3446 : * @endcode
3447 : *
3448 : * This expands to one of the following:
3449 : *
3450 : * "/a" "/c"
3451 : * "/c" "/a"
3452 : *
3453 : * "One of the following" is because no guarantees are made about the
3454 : * order that node identifiers are passed to @p fn in the expansion.
3455 : *
3456 : * (The `/c` string literal is present because a missing status
3457 : * property is always treated as if the status were set to `okay`.)
3458 : *
3459 : * Note also that @p fn is responsible for adding commas, semicolons,
3460 : * or other terminators as needed.
3461 : *
3462 : * @param compat lowercase-and-underscores devicetree compatible
3463 : * @param fn Macro to call for each enabled node. Must accept a
3464 : * node_id as its only parameter.
3465 : */
3466 1 : #define DT_FOREACH_STATUS_OKAY(compat, fn) \
3467 : COND_CODE_1(DT_HAS_COMPAT_STATUS_OKAY(compat), \
3468 : (UTIL_CAT(DT_FOREACH_OKAY_, compat)(fn)), \
3469 : ())
3470 :
3471 : /**
3472 : * @brief Invokes @p fn for each status `okay` node of a compatible
3473 : * with multiple arguments.
3474 : *
3475 : * This is like DT_FOREACH_STATUS_OKAY() except you can also pass
3476 : * additional arguments to @p fn.
3477 : *
3478 : * Example devicetree fragment:
3479 : *
3480 : * @code{.dts}
3481 : * / {
3482 : * a {
3483 : * compatible = "foo";
3484 : * val = <3>;
3485 : * };
3486 : * b {
3487 : * compatible = "foo";
3488 : * val = <4>;
3489 : * };
3490 : * };
3491 : * @endcode
3492 : *
3493 : * Example usage:
3494 : *
3495 : * @code{.c}
3496 : * #define MY_FN(node_id, operator) DT_PROP(node_id, val) operator
3497 : * x = DT_FOREACH_STATUS_OKAY_VARGS(foo, MY_FN, +) 0;
3498 : * @endcode
3499 : *
3500 : * This expands to one of the following:
3501 : *
3502 : * @code{.c}
3503 : * x = 3 + 4 + 0;
3504 : * x = 4 + 3 + 0;
3505 : * @endcode
3506 : *
3507 : * i.e. it sets `x` to 7. As with DT_FOREACH_STATUS_OKAY(), there are no
3508 : * guarantees about the order nodes appear in the expansion.
3509 : *
3510 : * @param compat lowercase-and-underscores devicetree compatible
3511 : * @param fn Macro to call for each enabled node. Must accept a
3512 : * node_id as its only parameter.
3513 : * @param ... Additional arguments to pass to @p fn
3514 : */
3515 1 : #define DT_FOREACH_STATUS_OKAY_VARGS(compat, fn, ...) \
3516 : COND_CODE_1(DT_HAS_COMPAT_STATUS_OKAY(compat), \
3517 : (DT_CAT(DT_FOREACH_OKAY_VARGS_, \
3518 : compat)(fn, __VA_ARGS__)), \
3519 : ())
3520 :
3521 : /**
3522 : * @brief Call @p fn on all nodes with compatible `compat`
3523 : * and status `okay` with multiple arguments
3524 : *
3525 : *
3526 : * @param compat lowercase-and-underscores devicetree compatible
3527 : * @param fn Macro to call for each enabled node. Must accept a
3528 : * devicetree compatible and instance number.
3529 : * @param ... Additional arguments to pass to @p fn
3530 : *
3531 : * @see DT_INST_FOREACH_STATUS_OKAY_VARGS
3532 : */
3533 1 : #define DT_COMPAT_FOREACH_STATUS_OKAY_VARGS(compat, fn, ...) \
3534 : COND_CODE_1(DT_HAS_COMPAT_STATUS_OKAY(compat), \
3535 : (UTIL_CAT(DT_FOREACH_OKAY_INST_VARGS_, \
3536 : compat)(fn, compat, __VA_ARGS__)), \
3537 : ())
3538 :
3539 :
3540 : /**
3541 : * @brief Invokes @p fn for each node label of a given node
3542 : *
3543 : * The order of the node labels in this macro's expansion matches
3544 : * the order in the final devicetree, with duplicates removed.
3545 : *
3546 : * Node labels are passed to @p fn as tokens. Note that devicetree
3547 : * node labels are always valid C tokens (see "6.2 Labels" in
3548 : * Devicetree Specification v0.4 for details). The node labels are
3549 : * passed as tokens to @p fn as-is, without any lowercasing or
3550 : * conversion of special characters to underscores.
3551 : *
3552 : * Example devicetree fragment:
3553 : *
3554 : * @code{.dts}
3555 : * foo: bar: FOO: node@deadbeef {};
3556 : * @endcode
3557 : *
3558 : * Example usage:
3559 : *
3560 : * @code{.c}
3561 : * int foo = 1;
3562 : * int bar = 2;
3563 : * int FOO = 3;
3564 : *
3565 : * #define FN(nodelabel) + nodelabel
3566 : * int sum = 0 DT_FOREACH_NODELABEL(DT_NODELABEL(foo), FN)
3567 : * @endcode
3568 : *
3569 : * This expands to:
3570 : *
3571 : * @code{.c}
3572 : * int sum = 0 + 1 + 2 + 3;
3573 : * @endcode
3574 : *
3575 : * @param node_id node identifier whose node labels to use
3576 : * @param fn macro which will be passed each node label in order
3577 : */
3578 1 : #define DT_FOREACH_NODELABEL(node_id, fn) DT_CAT(node_id, _FOREACH_NODELABEL)(fn)
3579 :
3580 : /**
3581 : * @brief Invokes @p fn for each node label of a given node with
3582 : * multiple arguments.
3583 : *
3584 : * This is like DT_FOREACH_NODELABEL() except you can also pass
3585 : * additional arguments to @p fn.
3586 : *
3587 : * Example devicetree fragment:
3588 : *
3589 : * @code{.dts}
3590 : * foo: bar: node@deadbeef {};
3591 : * @endcode
3592 : *
3593 : * Example usage:
3594 : *
3595 : * @code{.c}
3596 : * int foo = 0;
3597 : * int bar = 1;
3598 : *
3599 : * #define VAR_PLUS(nodelabel, to_add) int nodelabel ## _added = nodelabel + to_add;
3600 : *
3601 : * DT_FOREACH_NODELABEL_VARGS(DT_NODELABEL(foo), VAR_PLUS, 1)
3602 : * @endcode
3603 : *
3604 : * This expands to:
3605 : *
3606 : * @code{.c}
3607 : * int foo = 0;
3608 : * int bar = 1;
3609 : * int foo_added = foo + 1;
3610 : * int bar_added = bar + 1;
3611 : * @endcode
3612 : *
3613 : * @param node_id node identifier whose node labels to use
3614 : * @param fn macro which will be passed each node label in order
3615 : * @param ... additional arguments to pass to @p fn
3616 : */
3617 1 : #define DT_FOREACH_NODELABEL_VARGS(node_id, fn, ...) \
3618 : DT_CAT(node_id, _FOREACH_NODELABEL_VARGS)(fn, __VA_ARGS__)
3619 :
3620 : /**
3621 : * @}
3622 : */
3623 :
3624 : /**
3625 : * @defgroup devicetree-generic-exist Existence checks
3626 : * @ingroup devicetree
3627 : * @{
3628 : */
3629 :
3630 : /**
3631 : * @brief Does a node identifier refer to a node?
3632 : *
3633 : * Tests whether a node identifier refers to a node which exists, i.e.
3634 : * is defined in the devicetree.
3635 : *
3636 : * It doesn't matter whether or not the node has a matching binding,
3637 : * or what the node's status value is. This is purely a check of
3638 : * whether the node exists at all.
3639 : *
3640 : * @param node_id a node identifier
3641 : * @return 1 if the node identifier refers to a node,
3642 : * 0 otherwise.
3643 : */
3644 1 : #define DT_NODE_EXISTS(node_id) IS_ENABLED(DT_CAT(node_id, _EXISTS))
3645 :
3646 : /**
3647 : * @brief Does a node identifier refer to a node with a status?
3648 : *
3649 : * Example uses:
3650 : *
3651 : * @code{.c}
3652 : * DT_NODE_HAS_STATUS(DT_PATH(soc, i2c_12340000), okay)
3653 : * DT_NODE_HAS_STATUS(DT_PATH(soc, i2c_12340000), disabled)
3654 : * @endcode
3655 : *
3656 : * Tests whether a node identifier refers to a node which:
3657 : *
3658 : * - exists in the devicetree, and
3659 : * - has a status property matching the second argument
3660 : * (except that either a missing status or an `ok` status
3661 : * in the devicetree is treated as if it were `okay` instead)
3662 : *
3663 : * @param node_id a node identifier
3664 : * @param status a status as one of the tokens okay or disabled, not a string
3665 : * @return 1 if the node has the given status, 0 otherwise.
3666 : */
3667 1 : #define DT_NODE_HAS_STATUS(node_id, status) \
3668 : DT_NODE_HAS_STATUS_INTERNAL(node_id, status)
3669 :
3670 : /**
3671 : * @brief Does a node identifier refer to a node with a status `okay`?
3672 : *
3673 : * Example uses:
3674 : *
3675 : * @code{.c}
3676 : * DT_NODE_HAS_STATUS_OKAY(DT_PATH(soc, i2c_12340000))
3677 : * @endcode
3678 : *
3679 : * Tests whether a node identifier refers to a node which:
3680 : *
3681 : * - exists in the devicetree, and
3682 : * - has a status property as `okay`
3683 : *
3684 : * As usual, both a missing status and an `ok` status are treated as
3685 : * `okay`.
3686 : *
3687 : * @param node_id a node identifier
3688 : * @return 1 if the node has status as `okay`, 0 otherwise.
3689 : */
3690 1 : #define DT_NODE_HAS_STATUS_OKAY(node_id) DT_NODE_HAS_STATUS(node_id, okay)
3691 :
3692 : /**
3693 : * @brief Does the devicetree have a status `okay` node with a compatible?
3694 : *
3695 : * Test for whether the devicetree has any nodes with status `okay`
3696 : * and the given compatible. That is, this returns 1 if and only if
3697 : * there is at least one @p node_id for which both of these
3698 : * expressions return 1:
3699 : *
3700 : * @code{.c}
3701 : * DT_NODE_HAS_STATUS(node_id, okay)
3702 : * DT_NODE_HAS_COMPAT(node_id, compat)
3703 : * @endcode
3704 : *
3705 : * As usual, both a missing status and an `ok` status are treated as
3706 : * `okay`.
3707 : *
3708 : * @param compat lowercase-and-underscores compatible, without quotes
3709 : * @return 1 if both of the above conditions are met, 0 otherwise
3710 : */
3711 1 : #define DT_HAS_COMPAT_STATUS_OKAY(compat) \
3712 : IS_ENABLED(DT_CAT(DT_COMPAT_HAS_OKAY_, compat))
3713 :
3714 : /**
3715 : * @brief Get the number of instances of a given compatible with
3716 : * status `okay`
3717 : * @param compat lowercase-and-underscores compatible, without quotes
3718 : * @return Number of instances with status `okay`
3719 : */
3720 1 : #define DT_NUM_INST_STATUS_OKAY(compat) \
3721 : UTIL_AND(DT_HAS_COMPAT_STATUS_OKAY(compat), \
3722 : UTIL_CAT(DT_N_INST, DT_DASH(compat, NUM_OKAY)))
3723 :
3724 : /**
3725 : * @brief Does a devicetree node match a compatible?
3726 : *
3727 : * Example devicetree fragment:
3728 : *
3729 : * @code{.dts}
3730 : * n: node {
3731 : * compatible = "vnd,specific-device", "generic-device";
3732 : * }
3733 : * @endcode
3734 : *
3735 : * Example usages which evaluate to 1:
3736 : *
3737 : * @code{.c}
3738 : * DT_NODE_HAS_COMPAT(DT_NODELABEL(n), vnd_specific_device)
3739 : * DT_NODE_HAS_COMPAT(DT_NODELABEL(n), generic_device)
3740 : * @endcode
3741 : *
3742 : * This macro only uses the value of the compatible property. Whether
3743 : * or not a particular compatible has a matching binding has no effect
3744 : * on its value, nor does the node's status.
3745 : *
3746 : * @param node_id node identifier
3747 : * @param compat lowercase-and-underscores compatible, without quotes
3748 : * @return 1 if the node's compatible property contains @p compat,
3749 : * 0 otherwise.
3750 : */
3751 1 : #define DT_NODE_HAS_COMPAT(node_id, compat) \
3752 : IS_ENABLED(DT_CAT3(node_id, _COMPAT_MATCHES_, compat))
3753 :
3754 : /**
3755 : * @brief Does a devicetree node have a compatible and status?
3756 : *
3757 : * This is equivalent to:
3758 : *
3759 : * @code{.c}
3760 : * (DT_NODE_HAS_COMPAT(node_id, compat) &&
3761 : * DT_NODE_HAS_STATUS(node_id, status))
3762 : * @endcode
3763 : *
3764 : * @param node_id node identifier
3765 : * @param compat lowercase-and-underscores compatible, without quotes
3766 : * @param status okay or disabled as a token, not a string
3767 : */
3768 1 : #define DT_NODE_HAS_COMPAT_STATUS(node_id, compat, status) \
3769 : UTIL_AND(DT_NODE_HAS_COMPAT(node_id, compat), DT_NODE_HAS_STATUS(node_id, status))
3770 :
3771 : /**
3772 : * @brief Does a devicetree node have a property?
3773 : *
3774 : * Tests whether a devicetree node has a property defined.
3775 : *
3776 : * This tests whether the property is defined at all, not whether a
3777 : * boolean property is true or false. To get a boolean property's
3778 : * truth value, use DT_PROP(node_id, prop) instead.
3779 : *
3780 : * @param node_id node identifier
3781 : * @param prop lowercase-and-underscores property name
3782 : * @return 1 if the node has the property, 0 otherwise.
3783 : */
3784 1 : #define DT_NODE_HAS_PROP(node_id, prop) \
3785 : IS_ENABLED(DT_CAT4(node_id, _P_, prop, _EXISTS))
3786 :
3787 :
3788 : /**
3789 : * @brief Does a phandle array have a named cell specifier at an index?
3790 : *
3791 : * If this returns 1, then the phandle-array property @p pha has a cell
3792 : * named @p cell at index @p idx, and therefore DT_PHA_BY_IDX(node_id,
3793 : * pha, idx, cell) is valid. If it returns 0, it's an error to use
3794 : * DT_PHA_BY_IDX() with the same arguments.
3795 : *
3796 : * @param node_id node identifier
3797 : * @param pha lowercase-and-underscores property with type `phandle-array`
3798 : * @param idx index to check within @p pha
3799 : * @param cell lowercase-and-underscores cell name whose existence to check
3800 : * at index @p idx
3801 : * @return 1 if the named cell exists in the specifier at index idx,
3802 : * 0 otherwise.
3803 : */
3804 1 : #define DT_PHA_HAS_CELL_AT_IDX(node_id, pha, idx, cell) \
3805 : IS_ENABLED(DT_CAT8(node_id, _P_, pha, \
3806 : _IDX_, idx, _VAL_, cell, _EXISTS))
3807 :
3808 : /**
3809 : * @brief Equivalent to DT_PHA_HAS_CELL_AT_IDX(node_id, pha, 0, cell)
3810 : * @param node_id node identifier
3811 : * @param pha lowercase-and-underscores property with type `phandle-array`
3812 : * @param cell lowercase-and-underscores cell name whose existence to check
3813 : * at index @p idx
3814 : * @return 1 if the named cell exists in the specifier at index 0,
3815 : * 0 otherwise.
3816 : */
3817 1 : #define DT_PHA_HAS_CELL(node_id, pha, cell) \
3818 : DT_PHA_HAS_CELL_AT_IDX(node_id, pha, 0, cell)
3819 :
3820 : /**
3821 : * @brief Iterate over all cells in a phandle array element by index
3822 : *
3823 : * This macro calls @p fn(cell_value) for each cell value in the
3824 : * phandle array element at index @p idx.
3825 : *
3826 : * In general, this macro expands to:
3827 : *
3828 : * fn(node_id, pha, idx, cell[0]) fn(node_id, pha, idx, cell[1]) [...]
3829 : * fn(node_id, pha, idx, cell[n-1])
3830 : *
3831 : * where `n` is the number of cells in @p pha, as it would be
3832 : * returned by `DT_PHA_NUM_CELLS_BY_IDX(node_id, pha, idx)`, and cell[x] is the NAME of the cell
3833 : * in the specifier.
3834 : *
3835 : * @param node_id node identifier
3836 : * @param pha lowercase-and-underscores property with type `phandle-array`
3837 : * @param idx index of the phandle array element
3838 : * @param fn macro to call for each cell value
3839 : */
3840 1 : #define DT_FOREACH_PHA_CELL_BY_IDX(node_id, pha, idx, fn) \
3841 : DT_CAT6(node_id, _P_, pha, _IDX_, idx, _FOREACH_CELL)(fn)
3842 :
3843 : /**
3844 : * @brief Iterate over all cells in a phandle array element by index with separator
3845 : *
3846 : * This is like DT_FOREACH_PHA_CELL_BY_IDX(), but @p sep is placed between
3847 : * each invocation of @p fn.
3848 : *
3849 : * @param node_id node identifier
3850 : * @param pha lowercase-and-underscores property with type `phandle-array`
3851 : * @param idx index of the phandle array element
3852 : * @param fn macro to call for each cell value
3853 : * @param sep separator (e.g. comma or semicolon)
3854 : */
3855 1 : #define DT_FOREACH_PHA_CELL_BY_IDX_SEP(node_id, pha, idx, fn, sep) \
3856 : DT_CAT6(node_id, _P_, pha, _IDX_, idx, _FOREACH_CELL_SEP)(fn, sep)
3857 :
3858 : /**
3859 : * @brief Get the number of cells in a phandle array element by index
3860 : *
3861 : * @param node_id node identifier
3862 : * @param pha lowercase-and-underscores property with type `phandle-array`
3863 : * @param idx index of the phandle array element
3864 : * @return number of cells in the element at index @p idx
3865 : */
3866 1 : #define DT_PHA_NUM_CELLS_BY_IDX(node_id, pha, idx) \
3867 : DT_CAT6(node_id, _P_, pha, _IDX_, idx, _NUM_CELLS)
3868 :
3869 : /**
3870 : * @brief Get the name of a phandle array element by index
3871 : *
3872 : * This returns the name in the *-names property of the node
3873 : * corresponding to the index @p idx of @p pha
3874 : *
3875 : * @param node_id node identifier
3876 : * @param pha lowercase-and-underscores property with type `phandle-array`
3877 : * @param idx index of the phandle array element
3878 : * @return name of the element at index @p idx
3879 : */
3880 1 : #define DT_PHA_ELEM_NAME_BY_IDX(node_id, pha, idx) \
3881 : DT_CAT6(node_id, _P_, pha, _IDX_, idx, _NAME)
3882 :
3883 : /**
3884 : * @brief Iterate over all cells in a phandle array element by name
3885 : *
3886 : * This macro calls @p fn(cell_value) for each cell value in the
3887 : * phandle array @p pha element with the given @p name in the *-names property.
3888 : *
3889 : * In general, this macro expands to:
3890 : *
3891 : * fn(node_id, pha, name, cell[0]) fn(node_id, pha, idx, cell[1]) [...]
3892 : * fn(node_id, pha, idx, cell[n-1])
3893 : *
3894 : * where `n` is the number of cells in @p pha, as it would be
3895 : * returned by `DT_PHA_NUM_CELLS_BY_NAME(node_id, pha, name)`, and cell[x] is the NAME of the cell
3896 : * in the specifier.
3897 : *
3898 : *
3899 : * @param node_id node identifier
3900 : * @param pha lowercase-and-underscores property with type `phandle-array`
3901 : * @param name lowercase-and-underscores name of the phandle array element
3902 : * @param fn macro to call for each cell value
3903 : */
3904 1 : #define DT_FOREACH_PHA_CELL_BY_NAME(node_id, pha, name, fn) \
3905 : DT_CAT6(node_id, _P_, pha, _NAME_, name, _FOREACH_CELL)(fn)
3906 :
3907 : /**
3908 : * @brief Iterate over all cells in a phandle array element by name with separator
3909 : *
3910 : * This is like DT_FOREACH_PHA_CELL_BY_NAME(), but @p sep is placed between
3911 : * each invocation of @p fn.
3912 : *
3913 : * @param node_id node identifier
3914 : * @param pha lowercase-and-underscores property with type `phandle-array`
3915 : * @param name lowercase-and-underscores name of the phandle array element
3916 : * @param fn macro to call for each cell value
3917 : * @param sep separator (e.g. comma or semicolon)
3918 : */
3919 1 : #define DT_FOREACH_PHA_CELL_BY_NAME_SEP(node_id, pha, name, fn, sep) \
3920 : DT_CAT6(node_id, _P_, pha, _NAME_, name, _FOREACH_CELL_SEP)(fn, sep)
3921 :
3922 : /**
3923 : * @brief Get the number of cells in a phandle array element by name
3924 : *
3925 : * @param node_id node identifier
3926 : * @param pha lowercase-and-underscores property with type `phandle-array`
3927 : * @param name lowercase-and-underscores name of the phandle array element
3928 : * @return number of cells in the element with the given @p name
3929 : */
3930 1 : #define DT_PHA_NUM_CELLS_BY_NAME(node_id, pha, name) \
3931 : DT_CAT6(node_id, _P_, pha, _NAME_, name, _NUM_CELLS)
3932 :
3933 : /**
3934 : * @brief Get the index of a phandle array element by name
3935 : *
3936 : * This returns the index of the @p pha which has the name @p name in the corresponding
3937 : * *-names property.
3938 : *
3939 : * @param node_id node identifier
3940 : * @param pha lowercase-and-underscores property with type `phandle-array`
3941 : * @param name lowercase-and-underscores name of the phandle array element
3942 : * @return index of the element with the given @p name
3943 : */
3944 1 : #define DT_PHA_ELEM_IDX_BY_NAME(node_id, pha, name) \
3945 : DT_CAT6(node_id, _P_, pha, _NAME_, name, _IDX)
3946 :
3947 :
3948 : /**
3949 : * @}
3950 : */
3951 :
3952 : /**
3953 : * @defgroup devicetree-generic-bus Bus helpers
3954 : * @ingroup devicetree
3955 : * @{
3956 : */
3957 :
3958 : /**
3959 : * @brief Node's bus controller
3960 : *
3961 : * Get the node identifier of the node's bus controller. This can be
3962 : * used with DT_PROP() to get properties of the bus controller.
3963 : *
3964 : * It is an error to use this with nodes which do not have bus
3965 : * controllers.
3966 : *
3967 : * Example devicetree fragment:
3968 : *
3969 : * @code{.dts}
3970 : * i2c@deadbeef {
3971 : * status = "okay";
3972 : * clock-frequency = < 100000 >;
3973 : *
3974 : * i2c_device: accelerometer@12 {
3975 : * ...
3976 : * };
3977 : * };
3978 : * @endcode
3979 : *
3980 : * Example usage:
3981 : *
3982 : * @code{.c}
3983 : * DT_PROP(DT_BUS(DT_NODELABEL(i2c_device)), clock_frequency) // 100000
3984 : * @endcode
3985 : *
3986 : * @param node_id node identifier
3987 : * @return a node identifier for the node's bus controller
3988 : */
3989 1 : #define DT_BUS(node_id) DT_CAT(node_id, _BUS)
3990 :
3991 : /**
3992 : * @brief Is a node on a bus of a given type?
3993 : *
3994 : * Example devicetree overlay:
3995 : *
3996 : * @code{.dts}
3997 : * &i2c0 {
3998 : * temp: temperature-sensor@76 {
3999 : * compatible = "vnd,some-sensor";
4000 : * reg = <0x76>;
4001 : * };
4002 : * };
4003 : * @endcode
4004 : *
4005 : * Example usage, assuming `i2c0` is an I2C bus controller node, and
4006 : * therefore `temp` is on an I2C bus:
4007 : *
4008 : * @code{.c}
4009 : * DT_ON_BUS(DT_NODELABEL(temp), i2c) // 1
4010 : * DT_ON_BUS(DT_NODELABEL(temp), spi) // 0
4011 : * @endcode
4012 : *
4013 : * @param node_id node identifier
4014 : * @param bus lowercase-and-underscores bus type as a C token (i.e.
4015 : * without quotes)
4016 : * @return 1 if the node is on a bus of the given type,
4017 : * 0 otherwise
4018 : */
4019 1 : #define DT_ON_BUS(node_id, bus) IS_ENABLED(DT_CAT3(node_id, _BUS_, bus))
4020 :
4021 : /**
4022 : * @}
4023 : */
4024 :
4025 : /**
4026 : * @defgroup devicetree-inst Instance-based devicetree APIs
4027 : * @ingroup devicetree
4028 : * @{
4029 : */
4030 :
4031 : /**
4032 : * @brief Node identifier for an instance of a `DT_DRV_COMPAT` compatible
4033 : * @param inst instance number
4034 : * @return a node identifier for the node with `DT_DRV_COMPAT` compatible and
4035 : * instance number @p inst
4036 : */
4037 1 : #define DT_DRV_INST(inst) DT_INST(inst, DT_DRV_COMPAT)
4038 :
4039 : /**
4040 : * @brief Get a `DT_DRV_COMPAT` parent's node identifier
4041 : * @param inst instance number
4042 : * @return a node identifier for the instance's parent
4043 : *
4044 : * @see DT_PARENT
4045 : */
4046 1 : #define DT_INST_PARENT(inst) DT_PARENT(DT_DRV_INST(inst))
4047 :
4048 : /**
4049 : * @brief Get a `DT_DRV_COMPAT` grandparent's node identifier
4050 : * @param inst instance number
4051 : * @return a node identifier for the instance's grandparent
4052 : *
4053 : * @see DT_GPARENT
4054 : */
4055 1 : #define DT_INST_GPARENT(inst) DT_GPARENT(DT_DRV_INST(inst))
4056 :
4057 : /**
4058 : * @brief Get a node identifier for a child node of DT_DRV_INST(inst)
4059 : *
4060 : * @param inst instance number
4061 : * @param child lowercase-and-underscores child node name
4062 : * @return node identifier for the node with the name referred to by 'child'
4063 : *
4064 : * @see DT_CHILD
4065 : */
4066 1 : #define DT_INST_CHILD(inst, child) \
4067 : DT_CHILD(DT_DRV_INST(inst), child)
4068 :
4069 : /**
4070 : * @brief Get the number of child nodes of a given node
4071 : *
4072 : * This is equivalent to @see
4073 : * <tt>DT_CHILD_NUM(DT_DRV_INST(inst))</tt>.
4074 : *
4075 : * @param inst Devicetree instance number
4076 : * @return Number of child nodes
4077 : */
4078 1 : #define DT_INST_CHILD_NUM(inst) DT_CHILD_NUM(DT_DRV_INST(inst))
4079 :
4080 : /**
4081 : * @brief Get the number of child nodes of a given node
4082 : *
4083 : * This is equivalent to @see
4084 : * <tt>DT_CHILD_NUM_STATUS_OKAY(DT_DRV_INST(inst))</tt>.
4085 : *
4086 : * @param inst Devicetree instance number
4087 : * @return Number of child nodes which status are okay
4088 : */
4089 1 : #define DT_INST_CHILD_NUM_STATUS_OKAY(inst) \
4090 : DT_CHILD_NUM_STATUS_OKAY(DT_DRV_INST(inst))
4091 :
4092 : /**
4093 : * @brief Get a string array of DT_DRV_INST(inst)'s node labels
4094 : *
4095 : * Equivalent to DT_NODELABEL_STRING_ARRAY(DT_DRV_INST(inst)).
4096 : *
4097 : * @param inst instance number
4098 : * @return an array initializer for an array of the instance's node labels as strings
4099 : */
4100 1 : #define DT_INST_NODELABEL_STRING_ARRAY(inst) DT_NODELABEL_STRING_ARRAY(DT_DRV_INST(inst))
4101 :
4102 : /**
4103 : * @brief Get the number of node labels by instance number
4104 : *
4105 : * Equivalent to DT_NUM_NODELABELS(DT_DRV_INST(inst)).
4106 : *
4107 : * @param inst instance number
4108 : * @return the number of node labels that the node with that instance number has
4109 : */
4110 1 : #define DT_INST_NUM_NODELABELS(inst) DT_NUM_NODELABELS(DT_DRV_INST(inst))
4111 :
4112 : /**
4113 : * @brief Call @p fn on all child nodes of DT_DRV_INST(inst).
4114 : *
4115 : * The macro @p fn should take one argument, which is the node
4116 : * identifier for the child node.
4117 : *
4118 : * The children will be iterated over in the same order as they
4119 : * appear in the final devicetree.
4120 : *
4121 : * @param inst instance number
4122 : * @param fn macro to invoke on each child node identifier
4123 : *
4124 : * @see DT_FOREACH_CHILD
4125 : */
4126 1 : #define DT_INST_FOREACH_CHILD(inst, fn) \
4127 : DT_FOREACH_CHILD(DT_DRV_INST(inst), fn)
4128 :
4129 : /**
4130 : * @brief Call @p fn on all child nodes of DT_DRV_INST(inst) with a separator
4131 : *
4132 : * The macro @p fn should take one argument, which is the node
4133 : * identifier for the child node.
4134 : *
4135 : * @param inst instance number
4136 : * @param fn macro to invoke on each child node identifier
4137 : * @param sep Separator (e.g. comma or semicolon). Must be in parentheses;
4138 : * this is required to enable providing a comma as separator.
4139 : *
4140 : * @see DT_FOREACH_CHILD_SEP
4141 : */
4142 1 : #define DT_INST_FOREACH_CHILD_SEP(inst, fn, sep) \
4143 : DT_FOREACH_CHILD_SEP(DT_DRV_INST(inst), fn, sep)
4144 :
4145 : /**
4146 : * @brief Call @p fn on all child nodes of DT_DRV_INST(inst).
4147 : *
4148 : * The macro @p fn takes multiple arguments. The first should be the node
4149 : * identifier for the child node. The remaining are passed-in by the caller.
4150 : *
4151 : * The children will be iterated over in the same order as they
4152 : * appear in the final devicetree.
4153 : *
4154 : * @param inst instance number
4155 : * @param fn macro to invoke on each child node identifier
4156 : * @param ... variable number of arguments to pass to @p fn
4157 : *
4158 : * @see DT_FOREACH_CHILD
4159 : */
4160 1 : #define DT_INST_FOREACH_CHILD_VARGS(inst, fn, ...) \
4161 : DT_FOREACH_CHILD_VARGS(DT_DRV_INST(inst), fn, __VA_ARGS__)
4162 :
4163 : /**
4164 : * @brief Call @p fn on all child nodes of DT_DRV_INST(inst) with separator.
4165 : *
4166 : * The macro @p fn takes multiple arguments. The first should be the node
4167 : * identifier for the child node. The remaining are passed-in by the caller.
4168 : *
4169 : * @param inst instance number
4170 : * @param fn macro to invoke on each child node identifier
4171 : * @param sep Separator (e.g. comma or semicolon). Must be in parentheses;
4172 : * this is required to enable providing a comma as separator.
4173 : * @param ... variable number of arguments to pass to @p fn
4174 : *
4175 : * @see DT_FOREACH_CHILD_SEP_VARGS
4176 : */
4177 1 : #define DT_INST_FOREACH_CHILD_SEP_VARGS(inst, fn, sep, ...) \
4178 : DT_FOREACH_CHILD_SEP_VARGS(DT_DRV_INST(inst), fn, sep, __VA_ARGS__)
4179 :
4180 : /**
4181 : * @brief Call @p fn on all child nodes of DT_DRV_INST(inst) with status `okay`.
4182 : *
4183 : * The macro @p fn should take one argument, which is the node
4184 : * identifier for the child node.
4185 : *
4186 : * @param inst instance number
4187 : * @param fn macro to invoke on each child node identifier
4188 : *
4189 : * @see DT_FOREACH_CHILD_STATUS_OKAY
4190 : */
4191 1 : #define DT_INST_FOREACH_CHILD_STATUS_OKAY(inst, fn) \
4192 : DT_FOREACH_CHILD_STATUS_OKAY(DT_DRV_INST(inst), fn)
4193 :
4194 : /**
4195 : * @brief Call @p fn on all child nodes of DT_DRV_INST(inst) with status `okay`
4196 : * and with separator.
4197 : *
4198 : * The macro @p fn should take one argument, which is the node
4199 : * identifier for the child node.
4200 : *
4201 : * @param inst instance number
4202 : * @param fn macro to invoke on each child node identifier
4203 : * @param sep Separator (e.g. comma or semicolon). Must be in parentheses;
4204 : * this is required to enable providing a comma as separator.
4205 : *
4206 : * @see DT_FOREACH_CHILD_STATUS_OKAY_SEP
4207 : */
4208 1 : #define DT_INST_FOREACH_CHILD_STATUS_OKAY_SEP(inst, fn, sep) \
4209 : DT_FOREACH_CHILD_STATUS_OKAY_SEP(DT_DRV_INST(inst), fn, sep)
4210 :
4211 : /**
4212 : * @brief Call @p fn on all child nodes of DT_DRV_INST(inst) with status `okay`
4213 : * and multiple arguments.
4214 : *
4215 : * The macro @p fn takes multiple arguments. The first should be the node
4216 : * identifier for the child node. The remaining are passed-in by the caller.
4217 : *
4218 : * @param inst instance number
4219 : * @param fn macro to invoke on each child node identifier
4220 : * @param ... variable number of arguments to pass to @p fn
4221 : *
4222 : * @see DT_FOREACH_CHILD_STATUS_OKAY_VARGS
4223 : */
4224 1 : #define DT_INST_FOREACH_CHILD_STATUS_OKAY_VARGS(inst, fn, ...) \
4225 : DT_FOREACH_CHILD_STATUS_OKAY_VARGS(DT_DRV_INST(inst), fn, __VA_ARGS__)
4226 :
4227 : /**
4228 : * @brief Call @p fn on all child nodes of DT_DRV_INST(inst) with status `okay`
4229 : * and with separator and multiple arguments.
4230 : *
4231 : * The macro @p fn takes multiple arguments. The first should be the node
4232 : * identifier for the child node. The remaining are passed-in by the caller.
4233 : *
4234 : * @param inst instance number
4235 : * @param fn macro to invoke on each child node identifier
4236 : * @param sep Separator (e.g. comma or semicolon). Must be in parentheses;
4237 : * this is required to enable providing a comma as separator.
4238 : * @param ... variable number of arguments to pass to @p fn
4239 : *
4240 : * @see DT_FOREACH_CHILD_STATUS_OKAY_SEP_VARGS
4241 : */
4242 1 : #define DT_INST_FOREACH_CHILD_STATUS_OKAY_SEP_VARGS(inst, fn, sep, ...) \
4243 : DT_FOREACH_CHILD_STATUS_OKAY_SEP_VARGS(DT_DRV_INST(inst), fn, sep, __VA_ARGS__)
4244 :
4245 : /**
4246 : * @brief Get a `DT_DRV_COMPAT` property array value's index into its enumeration values
4247 : * @param inst instance number
4248 : * @param prop lowercase-and-underscores property name
4249 : * @param idx the index to get
4250 : * @return zero-based index of the property's value in its enum: list
4251 : */
4252 1 : #define DT_INST_ENUM_IDX_BY_IDX(inst, prop, idx) \
4253 : DT_ENUM_IDX_BY_IDX(DT_DRV_INST(inst), prop, idx)
4254 :
4255 : /**
4256 : * @brief Get a `DT_DRV_COMPAT` value's index into its enumeration values
4257 : * @param inst instance number
4258 : * @param prop lowercase-and-underscores property name
4259 : * @return zero-based index of the property's value in its enum: list
4260 : */
4261 1 : #define DT_INST_ENUM_IDX(inst, prop) \
4262 : DT_ENUM_IDX(DT_DRV_INST(inst), prop)
4263 :
4264 : /**
4265 : * @brief Like DT_INST_ENUM_IDX_BY_IDX(), but with a fallback to a default enum index
4266 : * @param inst instance number
4267 : * @param prop lowercase-and-underscores property name
4268 : * @param idx the index to get
4269 : * @param default_idx_value a fallback index value to expand to
4270 : * @return zero-based index of the property's value in its enum if present,
4271 : * default_idx_value otherwise
4272 : */
4273 1 : #define DT_INST_ENUM_IDX_BY_IDX_OR(inst, prop, idx, default_idx_value) \
4274 : DT_ENUM_IDX_BY_IDX_OR(DT_DRV_INST(inst), prop, idx, default_idx_value)
4275 :
4276 : /**
4277 : * @brief Like DT_INST_ENUM_IDX(), but with a fallback to a default enum index
4278 : * @param inst instance number
4279 : * @param prop lowercase-and-underscores property name
4280 : * @param default_idx_value a fallback index value to expand to
4281 : * @return zero-based index of the property's value in its enum if present,
4282 : * default_idx_value otherwise
4283 : */
4284 1 : #define DT_INST_ENUM_IDX_OR(inst, prop, default_idx_value) \
4285 : DT_ENUM_IDX_OR(DT_DRV_INST(inst), prop, default_idx_value)
4286 :
4287 : /**
4288 : * @brief Does a `DT_DRV_COMPAT` enumeration property have a given value by index?
4289 : * @param inst instance number
4290 : * @param prop lowercase-and-underscores property name
4291 : * @param idx the index to get
4292 : * @param value lowercase-and-underscores enumeration value
4293 : * @return zero-based index of the property's value in its enum
4294 : */
4295 1 : #define DT_INST_ENUM_HAS_VALUE_BY_IDX(inst, prop, idx, value) \
4296 : DT_ENUM_HAS_VALUE_BY_IDX(DT_DRV_INST(inst), prop, idx, value)
4297 :
4298 : /**
4299 : * @brief Does a `DT_DRV_COMPAT` enumeration property have a given value?
4300 : *
4301 : * @param inst instance number
4302 : * @param prop lowercase-and-underscores property name
4303 : * @param value lowercase-and-underscores enumeration value
4304 : * @return 1 if the node property has the value @a value, 0 otherwise.
4305 : */
4306 1 : #define DT_INST_ENUM_HAS_VALUE(inst, prop, value) \
4307 : DT_ENUM_HAS_VALUE(DT_DRV_INST(inst), prop, value)
4308 :
4309 : /**
4310 : * @brief Get a `DT_DRV_COMPAT` instance property
4311 : * @param inst instance number
4312 : * @param prop lowercase-and-underscores property name
4313 : * @return a representation of the property's value
4314 : */
4315 1 : #define DT_INST_PROP(inst, prop) DT_PROP(DT_DRV_INST(inst), prop)
4316 :
4317 : /**
4318 : * @brief Get a `DT_DRV_COMPAT` property length
4319 : * @param inst instance number
4320 : * @param prop lowercase-and-underscores property name
4321 : * @return logical length of the property
4322 : */
4323 1 : #define DT_INST_PROP_LEN(inst, prop) DT_PROP_LEN(DT_DRV_INST(inst), prop)
4324 :
4325 : /**
4326 : * @brief Is index @p idx valid for an array type property
4327 : * on a `DT_DRV_COMPAT` instance?
4328 : * @param inst instance number
4329 : * @param prop lowercase-and-underscores property name
4330 : * @param idx index to check
4331 : * @return 1 if @p idx is a valid index into the given property,
4332 : * 0 otherwise.
4333 : */
4334 1 : #define DT_INST_PROP_HAS_IDX(inst, prop, idx) \
4335 : DT_PROP_HAS_IDX(DT_DRV_INST(inst), prop, idx)
4336 :
4337 : /**
4338 : * @brief Is name @p name available in a `foo-names` property?
4339 : * @param inst instance number
4340 : * @param prop a lowercase-and-underscores `prop-names` type property
4341 : * @param name a lowercase-and-underscores name to check
4342 : * @return An expression which evaluates to 1 if @p name is an available
4343 : * name into the given property, and 0 otherwise.
4344 : */
4345 1 : #define DT_INST_PROP_HAS_NAME(inst, prop, name) \
4346 : DT_PROP_HAS_NAME(DT_DRV_INST(inst), prop, name)
4347 :
4348 : /**
4349 : * @brief Get a `DT_DRV_COMPAT` element value in an array property
4350 : * @param inst instance number
4351 : * @param prop lowercase-and-underscores property name
4352 : * @param idx the index to get
4353 : * @return a representation of the idx-th element of the property
4354 : */
4355 1 : #define DT_INST_PROP_BY_IDX(inst, prop, idx) \
4356 : DT_PROP_BY_IDX(DT_DRV_INST(inst), prop, idx)
4357 :
4358 : /**
4359 : * @brief Like DT_INST_PROP(), but with a fallback to @p default_value
4360 : * @param inst instance number
4361 : * @param prop lowercase-and-underscores property name
4362 : * @param default_value a fallback value to expand to
4363 : * @return DT_INST_PROP(inst, prop) or @p default_value
4364 : */
4365 1 : #define DT_INST_PROP_OR(inst, prop, default_value) \
4366 : DT_PROP_OR(DT_DRV_INST(inst), prop, default_value)
4367 :
4368 : /**
4369 : * @brief Like DT_INST_PROP_LEN(), but with a fallback to @p default_value
4370 : * @param inst instance number
4371 : * @param prop lowercase-and-underscores property name
4372 : * @param default_value a fallback value to expand to
4373 : * @return DT_INST_PROP_LEN(inst, prop) or @p default_value
4374 : */
4375 1 : #define DT_INST_PROP_LEN_OR(inst, prop, default_value) \
4376 : DT_PROP_LEN_OR(DT_DRV_INST(inst), prop, default_value)
4377 :
4378 : /**
4379 : * @brief Get a `DT_DRV_COMPAT` instance's string property's value as a
4380 : * token.
4381 : *
4382 : * @param inst instance number
4383 : * @param prop lowercase-and-underscores property name
4384 : * @return the value of @p prop as a token, i.e. without any quotes
4385 : * and with special characters converted to underscores
4386 : */
4387 1 : #define DT_INST_STRING_TOKEN(inst, prop) \
4388 : DT_STRING_TOKEN(DT_DRV_INST(inst), prop)
4389 :
4390 : /**
4391 : * @brief Like DT_INST_STRING_TOKEN(), but uppercased.
4392 : * @param inst instance number
4393 : * @param prop lowercase-and-underscores property name
4394 : * @return the value of @p prop as an uppercased token, i.e. without
4395 : * any quotes and with special characters converted to underscores
4396 : */
4397 1 : #define DT_INST_STRING_UPPER_TOKEN(inst, prop) \
4398 : DT_STRING_UPPER_TOKEN(DT_DRV_INST(inst), prop)
4399 :
4400 : /**
4401 : * @brief Get a `DT_DRV_COMPAT` instance's string property's value as
4402 : * an unquoted sequence of tokens.
4403 : *
4404 : * @param inst instance number
4405 : * @param prop lowercase-and-underscores property name
4406 : * @return the value of @p prop as a sequence of tokens, with no quotes
4407 : */
4408 1 : #define DT_INST_STRING_UNQUOTED(inst, prop) \
4409 : DT_STRING_UNQUOTED(DT_DRV_INST(inst), prop)
4410 :
4411 : /**
4412 : * @brief Get an element out of string-array property as a token.
4413 : * @param inst instance number
4414 : * @param prop lowercase-and-underscores property name
4415 : * @param idx the index to get
4416 : * @return the element in @p prop at index @p idx as a token
4417 : */
4418 1 : #define DT_INST_STRING_TOKEN_BY_IDX(inst, prop, idx) \
4419 : DT_STRING_TOKEN_BY_IDX(DT_DRV_INST(inst), prop, idx)
4420 :
4421 : /**
4422 : * @brief Like DT_INST_STRING_TOKEN_BY_IDX(), but uppercased.
4423 : * @param inst instance number
4424 : * @param prop lowercase-and-underscores property name
4425 : * @param idx the index to get
4426 : * @return the element in @p prop at index @p idx as an uppercased token
4427 : */
4428 1 : #define DT_INST_STRING_UPPER_TOKEN_BY_IDX(inst, prop, idx) \
4429 : DT_STRING_UPPER_TOKEN_BY_IDX(DT_DRV_INST(inst), prop, idx)
4430 :
4431 : /**
4432 : * @brief Get an element out of string-array property as an unquoted sequence of tokens.
4433 : * @param inst instance number
4434 : * @param prop lowercase-and-underscores property name
4435 : * @param idx the index to get
4436 : * @return the value of @p prop at index @p idx as a sequence of tokens, with no quotes
4437 : */
4438 1 : #define DT_INST_STRING_UNQUOTED_BY_IDX(inst, prop, idx) \
4439 : DT_STRING_UNQUOTED_BY_IDX(DT_DRV_INST(inst), prop, idx)
4440 :
4441 : /**
4442 : * @brief Get a `DT_DRV_COMPAT` instance's property value from a phandle's node
4443 : * @param inst instance number
4444 : * @param ph lowercase-and-underscores property of @p inst
4445 : * with type `phandle`
4446 : * @param prop lowercase-and-underscores property of the phandle's node
4447 : * @return the value of @p prop as described in the DT_PROP() documentation
4448 : */
4449 1 : #define DT_INST_PROP_BY_PHANDLE(inst, ph, prop) \
4450 : DT_INST_PROP_BY_PHANDLE_IDX(inst, ph, 0, prop)
4451 :
4452 : /**
4453 : * @brief Get a `DT_DRV_COMPAT` instance's property value from a phandle in a
4454 : * property.
4455 : * @param inst instance number
4456 : * @param phs lowercase-and-underscores property with type `phandle`,
4457 : * `phandles`, or `phandle-array`
4458 : * @param idx logical index into "phs", which must be zero if "phs"
4459 : * has type `phandle`
4460 : * @param prop lowercase-and-underscores property of the phandle's node
4461 : * @return the value of @p prop as described in the DT_PROP() documentation
4462 : */
4463 1 : #define DT_INST_PROP_BY_PHANDLE_IDX(inst, phs, idx, prop) \
4464 : DT_PROP_BY_PHANDLE_IDX(DT_DRV_INST(inst), phs, idx, prop)
4465 :
4466 : /**
4467 : * @brief Get a `DT_DRV_COMPAT` instance's phandle-array specifier value at an index
4468 : * @param inst instance number
4469 : * @param pha lowercase-and-underscores property with type `phandle-array`
4470 : * @param idx logical index into the property @p pha
4471 : * @param cell binding's cell name within the specifier at index @p idx
4472 : * @return the value of the cell inside the specifier at index @p idx
4473 : */
4474 1 : #define DT_INST_PHA_BY_IDX(inst, pha, idx, cell) \
4475 : DT_PHA_BY_IDX(DT_DRV_INST(inst), pha, idx, cell)
4476 :
4477 : /**
4478 : * @brief Like DT_INST_PHA_BY_IDX(), but with a fallback to default_value
4479 : * @param inst instance number
4480 : * @param pha lowercase-and-underscores property with type `phandle-array`
4481 : * @param idx logical index into the property @p pha
4482 : * @param cell binding's cell name within the specifier at index @p idx
4483 : * @param default_value a fallback value to expand to
4484 : * @return DT_INST_PHA_BY_IDX(inst, pha, idx, cell) or default_value
4485 : */
4486 1 : #define DT_INST_PHA_BY_IDX_OR(inst, pha, idx, cell, default_value) \
4487 : DT_PHA_BY_IDX_OR(DT_DRV_INST(inst), pha, idx, cell, default_value)
4488 :
4489 : /**
4490 : * @brief Get a `DT_DRV_COMPAT` instance's phandle-array specifier value
4491 : * Equivalent to DT_INST_PHA_BY_IDX(inst, pha, 0, cell)
4492 : * @param inst instance number
4493 : * @param pha lowercase-and-underscores property with type `phandle-array`
4494 : * @param cell binding's cell name for the specifier at @p pha index 0
4495 : * @return the cell value
4496 : */
4497 1 : #define DT_INST_PHA(inst, pha, cell) DT_INST_PHA_BY_IDX(inst, pha, 0, cell)
4498 :
4499 : /**
4500 : * @brief Like DT_INST_PHA(), but with a fallback to default_value
4501 : * @param inst instance number
4502 : * @param pha lowercase-and-underscores property with type `phandle-array`
4503 : * @param cell binding's cell name for the specifier at @p pha index 0
4504 : * @param default_value a fallback value to expand to
4505 : * @return DT_INST_PHA(inst, pha, cell) or default_value
4506 : */
4507 1 : #define DT_INST_PHA_OR(inst, pha, cell, default_value) \
4508 : DT_INST_PHA_BY_IDX_OR(inst, pha, 0, cell, default_value)
4509 :
4510 : /**
4511 : * @brief Get a `DT_DRV_COMPAT` instance's value within a phandle-array
4512 : * specifier by name
4513 : * @param inst instance number
4514 : * @param pha lowercase-and-underscores property with type `phandle-array`
4515 : * @param name lowercase-and-underscores name of a specifier in @p pha
4516 : * @param cell binding's cell name for the named specifier
4517 : * @return the cell value
4518 : */
4519 1 : #define DT_INST_PHA_BY_NAME(inst, pha, name, cell) \
4520 : DT_PHA_BY_NAME(DT_DRV_INST(inst), pha, name, cell)
4521 :
4522 : /**
4523 : * @brief Like DT_INST_PHA_BY_NAME(), but with a fallback to default_value
4524 : * @param inst instance number
4525 : * @param pha lowercase-and-underscores property with type `phandle-array`
4526 : * @param name lowercase-and-underscores name of a specifier in @p pha
4527 : * @param cell binding's cell name for the named specifier
4528 : * @param default_value a fallback value to expand to
4529 : * @return DT_INST_PHA_BY_NAME(inst, pha, name, cell) or default_value
4530 : */
4531 1 : #define DT_INST_PHA_BY_NAME_OR(inst, pha, name, cell, default_value) \
4532 : DT_PHA_BY_NAME_OR(DT_DRV_INST(inst), pha, name, cell, default_value)
4533 :
4534 : /**
4535 : * @brief Get a `DT_DRV_COMPAT` instance's phandle node identifier from a
4536 : * phandle array by name
4537 : * @param inst instance number
4538 : * @param pha lowercase-and-underscores property with type `phandle-array`
4539 : * @param name lowercase-and-underscores name of an element in @p pha
4540 : * @return node identifier for the phandle at the element named "name"
4541 : */
4542 1 : #define DT_INST_PHANDLE_BY_NAME(inst, pha, name) \
4543 : DT_PHANDLE_BY_NAME(DT_DRV_INST(inst), pha, name) \
4544 :
4545 : /**
4546 : * @brief Get a `DT_DRV_COMPAT` instance's node identifier for a phandle in
4547 : * a property.
4548 : * @param inst instance number
4549 : * @param prop lowercase-and-underscores property name in @p inst
4550 : * with type `phandle`, `phandles` or `phandle-array`
4551 : * @param idx index into @p prop
4552 : * @return a node identifier for the phandle at index @p idx in @p prop
4553 : */
4554 1 : #define DT_INST_PHANDLE_BY_IDX(inst, prop, idx) \
4555 : DT_PHANDLE_BY_IDX(DT_DRV_INST(inst), prop, idx)
4556 :
4557 : /**
4558 : * @brief Get a `DT_DRV_COMPAT` instance's node identifier for a phandle
4559 : * property's value
4560 : * @param inst instance number
4561 : * @param prop lowercase-and-underscores property of @p inst
4562 : * with type `phandle`
4563 : * @return a node identifier for the node pointed to by "ph"
4564 : */
4565 1 : #define DT_INST_PHANDLE(inst, prop) DT_INST_PHANDLE_BY_IDX(inst, prop, 0)
4566 :
4567 : /**
4568 : * @brief is @p idx a valid register block index on a `DT_DRV_COMPAT` instance?
4569 : * @param inst instance number
4570 : * @param idx index to check
4571 : * @return 1 if @p idx is a valid register block index,
4572 : * 0 otherwise.
4573 : */
4574 1 : #define DT_INST_REG_HAS_IDX(inst, idx) DT_REG_HAS_IDX(DT_DRV_INST(inst), idx)
4575 :
4576 : /**
4577 : * @brief is @p name a valid register block name on a `DT_DRV_COMPAT` instance?
4578 : * @param inst instance number
4579 : * @param name name to check
4580 : * @return 1 if @p name is a valid register block name,
4581 : * 0 otherwise.
4582 : */
4583 1 : #define DT_INST_REG_HAS_NAME(inst, name) DT_REG_HAS_NAME(DT_DRV_INST(inst), name)
4584 :
4585 : /**
4586 : * @brief Get a `DT_DRV_COMPAT` instance's idx-th register block's raw address
4587 : * @param inst instance number
4588 : * @param idx index of the register whose address to return
4589 : * @return address of the instance's idx-th register block
4590 : */
4591 1 : #define DT_INST_REG_ADDR_BY_IDX_RAW(inst, idx) DT_REG_ADDR_BY_IDX_RAW(DT_DRV_INST(inst), idx)
4592 :
4593 : /**
4594 : * @brief Get a `DT_DRV_COMPAT` instance's idx-th register block's address
4595 : * @param inst instance number
4596 : * @param idx index of the register whose address to return
4597 : * @return address of the instance's idx-th register block
4598 : */
4599 1 : #define DT_INST_REG_ADDR_BY_IDX(inst, idx) DT_REG_ADDR_BY_IDX(DT_DRV_INST(inst), idx)
4600 :
4601 : /**
4602 : * @brief Get a `DT_DRV_COMPAT` instance's idx-th register block's size
4603 : * @param inst instance number
4604 : * @param idx index of the register whose size to return
4605 : * @return size of the instance's idx-th register block
4606 : */
4607 1 : #define DT_INST_REG_SIZE_BY_IDX(inst, idx) \
4608 : DT_REG_SIZE_BY_IDX(DT_DRV_INST(inst), idx)
4609 :
4610 : /**
4611 : * @brief Get a `DT_DRV_COMPAT`'s register block address by name
4612 : * @param inst instance number
4613 : * @param name lowercase-and-underscores register specifier name
4614 : * @return address of the register block with the given @p name
4615 : */
4616 1 : #define DT_INST_REG_ADDR_BY_NAME(inst, name) \
4617 : DT_REG_ADDR_BY_NAME(DT_DRV_INST(inst), name)
4618 :
4619 : /**
4620 : * @brief Like DT_INST_REG_ADDR_BY_NAME(), but with a fallback to @p default_value
4621 : * @param inst instance number
4622 : * @param name lowercase-and-underscores register specifier name
4623 : * @param default_value a fallback value to expand to
4624 : * @return address of the register block specified by name if present,
4625 : * @p default_value otherwise
4626 : */
4627 1 : #define DT_INST_REG_ADDR_BY_NAME_OR(inst, name, default_value) \
4628 : DT_REG_ADDR_BY_NAME_OR(DT_DRV_INST(inst), name, default_value)
4629 :
4630 : /**
4631 : * @brief 64-bit version of DT_INST_REG_ADDR_BY_NAME()
4632 : *
4633 : * This macro version adds the appropriate suffix for 64-bit unsigned
4634 : * integer literals.
4635 : * Note that this macro is equivalent to DT_INST_REG_ADDR_BY_NAME() in
4636 : * linker/ASM context.
4637 : *
4638 : * @param inst instance number
4639 : * @param name lowercase-and-underscores register specifier name
4640 : * @return address of the register block with the given @p name
4641 : */
4642 1 : #define DT_INST_REG_ADDR_BY_NAME_U64(inst, name) \
4643 : DT_REG_ADDR_BY_NAME_U64(DT_DRV_INST(inst), name)
4644 :
4645 : /**
4646 : * @brief Get a `DT_DRV_COMPAT`'s register block size by name
4647 : * @param inst instance number
4648 : * @param name lowercase-and-underscores register specifier name
4649 : * @return size of the register block with the given @p name
4650 : */
4651 1 : #define DT_INST_REG_SIZE_BY_NAME(inst, name) \
4652 : DT_REG_SIZE_BY_NAME(DT_DRV_INST(inst), name)
4653 :
4654 : /**
4655 : * @brief Like DT_INST_REG_SIZE_BY_NAME(), but with a fallback to @p default_value
4656 : * @param inst instance number
4657 : * @param name lowercase-and-underscores register specifier name
4658 : * @param default_value a fallback value to expand to
4659 : * @return size of the register block specified by name if present,
4660 : * @p default_value otherwise
4661 : */
4662 1 : #define DT_INST_REG_SIZE_BY_NAME_OR(inst, name, default_value) \
4663 : DT_REG_SIZE_BY_NAME_OR(DT_DRV_INST(inst), name, default_value)
4664 :
4665 : /**
4666 : * @brief Get a `DT_DRV_COMPAT`'s (only) register block raw address
4667 : * @param inst instance number
4668 : * @return instance's register block address
4669 : */
4670 1 : #define DT_INST_REG_ADDR_RAW(inst) DT_INST_REG_ADDR_BY_IDX_RAW(inst, 0)
4671 :
4672 : /**
4673 : * @brief Get a `DT_DRV_COMPAT`'s (only) register block address
4674 : * @param inst instance number
4675 : * @return instance's register block address
4676 : */
4677 1 : #define DT_INST_REG_ADDR(inst) DT_INST_REG_ADDR_BY_IDX(inst, 0)
4678 :
4679 : /**
4680 : * @brief 64-bit version of DT_INST_REG_ADDR()
4681 : *
4682 : * This macro version adds the appropriate suffix for 64-bit unsigned
4683 : * integer literals.
4684 : * Note that this macro is equivalent to DT_INST_REG_ADDR() in
4685 : * linker/ASM context.
4686 : *
4687 : * @param inst instance number
4688 : * @return instance's register block address
4689 : */
4690 1 : #define DT_INST_REG_ADDR_U64(inst) DT_REG_ADDR_U64(DT_DRV_INST(inst))
4691 :
4692 : /**
4693 : * @brief Get a `DT_DRV_COMPAT`'s (only) register block size
4694 : * @param inst instance number
4695 : * @return instance's register block size
4696 : */
4697 1 : #define DT_INST_REG_SIZE(inst) DT_INST_REG_SIZE_BY_IDX(inst, 0)
4698 :
4699 : /**
4700 : * @brief Get a `DT_DRV_COMPAT`'s number of interrupts
4701 : *
4702 : * @param inst instance number
4703 : * @return number of interrupts
4704 : */
4705 1 : #define DT_INST_NUM_IRQS(inst) DT_NUM_IRQS(DT_DRV_INST(inst))
4706 :
4707 : /**
4708 : * @brief Get a `DT_DRV_COMPAT` interrupt level
4709 : *
4710 : * @param inst instance number
4711 : * @return interrupt level
4712 : */
4713 1 : #define DT_INST_IRQ_LEVEL(inst) DT_IRQ_LEVEL(DT_DRV_INST(inst))
4714 :
4715 : /**
4716 : * @brief Get a `DT_DRV_COMPAT` interrupt specifier value at an index
4717 : * @param inst instance number
4718 : * @param idx logical index into the interrupt specifier array
4719 : * @param cell cell name specifier
4720 : * @return the named value at the specifier given by the index
4721 : */
4722 1 : #define DT_INST_IRQ_BY_IDX(inst, idx, cell) \
4723 : DT_IRQ_BY_IDX(DT_DRV_INST(inst), idx, cell)
4724 :
4725 : /**
4726 : * @brief Get a `DT_DRV_COMPAT` interrupt specifier's interrupt controller by index
4727 : * @param inst instance number
4728 : * @param idx interrupt specifier's index
4729 : * @return node_id of interrupt specifier's interrupt controller
4730 : */
4731 1 : #define DT_INST_IRQ_INTC_BY_IDX(inst, idx) \
4732 : DT_IRQ_INTC_BY_IDX(DT_DRV_INST(inst), idx)
4733 :
4734 : /**
4735 : * @brief Get a `DT_DRV_COMPAT` interrupt specifier's interrupt controller by name
4736 : * @param inst instance number
4737 : * @param name interrupt specifier's name
4738 : * @return node_id of interrupt specifier's interrupt controller
4739 : */
4740 1 : #define DT_INST_IRQ_INTC_BY_NAME(inst, name) \
4741 : DT_IRQ_INTC_BY_NAME(DT_DRV_INST(inst), name)
4742 :
4743 : /**
4744 : * @brief Get a `DT_DRV_COMPAT` interrupt specifier's interrupt controller
4745 : * @note Equivalent to DT_INST_IRQ_INTC_BY_IDX(node_id, 0)
4746 : * @param inst instance number
4747 : * @return node_id of interrupt specifier's interrupt controller
4748 : * @see DT_INST_IRQ_INTC_BY_IDX()
4749 : */
4750 1 : #define DT_INST_IRQ_INTC(inst) \
4751 : DT_INST_IRQ_INTC_BY_IDX(inst, 0)
4752 :
4753 : /**
4754 : * @brief Get a `DT_DRV_COMPAT` interrupt specifier value by name
4755 : * @param inst instance number
4756 : * @param name lowercase-and-underscores interrupt specifier name
4757 : * @param cell cell name specifier
4758 : * @return the named value at the specifier given by the index
4759 : */
4760 1 : #define DT_INST_IRQ_BY_NAME(inst, name, cell) \
4761 : DT_IRQ_BY_NAME(DT_DRV_INST(inst), name, cell)
4762 :
4763 : /**
4764 : * @brief Get a `DT_DRV_COMPAT` interrupt specifier's value
4765 : * @param inst instance number
4766 : * @param cell cell name specifier
4767 : * @return the named value at that index
4768 : */
4769 1 : #define DT_INST_IRQ(inst, cell) DT_INST_IRQ_BY_IDX(inst, 0, cell)
4770 :
4771 : /**
4772 : * @brief Get a `DT_DRV_COMPAT`'s (only) irq number
4773 : * @param inst instance number
4774 : * @return the interrupt number for the node's only interrupt
4775 : */
4776 1 : #define DT_INST_IRQN(inst) DT_IRQN(DT_DRV_INST(inst))
4777 :
4778 : /**
4779 : * @brief Get a `DT_DRV_COMPAT`'s irq number at index
4780 : * @param inst instance number
4781 : * @param idx logical index into the interrupt specifier array
4782 : * @return the interrupt number for the node's idx-th interrupt
4783 : */
4784 1 : #define DT_INST_IRQN_BY_IDX(inst, idx) DT_IRQN_BY_IDX(DT_DRV_INST(inst), idx)
4785 :
4786 : /**
4787 : * @brief Get a `DT_DRV_COMPAT`'s bus node identifier
4788 : * @param inst instance number
4789 : * @return node identifier for the instance's bus node
4790 : */
4791 1 : #define DT_INST_BUS(inst) DT_BUS(DT_DRV_INST(inst))
4792 :
4793 : /**
4794 : * @brief Test if a `DT_DRV_COMPAT`'s bus type is a given type
4795 : * @param inst instance number
4796 : * @param bus a binding's bus type as a C token, lowercased and without quotes
4797 : * @return 1 if the given instance is on a bus of the given type,
4798 : * 0 otherwise
4799 : */
4800 1 : #define DT_INST_ON_BUS(inst, bus) DT_ON_BUS(DT_DRV_INST(inst), bus)
4801 :
4802 : /**
4803 : * @brief Like DT_INST_STRING_TOKEN(), but with a fallback to @p default_value
4804 : * @param inst instance number
4805 : * @param name lowercase-and-underscores property name
4806 : * @param default_value a fallback value to expand to
4807 : * @return if @p prop exists, its value as a token, i.e. without any quotes and
4808 : * with special characters converted to underscores. Otherwise
4809 : * @p default_value
4810 : */
4811 1 : #define DT_INST_STRING_TOKEN_OR(inst, name, default_value) \
4812 : DT_STRING_TOKEN_OR(DT_DRV_INST(inst), name, default_value)
4813 :
4814 : /**
4815 : * @brief Like DT_INST_STRING_UPPER_TOKEN(), but with a fallback to
4816 : * @p default_value
4817 : * @param inst instance number
4818 : * @param name lowercase-and-underscores property name
4819 : * @param default_value a fallback value to expand to
4820 : * @return the property's value as an uppercased token, or @p default_value
4821 : */
4822 1 : #define DT_INST_STRING_UPPER_TOKEN_OR(inst, name, default_value) \
4823 : DT_STRING_UPPER_TOKEN_OR(DT_DRV_INST(inst), name, default_value)
4824 :
4825 : /**
4826 : * @brief Like DT_INST_STRING_UNQUOTED(), but with a fallback to
4827 : * @p default_value
4828 : * @param inst instance number
4829 : * @param name lowercase-and-underscores property name
4830 : * @param default_value a fallback value to expand to
4831 : * @return the property's value as a sequence of tokens, with no quotes, or @p default_value
4832 : */
4833 1 : #define DT_INST_STRING_UNQUOTED_OR(inst, name, default_value) \
4834 : DT_STRING_UNQUOTED_OR(DT_DRV_INST(inst), name, default_value)
4835 :
4836 : /**
4837 : * @brief Test if any enabled node with the given compatible is on
4838 : * the given bus type
4839 : *
4840 : * This is like DT_ANY_INST_ON_BUS_STATUS_OKAY(), except it can also
4841 : * be useful for handling multiple compatibles in single source file.
4842 : *
4843 : * Example devicetree overlay:
4844 : *
4845 : * @code{.dts}
4846 : * &i2c0 {
4847 : * temp: temperature-sensor@76 {
4848 : * compatible = "vnd,some-sensor";
4849 : * reg = <0x76>;
4850 : * };
4851 : * };
4852 : * @endcode
4853 : *
4854 : * Example usage, assuming `i2c0` is an I2C bus controller node, and
4855 : * therefore `temp` is on an I2C bus:
4856 : *
4857 : * @code{.c}
4858 : * DT_HAS_COMPAT_ON_BUS_STATUS_OKAY(vnd_some_sensor, i2c) // 1
4859 : * @endcode
4860 : *
4861 : * @param compat lowercase-and-underscores compatible, without quotes
4862 : * @param bus a binding's bus type as a C token, lowercased and without quotes
4863 : * @return 1 if any enabled node with that compatible is on that bus type,
4864 : * 0 otherwise
4865 : */
4866 1 : #define DT_HAS_COMPAT_ON_BUS_STATUS_OKAY(compat, bus) \
4867 : IS_ENABLED(DT_CAT4(DT_COMPAT_, compat, _BUS_, bus))
4868 :
4869 : /**
4870 : * @brief Test if any `DT_DRV_COMPAT` node is on a bus of a given type
4871 : * and has status okay
4872 : *
4873 : * This is a special-purpose macro which can be useful when writing
4874 : * drivers for devices which can appear on multiple buses. One example
4875 : * is a sensor device which may be wired on an I2C or SPI bus.
4876 : *
4877 : * Example devicetree overlay:
4878 : *
4879 : * @code{.dts}
4880 : * &i2c0 {
4881 : * temp: temperature-sensor@76 {
4882 : * compatible = "vnd,some-sensor";
4883 : * reg = <0x76>;
4884 : * };
4885 : * };
4886 : * @endcode
4887 : *
4888 : * Example usage, assuming `i2c0` is an I2C bus controller node, and
4889 : * therefore `temp` is on an I2C bus:
4890 : *
4891 : * @code{.c}
4892 : * #define DT_DRV_COMPAT vnd_some_sensor
4893 : *
4894 : * DT_ANY_INST_ON_BUS_STATUS_OKAY(i2c) // 1
4895 : * @endcode
4896 : *
4897 : * @param bus a binding's bus type as a C token, lowercased and without quotes
4898 : * @return 1 if any enabled node with that compatible is on that bus type,
4899 : * 0 otherwise
4900 : */
4901 1 : #define DT_ANY_INST_ON_BUS_STATUS_OKAY(bus) \
4902 : DT_HAS_COMPAT_ON_BUS_STATUS_OKAY(DT_DRV_COMPAT, bus)
4903 :
4904 : /**
4905 : * @brief Check if any `DT_DRV_COMPAT` node with status `okay` has a given
4906 : * property.
4907 : *
4908 : * @param prop lowercase-and-underscores property name
4909 : *
4910 : * Example devicetree overlay:
4911 : *
4912 : * @code{.dts}
4913 : * &i2c0 {
4914 : * sensor0: sensor@0 {
4915 : * compatible = "vnd,some-sensor";
4916 : * status = "okay";
4917 : * reg = <0>;
4918 : * foo = <1>;
4919 : * bar = <2>;
4920 : * };
4921 : *
4922 : * sensor1: sensor@1 {
4923 : * compatible = "vnd,some-sensor";
4924 : * status = "okay";
4925 : * reg = <1>;
4926 : * foo = <2>;
4927 : * };
4928 : *
4929 : * sensor2: sensor@2 {
4930 : * compatible = "vnd,some-sensor";
4931 : * status = "disabled";
4932 : * reg = <2>;
4933 : * baz = <1>;
4934 : * };
4935 : * };
4936 : * @endcode
4937 : *
4938 : * Example usage:
4939 : *
4940 : * @code{.c}
4941 : * #define DT_DRV_COMPAT vnd_some_sensor
4942 : *
4943 : * DT_ANY_INST_HAS_PROP_STATUS_OKAY(foo) // 1
4944 : * DT_ANY_INST_HAS_PROP_STATUS_OKAY(bar) // 1
4945 : * DT_ANY_INST_HAS_PROP_STATUS_OKAY(baz) // 0
4946 : * @endcode
4947 : */
4948 1 : #define DT_ANY_INST_HAS_PROP_STATUS_OKAY(prop) \
4949 : UTIL_NOT(IS_EMPTY( \
4950 : DT_INST_FOREACH_STATUS_OKAY_VARGS(DT_ANY_INST_HAS_PROP_STATUS_OKAY_, prop)))
4951 :
4952 : /**
4953 : * @brief Check if all `DT_DRV_COMPAT` node with status `okay` has a given
4954 : * property. If all nodes are disabled, this will return 1.
4955 : *
4956 : * @param prop lowercase-and-underscores property name
4957 : *
4958 : * Example devicetree overlay:
4959 : *
4960 : * @code{.dts}
4961 : * &i2c0 {
4962 : * sensor0: sensor@0 {
4963 : * compatible = "vnd,some-sensor";
4964 : * status = "okay";
4965 : * reg = <0>;
4966 : * foo = <1>;
4967 : * bar = <2>;
4968 : * };
4969 : *
4970 : * sensor1: sensor@1 {
4971 : * compatible = "vnd,some-sensor";
4972 : * status = "okay";
4973 : * reg = <1>;
4974 : * foo = <2>;
4975 : * };
4976 : *
4977 : * sensor2: sensor@2 {
4978 : * compatible = "vnd,some-sensor";
4979 : * status = "disabled";
4980 : * reg = <2>;
4981 : * baz = <1>;
4982 : * };
4983 : * };
4984 : * @endcode
4985 : *
4986 : * Example usage:
4987 : *
4988 : * @code{.c}
4989 : * #define DT_DRV_COMPAT vnd_some_sensor
4990 : *
4991 : * DT_ALL_INST_HAS_PROP_STATUS_OKAY(foo) // 1
4992 : * DT_ALL_INST_HAS_PROP_STATUS_OKAY(bar) // 0
4993 : * DT_ALL_INST_HAS_PROP_STATUS_OKAY(baz) // 0
4994 : * @endcode
4995 : */
4996 1 : #define DT_ALL_INST_HAS_PROP_STATUS_OKAY(prop) \
4997 : IS_EMPTY(DT_INST_FOREACH_STATUS_OKAY_VARGS(DT_ALL_INST_HAS_PROP_STATUS_OKAY_, prop))
4998 :
4999 : /**
5000 : * @brief Check if any device node with status `okay` has a given
5001 : * property.
5002 : *
5003 : * @param compat lowercase-and-underscores devicetree compatible
5004 : * @param prop lowercase-and-underscores property name
5005 : *
5006 : * Example devicetree overlay:
5007 : *
5008 : * @code{.dts}
5009 : * &i2c0 {
5010 : * sensor0: sensor@0 {
5011 : * compatible = "vnd,some-sensor";
5012 : * status = "okay";
5013 : * reg = <0>;
5014 : * foo = <1>;
5015 : * bar = <2>;
5016 : * };
5017 : *
5018 : * sensor1: sensor@1 {
5019 : * compatible = "vnd,some-sensor";
5020 : * status = "okay";
5021 : * reg = <1>;
5022 : * foo = <2>;
5023 : * };
5024 : *
5025 : * sensor2: sensor@2 {
5026 : * compatible = "vnd,some-sensor";
5027 : * status = "disabled";
5028 : * reg = <2>;
5029 : * baz = <1>;
5030 : * };
5031 : * };
5032 : * @endcode
5033 : *
5034 : * Example usage:
5035 : *
5036 : * @code{.c}
5037 : *
5038 : * DT_ANY_COMPAT_HAS_PROP_STATUS_OKAY(vnd_some_sensor, foo) // 1
5039 : * DT_ANY_COMPAT_HAS_PROP_STATUS_OKAY(vnd_some_sensor, bar) // 1
5040 : * DT_ANY_COMPAT_HAS_PROP_STATUS_OKAY(vnd_some_sensor, baz) // 0
5041 : * @endcode
5042 : */
5043 1 : #define DT_ANY_COMPAT_HAS_PROP_STATUS_OKAY(compat, prop) \
5044 : (DT_COMPAT_FOREACH_STATUS_OKAY_VARGS(compat, DT_COMPAT_NODE_HAS_PROP_AND_OR, prop) 0)
5045 :
5046 : /**
5047 : * @brief Check if any `DT_DRV_COMPAT` node with status `okay` has a given
5048 : * boolean property that exists.
5049 : *
5050 : * This differs from @ref DT_ANY_INST_HAS_PROP_STATUS_OKAY because even when not present
5051 : * on a node, the boolean property is generated with a value of 0 and therefore exists.
5052 : *
5053 : * @param prop lowercase-and-underscores property name
5054 : *
5055 : * Example devicetree overlay:
5056 : *
5057 : * @code{.dts}
5058 : * &i2c0 {
5059 : * sensor0: sensor@0 {
5060 : * compatible = "vnd,some-sensor";
5061 : * status = "okay";
5062 : * reg = <0>;
5063 : * foo;
5064 : * bar;
5065 : * };
5066 : *
5067 : * sensor1: sensor@1 {
5068 : * compatible = "vnd,some-sensor";
5069 : * status = "okay";
5070 : * reg = <1>;
5071 : * foo;
5072 : * };
5073 : *
5074 : * sensor2: sensor@2 {
5075 : * compatible = "vnd,some-sensor";
5076 : * status = "disabled";
5077 : * reg = <2>;
5078 : * baz;
5079 : * };
5080 : * };
5081 : * @endcode
5082 : *
5083 : * Example usage:
5084 : *
5085 : * @code{.c}
5086 : * #define DT_DRV_COMPAT vnd_some_sensor
5087 : *
5088 : * DT_ANY_INST_HAS_BOOL_STATUS_OKAY(foo) // 1
5089 : * DT_ANY_INST_HAS_BOOL_STATUS_OKAY(bar) // 1
5090 : * DT_ANY_INST_HAS_BOOL_STATUS_OKAY(baz) // 0
5091 : * @endcode
5092 : */
5093 1 : #define DT_ANY_INST_HAS_BOOL_STATUS_OKAY(prop) \
5094 : UTIL_NOT(IS_EMPTY( \
5095 : DT_INST_FOREACH_STATUS_OKAY_VARGS(DT_ANY_INST_HAS_BOOL_STATUS_OKAY_, prop)))
5096 :
5097 : /**
5098 : * @brief Check if all `DT_DRV_COMPAT` node with status `okay` has a given
5099 : * boolean property that exists. If all nodes are disabled, this
5100 : * will return 1.
5101 : * *
5102 : * @param prop lowercase-and-underscores property name
5103 : *
5104 : * Example devicetree overlay:
5105 : *
5106 : * @code{.dts}
5107 : * &i2c0 {
5108 : * sensor0: sensor@0 {
5109 : * compatible = "vnd,some-sensor";
5110 : * status = "okay";
5111 : * reg = <0>;
5112 : * foo;
5113 : * bar;
5114 : * };
5115 : *
5116 : * sensor1: sensor@1 {
5117 : * compatible = "vnd,some-sensor";
5118 : * status = "okay";
5119 : * reg = <1>;
5120 : * foo;
5121 : * };
5122 : *
5123 : * sensor2: sensor@2 {
5124 : * compatible = "vnd,some-sensor";
5125 : * status = "disabled";
5126 : * reg = <2>;
5127 : * baz;
5128 : * };
5129 : * };
5130 : * @endcode
5131 : *
5132 : * Example usage:
5133 : *
5134 : * @code{.c}
5135 : * #define DT_DRV_COMPAT vnd_some_sensor
5136 : *
5137 : * DT_ALL_INST_HAS_BOOL_STATUS_OKAY(foo) // 1
5138 : * DT_ALL_INST_HAS_BOOL_STATUS_OKAY(bar) // 0
5139 : * DT_ALL_INST_HAS_BOOL_STATUS_OKAY(baz) // 0
5140 : * @endcode
5141 : */
5142 1 : #define DT_ALL_INST_HAS_BOOL_STATUS_OKAY(prop) \
5143 : IS_EMPTY(DT_INST_FOREACH_STATUS_OKAY_VARGS(DT_ALL_INST_HAS_BOOL_STATUS_OKAY_, prop))
5144 :
5145 : /**
5146 : * @brief Call @p fn on all nodes with compatible `DT_DRV_COMPAT`
5147 : * and status `okay`
5148 : *
5149 : * This macro calls `fn(inst)` on each `inst` number that refers to a
5150 : * node with status `okay`. Whitespace is added between invocations.
5151 : *
5152 : * Example devicetree fragment:
5153 : *
5154 : * @code{.dts}
5155 : * a {
5156 : * compatible = "vnd,device";
5157 : * status = "okay";
5158 : * foobar = "DEV_A";
5159 : * };
5160 : *
5161 : * b {
5162 : * compatible = "vnd,device";
5163 : * status = "okay";
5164 : * foobar = "DEV_B";
5165 : * };
5166 : *
5167 : * c {
5168 : * compatible = "vnd,device";
5169 : * status = "disabled";
5170 : * foobar = "DEV_C";
5171 : * };
5172 : * @endcode
5173 : *
5174 : * Example usage:
5175 : *
5176 : * @code{.c}
5177 : * #define DT_DRV_COMPAT vnd_device
5178 : * #define MY_FN(inst) DT_INST_PROP(inst, foobar),
5179 : *
5180 : * DT_INST_FOREACH_STATUS_OKAY(MY_FN)
5181 : * @endcode
5182 : *
5183 : * This expands to:
5184 : *
5185 : * @code{.c}
5186 : * MY_FN(0) MY_FN(1)
5187 : * @endcode
5188 : *
5189 : * and from there, to either this:
5190 : *
5191 : * "DEV_A", "DEV_B",
5192 : *
5193 : * or this:
5194 : *
5195 : * "DEV_B", "DEV_A",
5196 : *
5197 : * No guarantees are made about the order that a and b appear in the
5198 : * expansion.
5199 : *
5200 : * Note that @p fn is responsible for adding commas, semicolons, or
5201 : * other separators or terminators.
5202 : *
5203 : * Device drivers should use this macro whenever possible to
5204 : * instantiate a struct device for each enabled node in the devicetree
5205 : * of the driver's compatible `DT_DRV_COMPAT`.
5206 : *
5207 : * @param fn Macro to call for each enabled node. Must accept an
5208 : * instance number as its only parameter.
5209 : */
5210 1 : #define DT_INST_FOREACH_STATUS_OKAY(fn) \
5211 : COND_CODE_1(DT_HAS_COMPAT_STATUS_OKAY(DT_DRV_COMPAT), \
5212 : (UTIL_CAT(DT_FOREACH_OKAY_INST_, \
5213 : DT_DRV_COMPAT)(fn)), \
5214 : ())
5215 :
5216 : /**
5217 : * @brief Call @p fn on all nodes with compatible `DT_DRV_COMPAT`
5218 : * and status `okay` with multiple arguments
5219 : *
5220 : *
5221 : * @param fn Macro to call for each enabled node. Must accept an
5222 : * instance number.
5223 : * @param ... variable number of arguments to pass to @p fn
5224 : *
5225 : * @see DT_INST_FOREACH_STATUS_OKAY
5226 : * @see DT_COMPAT_FOREACH_STATUS_OKAY_VARGS
5227 : */
5228 1 : #define DT_INST_FOREACH_STATUS_OKAY_VARGS(fn, ...) \
5229 : COND_CODE_1(DT_HAS_COMPAT_STATUS_OKAY(DT_DRV_COMPAT), \
5230 : (UTIL_CAT(DT_FOREACH_OKAY_INST_VARGS_, \
5231 : DT_DRV_COMPAT)(fn, __VA_ARGS__)), \
5232 : ())
5233 :
5234 : /**
5235 : * @brief Call @p fn on all node labels for a given `DT_DRV_COMPAT` instance
5236 : *
5237 : * Equivalent to DT_FOREACH_NODELABEL(DT_DRV_INST(inst), fn).
5238 : *
5239 : * @param inst instance number
5240 : * @param fn macro which will be passed each node label for the node
5241 : * with that instance number
5242 : */
5243 1 : #define DT_INST_FOREACH_NODELABEL(inst, fn) \
5244 : DT_FOREACH_NODELABEL(DT_DRV_INST(inst), fn)
5245 :
5246 : /**
5247 : * @brief Call @p fn on all node labels for a given `DT_DRV_COMPAT` instance
5248 : * with multiple arguments
5249 : *
5250 : * Equivalent to DT_FOREACH_NODELABEL_VARGS(DT_DRV_INST(inst), fn, ...).
5251 : *
5252 : * @param inst instance number
5253 : * @param fn macro which will be passed each node label for the node
5254 : * with that instance number
5255 : * @param ... additional arguments to pass to @p fn
5256 : */
5257 1 : #define DT_INST_FOREACH_NODELABEL_VARGS(inst, fn, ...) \
5258 : DT_FOREACH_NODELABEL_VARGS(DT_DRV_INST(inst), fn, __VA_ARGS__)
5259 :
5260 : /**
5261 : * @brief Invokes @p fn for each element of property @p prop for
5262 : * a `DT_DRV_COMPAT` instance.
5263 : *
5264 : * Equivalent to DT_FOREACH_PROP_ELEM(DT_DRV_INST(inst), prop, fn).
5265 : *
5266 : * @param inst instance number
5267 : * @param prop lowercase-and-underscores property name
5268 : * @param fn macro to invoke
5269 : */
5270 1 : #define DT_INST_FOREACH_PROP_ELEM(inst, prop, fn) \
5271 : DT_FOREACH_PROP_ELEM(DT_DRV_INST(inst), prop, fn)
5272 :
5273 : /**
5274 : * @brief Invokes @p fn for each element of property @p prop for
5275 : * a `DT_DRV_COMPAT` instance with a separator.
5276 : *
5277 : * Equivalent to DT_FOREACH_PROP_ELEM_SEP(DT_DRV_INST(inst), prop, fn, sep).
5278 : *
5279 : * @param inst instance number
5280 : * @param prop lowercase-and-underscores property name
5281 : * @param fn macro to invoke
5282 : * @param sep Separator (e.g. comma or semicolon). Must be in parentheses;
5283 : * this is required to enable providing a comma as separator.
5284 : */
5285 1 : #define DT_INST_FOREACH_PROP_ELEM_SEP(inst, prop, fn, sep) \
5286 : DT_FOREACH_PROP_ELEM_SEP(DT_DRV_INST(inst), prop, fn, sep)
5287 :
5288 : /**
5289 : * @brief Invokes @p fn for each element of property @p prop for
5290 : * a `DT_DRV_COMPAT` instance with multiple arguments.
5291 : *
5292 : * Equivalent to
5293 : * DT_FOREACH_PROP_ELEM_VARGS(DT_DRV_INST(inst), prop, fn, __VA_ARGS__)
5294 : *
5295 : * @param inst instance number
5296 : * @param prop lowercase-and-underscores property name
5297 : * @param fn macro to invoke
5298 : * @param ... variable number of arguments to pass to @p fn
5299 : *
5300 : * @see DT_INST_FOREACH_PROP_ELEM
5301 : */
5302 1 : #define DT_INST_FOREACH_PROP_ELEM_VARGS(inst, prop, fn, ...) \
5303 : DT_FOREACH_PROP_ELEM_VARGS(DT_DRV_INST(inst), prop, fn, __VA_ARGS__)
5304 :
5305 : /**
5306 : * @brief Invokes @p fn for each element of property @p prop for
5307 : * a `DT_DRV_COMPAT` instance with multiple arguments and a separator.
5308 : *
5309 : * Equivalent to
5310 : * DT_FOREACH_PROP_ELEM_SEP_VARGS(DT_DRV_INST(inst), prop, fn, sep,
5311 : * __VA_ARGS__)
5312 : *
5313 : * @param inst instance number
5314 : * @param prop lowercase-and-underscores property name
5315 : * @param fn macro to invoke
5316 : * @param sep Separator (e.g. comma or semicolon). Must be in parentheses;
5317 : * this is required to enable providing a comma as separator.
5318 : * @param ... variable number of arguments to pass to fn
5319 : *
5320 : * @see DT_INST_FOREACH_PROP_ELEM
5321 : */
5322 1 : #define DT_INST_FOREACH_PROP_ELEM_SEP_VARGS(inst, prop, fn, sep, ...) \
5323 : DT_FOREACH_PROP_ELEM_SEP_VARGS(DT_DRV_INST(inst), prop, fn, sep, \
5324 : __VA_ARGS__)
5325 :
5326 : /**
5327 : * @brief Does a DT_DRV_COMPAT instance have a property?
5328 : * @param inst instance number
5329 : * @param prop lowercase-and-underscores property name
5330 : * @return 1 if the instance has the property, 0 otherwise.
5331 : */
5332 1 : #define DT_INST_NODE_HAS_PROP(inst, prop) \
5333 : DT_NODE_HAS_PROP(DT_DRV_INST(inst), prop)
5334 :
5335 : /**
5336 : * @brief Does a DT_DRV_COMPAT instance have the compatible?
5337 : * @param inst instance number
5338 : * @param compat lowercase-and-underscores compatible, without quotes
5339 : * @return 1 if the instance matches the compatible, 0 otherwise.
5340 : */
5341 1 : #define DT_INST_NODE_HAS_COMPAT(inst, compat) \
5342 : DT_NODE_HAS_COMPAT(DT_DRV_INST(inst), compat)
5343 :
5344 : /**
5345 : * @brief Does a phandle array have a named cell specifier at an index
5346 : * for a `DT_DRV_COMPAT` instance?
5347 : * @param inst instance number
5348 : * @param pha lowercase-and-underscores property with type `phandle-array`
5349 : * @param idx index to check
5350 : * @param cell named cell value whose existence to check
5351 : * @return 1 if the named @p cell exists in the specifier at index @p idx,
5352 : * 0 otherwise.
5353 : */
5354 1 : #define DT_INST_PHA_HAS_CELL_AT_IDX(inst, pha, idx, cell) \
5355 : DT_PHA_HAS_CELL_AT_IDX(DT_DRV_INST(inst), pha, idx, cell)
5356 :
5357 : /**
5358 : * @brief Does a phandle array have a named cell specifier at index 0
5359 : * for a `DT_DRV_COMPAT` instance?
5360 : * @param inst instance number
5361 : * @param pha lowercase-and-underscores property with type `phandle-array`
5362 : * @param cell named cell value whose existence to check
5363 : * @return 1 if the named @p cell exists in the specifier at index 0,
5364 : * 0 otherwise.
5365 : */
5366 1 : #define DT_INST_PHA_HAS_CELL(inst, pha, cell) \
5367 : DT_INST_PHA_HAS_CELL_AT_IDX(inst, pha, 0, cell)
5368 :
5369 : /**
5370 : * @brief is index valid for interrupt property on a `DT_DRV_COMPAT` instance?
5371 : * @param inst instance number
5372 : * @param idx logical index into the interrupt specifier array
5373 : * @return 1 if the @p idx is valid for the interrupt property
5374 : * 0 otherwise.
5375 : */
5376 1 : #define DT_INST_IRQ_HAS_IDX(inst, idx) DT_IRQ_HAS_IDX(DT_DRV_INST(inst), idx)
5377 :
5378 : /**
5379 : * @brief Does a `DT_DRV_COMPAT` instance have an interrupt named cell specifier?
5380 : * @param inst instance number
5381 : * @param idx index to check
5382 : * @param cell named cell value whose existence to check
5383 : * @return 1 if the named @p cell exists in the interrupt specifier at index
5384 : * @p idx 0 otherwise.
5385 : */
5386 1 : #define DT_INST_IRQ_HAS_CELL_AT_IDX(inst, idx, cell) \
5387 : DT_IRQ_HAS_CELL_AT_IDX(DT_DRV_INST(inst), idx, cell)
5388 :
5389 : /**
5390 : * @brief Does a `DT_DRV_COMPAT` instance have an interrupt value?
5391 : * @param inst instance number
5392 : * @param cell named cell value whose existence to check
5393 : * @return 1 if the named @p cell exists in the interrupt specifier at index 0
5394 : * 0 otherwise.
5395 : */
5396 1 : #define DT_INST_IRQ_HAS_CELL(inst, cell) \
5397 : DT_INST_IRQ_HAS_CELL_AT_IDX(inst, 0, cell)
5398 :
5399 : /**
5400 : * @brief Does a `DT_DRV_COMPAT` instance have an interrupt value?
5401 : * @param inst instance number
5402 : * @param name lowercase-and-underscores interrupt specifier name
5403 : * @return 1 if @p name is a valid named specifier
5404 : */
5405 1 : #define DT_INST_IRQ_HAS_NAME(inst, name) \
5406 : DT_IRQ_HAS_NAME(DT_DRV_INST(inst), name)
5407 :
5408 : /**
5409 : * @}
5410 : */
5411 :
5412 : /** @cond INTERNAL_HIDDEN */
5413 :
5414 : /** @brief Helper for DT_ANY_INST_HAS_PROP_STATUS_OKAY
5415 : *
5416 : * This macro generates token "1," for instance of a device,
5417 : * identified by index @p idx, if instance has property @p prop.
5418 : *
5419 : * @param idx instance number
5420 : * @param prop property to check for
5421 : *
5422 : * @return Macro evaluates to `1,` if instance has the property,
5423 : * otherwise it evaluates to literal nothing.
5424 : */
5425 : #define DT_ANY_INST_HAS_PROP_STATUS_OKAY_(idx, prop) \
5426 : IF_ENABLED(DT_INST_NODE_HAS_PROP(idx, prop), (1,))
5427 :
5428 : /** @brief Helper for DT_ANY_INST_HAS_BOOL_STATUS_OKAY
5429 : *
5430 : * This macro generates token "1," for instance of a device,
5431 : * identified by index @p idx, if instance has boolean property
5432 : * @p prop with value 1.
5433 : *
5434 : * @param idx instance number
5435 : * @param prop property to check for
5436 : *
5437 : * @return Macro evaluates to `1,` if instance property value is 1,
5438 : * otherwise it evaluates to literal nothing.
5439 : */
5440 : #define DT_ANY_INST_HAS_BOOL_STATUS_OKAY_(idx, prop) \
5441 : IF_ENABLED(DT_INST_PROP(idx, prop), (1,))
5442 :
5443 : /** @brief Helper for DT_ALL_INST_HAS_PROP_STATUS_OKAY
5444 : *
5445 : * This macro generates token "1," for instance of a device,
5446 : * identified by index @p idx, if instance has no property @p prop.
5447 : *
5448 : * @param idx instance number
5449 : * @param prop property to check for
5450 : *
5451 : * @return Macro evaluates to `1,` if instance has the property,
5452 : * otherwise it evaluates to literal nothing.
5453 : */
5454 : #define DT_ALL_INST_HAS_PROP_STATUS_OKAY_(idx, prop) \
5455 : IF_DISABLED(DT_INST_NODE_HAS_PROP(idx, prop), (1,))
5456 :
5457 : /** @brief Helper for DT_ALL_INST_HAS_BOOL_STATUS_OKAY
5458 : *
5459 : * This macro generates token "1," for instance of a device,
5460 : * identified by index @p idx, if instance has no boolean property
5461 : * @p prop with value 1.
5462 : *
5463 : * @param idx instance number
5464 : * @param prop property to check for
5465 : *
5466 : * @return Macro evaluates to `1,` if instance property value is 0,
5467 : * otherwise it evaluates to literal nothing.
5468 : */
5469 : #define DT_ALL_INST_HAS_BOOL_STATUS_OKAY_(idx, prop) \
5470 : IF_DISABLED(DT_INST_PROP(idx, prop), (1,))
5471 :
5472 : #define DT_PATH_INTERNAL(...) \
5473 : UTIL_CAT(DT_ROOT, MACRO_MAP_CAT(DT_S_PREFIX, __VA_ARGS__))
5474 : /** @brief DT_PATH_INTERNAL() helper: prepends _S_ to a node name
5475 : * We don't want to expand 'name' recursively before expansion
5476 : * in this case. The MACRO_MAP_CAT above is giving us the exact
5477 : * tokens it wants prefixed with _S_.
5478 : */
5479 : #define DT_S_PREFIX(name) _S_##name
5480 :
5481 : /**
5482 : * @brief Concatenation helper, 2 arguments
5483 : *
5484 : * This and the following macros are used to paste things together
5485 : * with "##" *after* forcing expansion on each argument.
5486 : *
5487 : * We could try to use something like UTIL_CAT(), but the compiler
5488 : * error messages from the util macros can be extremely long when they
5489 : * are misused. This unfortunately happens often with devicetree.h,
5490 : * since its macro-based API is fiddly and can be hard to get right.
5491 : *
5492 : * Keeping things brutally simple here hopefully makes some errors
5493 : * easier to read.
5494 : */
5495 : #define DT_CAT(a1, a2) a1 ## a2
5496 : /** @brief Concatenation helper, 3 arguments */
5497 : #define DT_CAT3(a1, a2, a3) a1 ## a2 ## a3
5498 : /** @brief Concatenation helper, 4 arguments */
5499 : #define DT_CAT4(a1, a2, a3, a4) a1 ## a2 ## a3 ## a4
5500 : /** @brief Internal concatenation helper, 5 arguments */
5501 : #define DT_CAT5(a1, a2, a3, a4, a5) a1 ## a2 ## a3 ## a4 ## a5
5502 : /** @brief Concatenation helper, 6 arguments */
5503 : #define DT_CAT6(a1, a2, a3, a4, a5, a6) a1 ## a2 ## a3 ## a4 ## a5 ## a6
5504 : /** @brief concatenation helper, 7 arguments */
5505 : #define DT_CAT7(a1, a2, a3, a4, a5, a6, a7) \
5506 : a1 ## a2 ## a3 ## a4 ## a5 ## a6 ## a7
5507 : /** @brief concatenation helper, 8 arguments */
5508 : #define DT_CAT8(a1, a2, a3, a4, a5, a6, a7, a8) \
5509 : a1 ## a2 ## a3 ## a4 ## a5 ## a6 ## a7 ## a8
5510 : /*
5511 : * If you need to define a bigger DT_CATN(), do so here. Don't leave
5512 : * any "holes" of undefined macros, please.
5513 : */
5514 :
5515 : /** @brief Helper for node identifier macros to expand args */
5516 : #define DT_DASH(...) MACRO_MAP_CAT(DT_DASH_PREFIX, __VA_ARGS__)
5517 : /** @brief Helper for DT_DASH(): prepends _ to a name */
5518 : #define DT_DASH_PREFIX(name) _##name
5519 : /** @brief Helper for DT_NODE_HAS_STATUS */
5520 : #define DT_NODE_HAS_STATUS_INTERNAL(node_id, status) \
5521 : IS_ENABLED(DT_CAT3(node_id, _STATUS_, status))
5522 :
5523 : /** @brief Helper macro to OR multiple has property checks in a loop macro
5524 : * (for the specified device)
5525 : */
5526 : #define DT_COMPAT_NODE_HAS_PROP_AND_OR(inst, compat, prop) \
5527 : DT_NODE_HAS_PROP(DT_INST(inst, compat), prop) ||
5528 :
5529 : /**
5530 : * @def DT_U32_C
5531 : * @brief Macro to add 32bit unsigned postfix to the devicetree address constants
5532 : */
5533 : #if defined(_LINKER) || defined(_ASMLANGUAGE)
5534 : #define DT_U32_C(_v) (_v)
5535 : #else
5536 : #define DT_U32_C(_v) UINT32_C(_v)
5537 : #endif
5538 :
5539 : /**
5540 : * @def DT_U64_C
5541 : * @brief Macro to add ULL postfix to the devicetree address constants
5542 : */
5543 : #if defined(_LINKER) || defined(_ASMLANGUAGE)
5544 : #define DT_U64_C(_v) (_v)
5545 : #else
5546 : #define DT_U64_C(_v) UINT64_C(_v)
5547 : #endif
5548 :
5549 : /* Helpers for DT_NODELABEL_STRING_ARRAY. We define our own stringify
5550 : * in order to avoid adding a dependency on toolchain.h..
5551 : */
5552 : #define DT_NODELABEL_STRING_ARRAY_ENTRY_INTERNAL(nodelabel) DT_STRINGIFY_INTERNAL(nodelabel),
5553 : #define DT_STRINGIFY_INTERNAL(arg) DT_STRINGIFY_INTERNAL_HELPER(arg)
5554 : #define DT_STRINGIFY_INTERNAL_HELPER(arg) #arg
5555 :
5556 : /** @endcond */
5557 :
5558 : /* have these last so they have access to all previously defined macros */
5559 : #include <zephyr/devicetree/io-channels.h>
5560 : #include <zephyr/devicetree/clocks.h>
5561 : #include <zephyr/devicetree/gpio.h>
5562 : #include <zephyr/devicetree/spi.h>
5563 : #include <zephyr/devicetree/dma.h>
5564 : #include <zephyr/devicetree/pwms.h>
5565 : #include <zephyr/devicetree/fixed-partitions.h>
5566 : #include <zephyr/devicetree/ordinals.h>
5567 : #include <zephyr/devicetree/pinctrl.h>
5568 : #include <zephyr/devicetree/can.h>
5569 : #include <zephyr/devicetree/reset.h>
5570 : #include <zephyr/devicetree/mbox.h>
5571 : #include <zephyr/devicetree/port-endpoint.h>
5572 : #include <zephyr/devicetree/display.h>
5573 :
5574 : #endif /* ZEPHYR_INCLUDE_DEVICETREE_H_ */
|