devicetree: Add vendor name helpers based on vendor prefixes

Adds vendor name helpers to access generated macros based on matching
entries in the vendor prefixes file.

Signed-off-by: Maureen Helm <maureen.helm@intel.com>
This commit is contained in:
Maureen Helm 2022-08-24 13:56:22 -05:00 committed by Marti Bolivar
parent 5b5aa6ebba
commit e1e16640b5
3 changed files with 122 additions and 0 deletions

View File

@ -1712,6 +1712,94 @@
* @}
*/
/**
* @defgroup devicetree-generic-vendor Vendor name helpers
* @ingroup devicetree
* @{
*/
/**
* @brief Get the vendor at index "idx" as a string literal
*
* The vendor is a string extracted from vendor prefixes if an entry exists
* that matches the node's compatible prefix. There may be as many as one
* vendor prefixes file per directory in DTS_ROOT.
*
* Example vendor-prefixes.txt:
*
* vnd A stand-in for a real vendor
* zephyr Zephyr-specific binding
*
* Example devicetree fragment:
*
* n1: node-1 {
* compatible = "vnd,model1", "gpio", "zephyr,model2";
* };
*
* Example usage:
*
* DT_NODE_VENDOR_BY_IDX(DT_NODELABEL(n1), 0) // "A stand-in for a real vendor"
* DT_NODE_VENDOR_BY_IDX(DT_NODELABEL(n1), 2) // "Zephyr-specific binding"
*
* Notice that the compatible at index 1 doesn't match any entries in the
* vendor prefix file and therefore index 1 is not a valid vendor index. Use
* DT_NODE_VENDOR_HAS_IDX(node_id, idx) to determine if an index is valid.
*
* @param node_id node identifier
* @param idx index of the vendor to return
* @return string literal of the idx-th vendor
*/
#define DT_NODE_VENDOR_BY_IDX(node_id, idx) \
DT_CAT(node_id, _COMPAT_VENDOR_IDX_##idx)
/**
* @brief Does a node's compatible property have a vendor at an index?
*
* If this returns 1, then DT_NODE_VENDOR_BY_IDX(node_id, idx) is valid. If it
* returns 0, it is an error to use DT_NODE_VENDOR_BY_IDX(node_id, idx) with
* index "idx".
*
* @param node_id node identifier
* @param idx index of the vendor to check
* @return 1 if "idx" is a valid vendor index,
* 0 otherwise.
*/
#define DT_NODE_VENDOR_HAS_IDX(node_id, idx) \
IS_ENABLED(DT_CAT4(node_id, _COMPAT_VENDOR_IDX_, idx, _EXISTS))
/**
* @brief Like DT_NODE_VENDOR_BY_IDX(), but with a fallback to default_value.
*
* If the value exists, this expands to DT_NODE_VENDOR_BY_IDX(node_id, idx).
* The default_value parameter is not expanded in this case.
*
* Otherwise, this expands to default_value.
*
* @param node_id node identifier
* @param idx index of the vendor to return
* @return string literal of the idx-th vendor
* @param default_value a fallback value to expand to
* @return string literal of the idx-th vendor or "default_value"
*/
#define DT_NODE_VENDOR_BY_IDX_OR(node_id, idx, default_value) \
COND_CODE_1(DT_NODE_VENDOR_HAS_IDX(node_id, idx), \
(DT_NODE_VENDOR_BY_IDX(node_id, idx)), (default_value))
/**
* @brief Get the node's (only) vendor as a string literal
*
* Equivalent to DT_NODE_VENDOR_BY_IDX_OR(node_id, 0, default_value).
*
* @param node_id node identifier
* @param default_value a fallback value to expand to
*/
#define DT_NODE_VENDOR_OR(node_id, default_value) \
DT_NODE_VENDOR_BY_IDX_OR(node_id, 0, default_value)
/**
* @}
*/
/**
* @defgroup devicetree-reg-prop reg property
* @ingroup devicetree

View File

@ -344,6 +344,11 @@
misc-prop = <1234>;
};
test_vendor: vendor {
compatible = "vnd,model1", "gpio", "zephyr,model2";
status = "okay";
};
test_intc: interrupt-controller@bbbbcccc {
compatible = "vnd,intc";
reg = <0xbbbbcccc 0x1000>;

View File

@ -36,6 +36,7 @@
#define TEST_IRQ DT_NODELABEL(test_irq)
#define TEST_TEMP DT_NODELABEL(test_temp_sensor)
#define TEST_REG DT_NODELABEL(test_reg)
#define TEST_VENDOR DT_NODELABEL(test_vendor)
#define TEST_ENUM_0 DT_NODELABEL(test_enum_0)
#define TEST_I2C DT_NODELABEL(test_i2c)
@ -398,6 +399,34 @@ ZTEST(devicetree_api, test_bus)
NULL);
}
#undef DT_DRV_COMPAT
#define DT_DRV_COMPAT vnd_vendor
#define VND_VENDOR "A stand-in for a real vendor which can be used in examples and tests"
#define ZEP_VENDOR "Zephyr-specific binding"
ZTEST(devicetree_api, test_vendor)
{
/* DT_NODE_VENDOR_HAS_IDX */
zassert_true(DT_NODE_VENDOR_HAS_IDX(TEST_VENDOR, 0), "");
zassert_false(DT_NODE_VENDOR_HAS_IDX(TEST_VENDOR, 1), "");
zassert_true(DT_NODE_VENDOR_HAS_IDX(TEST_VENDOR, 2), "");
zassert_false(DT_NODE_VENDOR_HAS_IDX(TEST_VENDOR, 3), "");
/* DT_NODE_VENDOR_BY_IDX */
zassert_true(!strcmp(DT_NODE_VENDOR_BY_IDX(TEST_VENDOR, 0), VND_VENDOR), "");
zassert_true(!strcmp(DT_NODE_VENDOR_BY_IDX(TEST_VENDOR, 2), ZEP_VENDOR), "");
/* DT_NODE_VENDOR_BY_IDX_OR */
zassert_true(!strcmp(DT_NODE_VENDOR_BY_IDX_OR(TEST_VENDOR, 0, NULL), VND_VENDOR), "");
zassert_is_null(DT_NODE_VENDOR_BY_IDX_OR(TEST_VENDOR, 1, NULL), "");
zassert_true(!strcmp(DT_NODE_VENDOR_BY_IDX_OR(TEST_VENDOR, 2, NULL), ZEP_VENDOR), "");
zassert_is_null(DT_NODE_VENDOR_BY_IDX_OR(TEST_VENDOR, 3, NULL), "");
/* DT_NODE_VENDOR_OR */
zassert_true(!strcmp(DT_NODE_VENDOR_OR(TEST_VENDOR, NULL), VND_VENDOR), "");
}
#undef DT_DRV_COMPAT
#define DT_DRV_COMPAT vnd_reg_holder
ZTEST(devicetree_api, test_reg)