Skip to content

Commit ce9bf10

Browse files
efra-mxcarlescufi
authored andcommitted
devicetree: introduce DT_ANY_COMPAT_HAS_PROP_STATUS_OKAY
Add a new macro, DT_ANY_COMPAT_HAS_PROP_STATUS_OKAY name, evaluates to 1 if any enabled instance of `compat` has the property or to zero if it hasn't. This macro can be useful in drivers for a family of devices. Signed-off-by: Efrain Calderon <[email protected]>
1 parent 8b914f6 commit ce9bf10

File tree

2 files changed

+99
-5
lines changed

2 files changed

+99
-5
lines changed

include/zephyr/devicetree.h

Lines changed: 77 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3201,7 +3201,7 @@
32013201
*/
32023202
#define DT_FOREACH_STATUS_OKAY(compat, fn) \
32033203
COND_CODE_1(DT_HAS_COMPAT_STATUS_OKAY(compat), \
3204-
(DT_CAT(DT_FOREACH_OKAY_, compat)(fn)), \
3204+
(UTIL_CAT(DT_FOREACH_OKAY_, compat)(fn)), \
32053205
())
32063206

32073207
/**
@@ -3254,6 +3254,25 @@
32543254
compat)(fn, __VA_ARGS__)), \
32553255
())
32563256

3257+
/**
3258+
* @brief Call @p fn on all nodes with compatible `compat`
3259+
* and status `okay` with multiple arguments
3260+
*
3261+
*
3262+
* @param compat lowercase-and-underscores devicetree compatible
3263+
* @param fn Macro to call for each enabled node. Must accept a
3264+
* devicetree compatible and instance number.
3265+
* @param ... Additional arguments to pass to @p fn
3266+
*
3267+
* @see DT_INST_FOREACH_STATUS_OKAY_VARGS
3268+
*/
3269+
#define DT_COMPAT_FOREACH_STATUS_OKAY_VARGS(compat, fn, ...) \
3270+
COND_CODE_1(DT_HAS_COMPAT_STATUS_OKAY(compat), \
3271+
(UTIL_CAT(DT_FOREACH_OKAY_INST_VARGS_, \
3272+
compat)(fn, compat, __VA_ARGS__)), \
3273+
())
3274+
3275+
32573276
/**
32583277
* @brief Invokes @p fn for each node label of a given node
32593278
*
@@ -4459,6 +4478,52 @@
44594478
#define DT_ANY_INST_HAS_PROP_STATUS_OKAY(prop) \
44604479
COND_CODE_1(IS_EMPTY(DT_ANY_INST_HAS_PROP_STATUS_OKAY_(prop)), (0), (1))
44614480

4481+
/**
4482+
* @brief Check if any device node with status `okay` has a given
4483+
* property.
4484+
*
4485+
* @param prop lowercase-and-underscores property name
4486+
*
4487+
* Example devicetree overlay:
4488+
*
4489+
* @code{.dts}
4490+
* &i2c0 {
4491+
* sensor0: sensor@0 {
4492+
* compatible = "vnd,some-sensor";
4493+
* status = "okay";
4494+
* reg = <0>;
4495+
* foo = <1>;
4496+
* bar = <2>;
4497+
* };
4498+
*
4499+
* sensor1: sensor@1 {
4500+
* compatible = "vnd,some-sensor";
4501+
* status = "okay";
4502+
* reg = <1>;
4503+
* foo = <2>;
4504+
* };
4505+
*
4506+
* sensor2: sensor@2 {
4507+
* compatible = "vnd,some-sensor";
4508+
* status = "disabled";
4509+
* reg = <2>;
4510+
* baz = <1>;
4511+
* };
4512+
* };
4513+
* @endcode
4514+
*
4515+
* Example usage:
4516+
*
4517+
* @code{.c}
4518+
*
4519+
* DT_ANY_COMPAT_HAS_PROP_STATUS_OKAY(vnd_some_sensor, foo) // 1
4520+
* DT_ANY_COMPAT_HAS_PROP_STATUS_OKAY(vnd_some_sensor, bar) // 1
4521+
* DT_ANY_COMPAT_HAS_PROP_STATUS_OKAY(vnd_some_sensor, baz) // 0
4522+
* @endcode
4523+
*/
4524+
#define DT_ANY_COMPAT_HAS_PROP_STATUS_OKAY(compat, prop) \
4525+
(DT_COMPAT_FOREACH_STATUS_OKAY_VARGS(compat, DT_COMPAT_NODE_HAS_PROP_AND_OR, prop) 0)
4526+
44624527
/**
44634528
* @brief Call @p fn on all nodes with compatible `DT_DRV_COMPAT`
44644529
* and status `okay`
@@ -4536,15 +4601,16 @@
45364601
*
45374602
*
45384603
* @param fn Macro to call for each enabled node. Must accept an
4539-
* instance number as its only parameter.
4604+
* instance number.
45404605
* @param ... variable number of arguments to pass to @p fn
45414606
*
45424607
* @see DT_INST_FOREACH_STATUS_OKAY
4608+
* @see DT_COMPAT_FOREACH_STATUS_OKAY_VARGS
45434609
*/
45444610
#define DT_INST_FOREACH_STATUS_OKAY_VARGS(fn, ...) \
4545-
COND_CODE_1(DT_HAS_COMPAT_STATUS_OKAY(DT_DRV_COMPAT), \
4546-
(UTIL_CAT(DT_FOREACH_OKAY_INST_VARGS_, \
4547-
DT_DRV_COMPAT)(fn, __VA_ARGS__)), \
4611+
COND_CODE_1(DT_HAS_COMPAT_STATUS_OKAY(DT_DRV_COMPAT), \
4612+
(UTIL_CAT(DT_FOREACH_OKAY_INST_VARGS_, \
4613+
DT_DRV_COMPAT)(fn, __VA_ARGS__)), \
45484614
())
45494615

45504616
/**
@@ -4806,6 +4872,12 @@
48064872
#define DT_NODE_HAS_STATUS_INTERNAL(node_id, status) \
48074873
IS_ENABLED(DT_CAT3(node_id, _STATUS_, status))
48084874

4875+
/** @brief Helper macro to OR multiple has property checks in a loop macro
4876+
* (for the specified device)
4877+
*/
4878+
#define DT_COMPAT_NODE_HAS_PROP_AND_OR(inst, compat, prop) \
4879+
DT_NODE_HAS_PROP(DT_INST(inst, compat), prop) ||
4880+
48094881
/**
48104882
* @def DT_U64_C
48114883
* @brief Macro to add ULL postfix to the devicetree address constants

tests/lib/devicetree/api/src/main.c

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,16 @@ ZTEST(devicetree_api, test_any_inst_prop)
211211
1, "");
212212
}
213213

214+
#undef DT_DRV_COMPAT
215+
ZTEST(devicetree_api, test_any_compat_inst_prop)
216+
{
217+
zassert_equal(DT_ANY_COMPAT_HAS_PROP_STATUS_OKAY(vnd_device_with_props, foo), 1, "");
218+
zassert_equal(DT_ANY_COMPAT_HAS_PROP_STATUS_OKAY(vnd_device_with_props, bar), 1, "");
219+
zassert_equal(DT_ANY_COMPAT_HAS_PROP_STATUS_OKAY(vnd_device_with_props, baz), 0, "");
220+
zassert_equal(DT_ANY_COMPAT_HAS_PROP_STATUS_OKAY(vnd_device_with_props, does_not_exist),
221+
0, "");
222+
}
223+
214224
ZTEST(devicetree_api, test_default_prop_access)
215225
{
216226
/*
@@ -1595,6 +1605,18 @@ ZTEST(devicetree_api, test_foreach_status_okay)
15951605
val = DT_FOREACH_STATUS_OKAY_VARGS(vnd_enum_holder, MY_FN, +) 3;
15961606
zassert_equal(val, 5, "");
15971607

1608+
#undef MY_FN
1609+
#define MY_FN(inst, compat, operator) DT_ENUM_IDX(DT_INST(inst, compat), val) operator
1610+
/* This should expand to something like:
1611+
*
1612+
* 0 + 2 + 3
1613+
*
1614+
* and order of expansion doesn't matter, since we're adding
1615+
* the values all up.
1616+
*/
1617+
val = DT_COMPAT_FOREACH_STATUS_OKAY_VARGS(vnd_enum_holder, MY_FN, +) 3;
1618+
zassert_equal(val, 5, "");
1619+
15981620
/*
15991621
* Make sure DT_INST_FOREACH_STATUS_OKAY can be called from functions
16001622
* using macros with side effects in the current scope.

0 commit comments

Comments
 (0)