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 <efrain.calderon.estrada@gmail.com>
This commit is contained in:
parent
8b914f6805
commit
ce9bf1071e
2 changed files with 99 additions and 5 deletions
|
@ -3201,7 +3201,7 @@
|
|||
*/
|
||||
#define DT_FOREACH_STATUS_OKAY(compat, fn) \
|
||||
COND_CODE_1(DT_HAS_COMPAT_STATUS_OKAY(compat), \
|
||||
(DT_CAT(DT_FOREACH_OKAY_, compat)(fn)), \
|
||||
(UTIL_CAT(DT_FOREACH_OKAY_, compat)(fn)), \
|
||||
())
|
||||
|
||||
/**
|
||||
|
@ -3254,6 +3254,25 @@
|
|||
compat)(fn, __VA_ARGS__)), \
|
||||
())
|
||||
|
||||
/**
|
||||
* @brief Call @p fn on all nodes with compatible `compat`
|
||||
* and status `okay` with multiple arguments
|
||||
*
|
||||
*
|
||||
* @param compat lowercase-and-underscores devicetree compatible
|
||||
* @param fn Macro to call for each enabled node. Must accept a
|
||||
* devicetree compatible and instance number.
|
||||
* @param ... Additional arguments to pass to @p fn
|
||||
*
|
||||
* @see DT_INST_FOREACH_STATUS_OKAY_VARGS
|
||||
*/
|
||||
#define DT_COMPAT_FOREACH_STATUS_OKAY_VARGS(compat, fn, ...) \
|
||||
COND_CODE_1(DT_HAS_COMPAT_STATUS_OKAY(compat), \
|
||||
(UTIL_CAT(DT_FOREACH_OKAY_INST_VARGS_, \
|
||||
compat)(fn, compat, __VA_ARGS__)), \
|
||||
())
|
||||
|
||||
|
||||
/**
|
||||
* @brief Invokes @p fn for each node label of a given node
|
||||
*
|
||||
|
@ -4459,6 +4478,52 @@
|
|||
#define DT_ANY_INST_HAS_PROP_STATUS_OKAY(prop) \
|
||||
COND_CODE_1(IS_EMPTY(DT_ANY_INST_HAS_PROP_STATUS_OKAY_(prop)), (0), (1))
|
||||
|
||||
/**
|
||||
* @brief Check if any device node with status `okay` has a given
|
||||
* property.
|
||||
*
|
||||
* @param prop lowercase-and-underscores property name
|
||||
*
|
||||
* Example devicetree overlay:
|
||||
*
|
||||
* @code{.dts}
|
||||
* &i2c0 {
|
||||
* sensor0: sensor@0 {
|
||||
* compatible = "vnd,some-sensor";
|
||||
* status = "okay";
|
||||
* reg = <0>;
|
||||
* foo = <1>;
|
||||
* bar = <2>;
|
||||
* };
|
||||
*
|
||||
* sensor1: sensor@1 {
|
||||
* compatible = "vnd,some-sensor";
|
||||
* status = "okay";
|
||||
* reg = <1>;
|
||||
* foo = <2>;
|
||||
* };
|
||||
*
|
||||
* sensor2: sensor@2 {
|
||||
* compatible = "vnd,some-sensor";
|
||||
* status = "disabled";
|
||||
* reg = <2>;
|
||||
* baz = <1>;
|
||||
* };
|
||||
* };
|
||||
* @endcode
|
||||
*
|
||||
* Example usage:
|
||||
*
|
||||
* @code{.c}
|
||||
*
|
||||
* DT_ANY_COMPAT_HAS_PROP_STATUS_OKAY(vnd_some_sensor, foo) // 1
|
||||
* DT_ANY_COMPAT_HAS_PROP_STATUS_OKAY(vnd_some_sensor, bar) // 1
|
||||
* DT_ANY_COMPAT_HAS_PROP_STATUS_OKAY(vnd_some_sensor, baz) // 0
|
||||
* @endcode
|
||||
*/
|
||||
#define DT_ANY_COMPAT_HAS_PROP_STATUS_OKAY(compat, prop) \
|
||||
(DT_COMPAT_FOREACH_STATUS_OKAY_VARGS(compat, DT_COMPAT_NODE_HAS_PROP_AND_OR, prop) 0)
|
||||
|
||||
/**
|
||||
* @brief Call @p fn on all nodes with compatible `DT_DRV_COMPAT`
|
||||
* and status `okay`
|
||||
|
@ -4536,10 +4601,11 @@
|
|||
*
|
||||
*
|
||||
* @param fn Macro to call for each enabled node. Must accept an
|
||||
* instance number as its only parameter.
|
||||
* instance number.
|
||||
* @param ... variable number of arguments to pass to @p fn
|
||||
*
|
||||
* @see DT_INST_FOREACH_STATUS_OKAY
|
||||
* @see DT_COMPAT_FOREACH_STATUS_OKAY_VARGS
|
||||
*/
|
||||
#define DT_INST_FOREACH_STATUS_OKAY_VARGS(fn, ...) \
|
||||
COND_CODE_1(DT_HAS_COMPAT_STATUS_OKAY(DT_DRV_COMPAT), \
|
||||
|
@ -4806,6 +4872,12 @@
|
|||
#define DT_NODE_HAS_STATUS_INTERNAL(node_id, status) \
|
||||
IS_ENABLED(DT_CAT3(node_id, _STATUS_, status))
|
||||
|
||||
/** @brief Helper macro to OR multiple has property checks in a loop macro
|
||||
* (for the specified device)
|
||||
*/
|
||||
#define DT_COMPAT_NODE_HAS_PROP_AND_OR(inst, compat, prop) \
|
||||
DT_NODE_HAS_PROP(DT_INST(inst, compat), prop) ||
|
||||
|
||||
/**
|
||||
* @def DT_U64_C
|
||||
* @brief Macro to add ULL postfix to the devicetree address constants
|
||||
|
|
|
@ -211,6 +211,16 @@ ZTEST(devicetree_api, test_any_inst_prop)
|
|||
1, "");
|
||||
}
|
||||
|
||||
#undef DT_DRV_COMPAT
|
||||
ZTEST(devicetree_api, test_any_compat_inst_prop)
|
||||
{
|
||||
zassert_equal(DT_ANY_COMPAT_HAS_PROP_STATUS_OKAY(vnd_device_with_props, foo), 1, "");
|
||||
zassert_equal(DT_ANY_COMPAT_HAS_PROP_STATUS_OKAY(vnd_device_with_props, bar), 1, "");
|
||||
zassert_equal(DT_ANY_COMPAT_HAS_PROP_STATUS_OKAY(vnd_device_with_props, baz), 0, "");
|
||||
zassert_equal(DT_ANY_COMPAT_HAS_PROP_STATUS_OKAY(vnd_device_with_props, does_not_exist),
|
||||
0, "");
|
||||
}
|
||||
|
||||
ZTEST(devicetree_api, test_default_prop_access)
|
||||
{
|
||||
/*
|
||||
|
@ -1595,6 +1605,18 @@ ZTEST(devicetree_api, test_foreach_status_okay)
|
|||
val = DT_FOREACH_STATUS_OKAY_VARGS(vnd_enum_holder, MY_FN, +) 3;
|
||||
zassert_equal(val, 5, "");
|
||||
|
||||
#undef MY_FN
|
||||
#define MY_FN(inst, compat, operator) DT_ENUM_IDX(DT_INST(inst, compat), val) operator
|
||||
/* This should expand to something like:
|
||||
*
|
||||
* 0 + 2 + 3
|
||||
*
|
||||
* and order of expansion doesn't matter, since we're adding
|
||||
* the values all up.
|
||||
*/
|
||||
val = DT_COMPAT_FOREACH_STATUS_OKAY_VARGS(vnd_enum_holder, MY_FN, +) 3;
|
||||
zassert_equal(val, 5, "");
|
||||
|
||||
/*
|
||||
* Make sure DT_INST_FOREACH_STATUS_OKAY can be called from functions
|
||||
* using macros with side effects in the current scope.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue