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