diff --git a/doc/guides/dts/macros.bnf b/doc/guides/dts/macros.bnf index b66c71f3f54c6..1514e0b883e8d 100644 --- a/doc/guides/dts/macros.bnf +++ b/doc/guides/dts/macros.bnf @@ -19,6 +19,8 @@ dt-macro = node-macro / other-macro ; A macro about a property value node-macro = property-macro +; A macro about the pinctrl properties in a node. +node-macro =/ pinctrl-macro ; EXISTS macro: node exists in the devicetree node-macro =/ %s"DT_N" path-id %s"_EXISTS" ; Bus macros: the plain BUS is a way to access a node's bus controller. @@ -71,6 +73,50 @@ node-macro =/ %s"DT_N" path-id %s"_REQUIRES_ORDS" ; The dependency ordinals of a node supports (reverse direct dependencies). node-macro =/ %s"DT_N" path-id %s"_SUPPORTS_ORDS" +; -------------------------------------------------------------------- +; pinctrl-macro: a macro related to the pinctrl properties in a node +; +; These are a bit of a special case because they kind of form an array, +; but the array indexes correspond to pinctrl-DIGIT properties in a node. +; +; So they're related to a node, but not just one property within the node. +; +; The following examples assume something like this: +; +; foo { +; pinctrl-0 = <&bar>; +; pinctrl-1 = <&baz>; +; pinctrl-names = "default", "sleep"; +; }; + +; Total number of pinctrl-DIGIT properties in the node. May be zero. +; +; #define DT_N__PINCTRL_NUM 2 +pinctrl-macro = %s"DT_N" path-id %s"_PINCTRL_NUM" +; A given pinctrl-DIGIT property exists. +; +; #define DT_N__PINCTRL_IDX_0_EXISTS 1 +; #define DT_N__PINCTRL_IDX_1_EXISTS 1 +pinctrl-macro =/ %s"DT_N" path-id %s"_PINCTRL_IDX_" DIGIT %s"_EXISTS" +; A given pinctrl property name exists. +; +; #define DT_N__PINCTRL_NAME_default_EXISTS 1 +; #define DT_N__PINCTRL_NAME_sleep_EXISTS 1 +pinctrl-macro =/ %s"DT_N" path-id %s"_PINCTRL_NAME_" dt-name %s"_EXISTS" +; The corresponding index number of a named pinctrl property. +; +; #define DT_N__PINCTRL_NAME_default_IDX 0 +; #define DT_N__PINCTRL_NAME_sleep_IDX 1 +pinctrl-macro =/ %s"DT_N" path-id %s"_PINCTRL_NAME_" dt-name %s"_IDX" +; The node identifier for the phandle in a named pinctrl property. +; +; #define DT_N__PINCTRL_NAME_default_IDX_0_PH +; +; There's no need for a separate macro for access by index: that's +; covered by property-macro. We only need this because the map from +; names to properties is implicit in the structure of the DT. +pinctrl-macro =/ %s"DT_N" path-id %s"_PINCTRL_NAME_" dt-name %s"_IDX_" DIGIT %s"_PH" + ; -------------------------------------------------------------------- ; property-macro: a macro related to a node property ; diff --git a/doc/reference/devicetree/api.rst b/doc/reference/devicetree/api.rst index 593f0be273452..9f4de8778699f 100644 --- a/doc/reference/devicetree/api.rst +++ b/doc/reference/devicetree/api.rst @@ -254,6 +254,34 @@ channels (e.g. ADC or DAC channels) for conversion. .. doxygengroup:: devicetree-io-channels +Pinctrl (pin control) +===================== + +These are used to access pin control properties by name or index. + +Devicetree nodes may have properties which specify pin control (sometimes known +as pin mux) settings. These are expressed using ``pinctrl-`` properties +within the node, where the ```` values are contiguous integers starting +from 0. These may also be named using the ``pinctrl-names`` property. + +Here is an example: + +.. code-block:: DTS + + node { + ... + pinctrl-0 = <&foo &bar ...>; + pinctrl-1 = <&baz ...>; + pinctrl-names = "default", "sleep"; + }; + +Above, ``pinctrl-0`` has name ``"default"``, and ``pinctrl-1`` has name +``"sleep"``. The ``pinctrl-`` property values contain phandles. The +``&foo``, ``&bar``, etc. phandles within the properties point to nodes whose +contents vary by platform, and which describe a pin configuration for the node. + +.. doxygengroup:: devicetree-pinctrl + PWM === diff --git a/drivers/adc/adc_npcx.c b/drivers/adc/adc_npcx.c index 51197007fe3c1..afc15ef8f78ce 100644 --- a/drivers/adc/adc_npcx.c +++ b/drivers/adc/adc_npcx.c @@ -25,7 +25,7 @@ LOG_MODULE_REGISTER(adc_npcx, CONFIG_ADC_LOG_LEVEL); #define ADC_REGULAR_MEAST_VAL 0x0001 /* ADC channel number */ -#define NPCX_ADC_CH_COUNT DT_INST_PROP_LEN(0, pinctrl_0) +#define NPCX_ADC_CH_COUNT DT_INST_NUM_PINCTRLS_BY_IDX(0, 0) /* ADC targeted operating frequency (2MHz) */ #define NPCX_ADC_CLK 2000000 diff --git a/drivers/i2c/i2c_ite_it8xxx2.c b/drivers/i2c/i2c_ite_it8xxx2.c index 44a6d5536ab86..5d3acc026cb50 100644 --- a/drivers/i2c/i2c_ite_it8xxx2.c +++ b/drivers/i2c/i2c_ite_it8xxx2.c @@ -1019,8 +1019,9 @@ static const struct i2c_driver_api i2c_it8xxx2_driver_api = { #define I2C_ITE_IT8XXX2_INIT(idx) \ static void i2c_it8xxx2_config_func_##idx(void); \ - static const struct i2c_alts_cfg i2c_alts_##idx[DT_INST_PROP_LEN \ - (idx, pinctrl_0)] = IT8XXX2_DT_ALT_ITEMS_LIST(idx); \ + static const struct i2c_alts_cfg \ + i2c_alts_##idx[DT_INST_NUM_PINCTRLS_BY_IDX(idx, 0)] = \ + IT8XXX2_DT_ALT_ITEMS_LIST(idx); \ \ static const struct i2c_it8xxx2_config i2c_it8xxx2_cfg_##idx = { \ .base = (uint8_t *)(DT_INST_REG_ADDR(idx)), \ diff --git a/drivers/pwm/pwm_ite_it8xxx2.c b/drivers/pwm/pwm_ite_it8xxx2.c index c8ded9d605e55..3cb600699f9a8 100644 --- a/drivers/pwm/pwm_ite_it8xxx2.c +++ b/drivers/pwm/pwm_ite_it8xxx2.c @@ -51,10 +51,8 @@ struct pwm_it8xxx2_cfg { #define DRV_REG(dev) (struct pwm_it8xxx2_regs *)(DRV_CONFIG(dev)->base) #define DEV_PINMUX(inst) \ DEVICE_DT_GET(DT_PHANDLE_BY_IDX(DT_NODELABEL(pinctrl_pwm##inst), pinctrls, 0)) -#define DEV_PIN(inst) \ - DT_PHA(DT_PHANDLE_BY_IDX(DT_DRV_INST(inst), pinctrl_0, 0), pinctrls, pin) -#define DEV_ALT_FUN(inst) \ - DT_PHA(DT_PHANDLE_BY_IDX(DT_DRV_INST(inst), pinctrl_0, 0), pinctrls, alt_func) +#define DEV_PIN(inst) DT_PHA(DT_INST_PINCTRL_0(inst, 0), pinctrls, pin) +#define DEV_ALT_FUN(inst) DT_PHA(DT_INST_PINCTRL_0(inst, 0), pinctrls, alt_func) static void pwm_enable(const struct device *dev, int enabled) { diff --git a/dts/bindings/test/vnd,temperature-sensor.yaml b/dts/bindings/test/vnd,adc-temp-sensor.yaml similarity index 79% rename from dts/bindings/test/vnd,temperature-sensor.yaml rename to dts/bindings/test/vnd,adc-temp-sensor.yaml index c665b4fd54110..32ca83b429692 100644 --- a/dts/bindings/test/vnd,temperature-sensor.yaml +++ b/dts/bindings/test/vnd,adc-temp-sensor.yaml @@ -21,3 +21,12 @@ properties: clocks: required: true + + pinctrl-0: + type: phandles + + pinctrl-1: + type: phandles + + pinctrl-2: + type: phandles diff --git a/dts/bindings/test/vnd,pinctrl.yaml b/dts/bindings/test/vnd,pinctrl.yaml new file mode 100644 index 0000000000000..59169925a62e9 --- /dev/null +++ b/dts/bindings/test/vnd,pinctrl.yaml @@ -0,0 +1,8 @@ +# Copyright (c) 2021 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +description: Test pin controller node + +compatible: "vnd,pinctrl" + +include: pincfg-node.yaml diff --git a/include/devicetree.h b/include/devicetree.h index 35a25c647cf0a..38e169053ceb3 100644 --- a/include/devicetree.h +++ b/include/devicetree.h @@ -2673,5 +2673,6 @@ #include #include #include +#include #endif /* DEVICETREE_H */ diff --git a/include/devicetree/pinctrl.h b/include/devicetree/pinctrl.h new file mode 100644 index 0000000000000..a5fde6a8fc162 --- /dev/null +++ b/include/devicetree/pinctrl.h @@ -0,0 +1,455 @@ +/* + * Copyright (c) 2021 Nordic Semiconductor ASA + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_DEVICETREE_PINCTRL_H_ +#define ZEPHYR_INCLUDE_DEVICETREE_PINCTRL_H_ + +/** + * @file + * @brief Devicetree pin control helpers + */ + +/** + * @defgroup devicetree-pinctrl Pin control + * @ingroup devicetree + * @{ + */ + +/** + * @brief Get a node identifier for a phandle in a pinctrl property by index + * + * Example devicetree fragment: + * + * n: node { + * pinctrl-0 = <&foo &bar>; + * pinctrl-1 = <&baz &blub>; + * } + * + * Example usage: + * + * DT_PINCTRL_BY_IDX(DT_NODELABEL(n), 0, 1) // DT_NODELABEL(bar) + * DT_PINCTRL_BY_IDX(DT_NODELABEL(n), 1, 0) // DT_NODELABEL(baz) + * + * @param node_id node with a pinctrl-'pc_idx' property + * @param pc_idx index of the pinctrl property itself + * @param idx index into the value of the pinctrl property + * @return node identifier for the phandle at index 'idx' in 'pinctrl-'pc_idx'' + */ +#define DT_PINCTRL_BY_IDX(node_id, pc_idx, idx) \ + DT_CAT6(node_id, _P_pinctrl_, pc_idx, _IDX_, idx, _PH) + +/** + * @brief Get a node identifier from a pinctrl-0 property + * + * This is equivalent to: + * + * DT_PINCTRL_BY_IDX(node_id, 0, idx) + * + * It is provided for convenience since pinctrl-0 is commonly used. + * + * @param node_id node with a pinctrl-0 property + * @param idx index into the pinctrl-0 property + * @return node identifier for the phandle at index idx in the pinctrl-0 + * property of that node + */ +#define DT_PINCTRL_0(node_id, idx) DT_PINCTRL_BY_IDX(node_id, 0, idx) + +/** + * @brief Get a node identifier for a phandle inside a pinctrl node by name + * + * Example devicetree fragment: + * + * n: node { + * pinctrl-0 = <&foo &bar>; + * pinctrl-1 = <&baz &blub>; + * pinctrl-names = "default", "sleep"; + * }; + * + * Example usage: + * + * DT_PINCTRL_BY_NAME(DT_NODELABEL(n), default, 1) // DT_NODELABEL(bar) + * DT_PINCTRL_BY_NAME(DT_NODELABEL(n), sleep, 0) // DT_NODELABEL(baz) + * + * @param node_id node with a named pinctrl property + * @param name lowercase-and-underscores pinctrl property name + * @param idx index into the value of the named pinctrl property + * @return node identifier for the phandle at that index in the pinctrl + * property + */ +#define DT_PINCTRL_BY_NAME(node_id, name, idx) \ + DT_CAT6(node_id, _PINCTRL_NAME_, name, _IDX_, idx, _PH) + +/** + * @brief Convert a pinctrl name to its corresponding index + * + * Example devicetree fragment: + * + * n: node { + * pinctrl-0 = <&foo &bar>; + * pinctrl-1 = <&baz &blub>; + * pinctrl-names = "default", "sleep"; + * }; + * + * Example usage: + * + * DT_PINCTRL_NAME_TO_IDX(DT_NODELABEL(n), default) // 0 + * DT_PINCTRL_NAME_TO_IDX(DT_NODELABEL(n), sleep) // 1 + * + * @param node_id node identifier with a named pinctrl property + * @param name lowercase-and-underscores name name of the pinctrl whose index to get + * @return integer literal for the index of the pinctrl property with that name + */ +#define DT_PINCTRL_NAME_TO_IDX(node_id, name) \ + DT_CAT4(node_id, _PINCTRL_NAME_, name, _IDX) + +/** + * @brief Convert a pinctrl property index to its name as a token + * + * This allows you to get a pinctrl property's name, and "remove the + * quotes" from it. + * + * DT_PINCTRL_IDX_TO_NAME_TOKEN() can only be used if the node has a + * pinctrl-'pc_idx' property and a pinctrl-names property element for + * that index. It is an error to use it in other circumstances. + * + * Example devicetree fragment: + * + * n: node { + * pinctrl-0 = <...>; + * pinctrl-1 = <...>; + * pinctrl-names = "default", "f.o.o2"; + * }; + * + * Example usage: + * + * DT_PINCTRL_IDX_TO_NAME_TOKEN(DT_NODELABEL(n), 0) // default + * DT_PINCTRL_IDX_TO_NAME_TOKEN(DT_NODELABEL(n), 1) // f_o_o2 + * + * The same caveats and restrictions that apply to DT_STRING_TOKEN()'s + * return value also apply here. + * + * @param node_id node identifier + * @param pc_idx index of a pinctrl property in that node + * @return name of the pinctrl property, as a token, without any quotes + * and with non-alphanumeric characters converted to underscores + */ +#define DT_PINCTRL_IDX_TO_NAME_TOKEN(node_id, pc_idx) \ + DT_CAT4(node_id, _PINCTRL_IDX_, pc_idx, _TOKEN) + +/** + * @brief Like DT_PINCTRL_IDX_TO_NAME_TOKEN(), but with an uppercased result + * + * This does the a similar conversion as + * DT_PINCTRL_IDX_TO_NAME_TOKEN(node_id, pc_idx). The only difference + * is that alphabetical characters in the result are uppercased. + * + * Example devicetree fragment: + * + * n: node { + * pinctrl-0 = <...>; + * pinctrl-1 = <...>; + * pinctrl-names = "default", "f.o.o2"; + * }; + * + * Example usage: + * + * DT_PINCTRL_IDX_TO_NAME_TOKEN(DT_NODELABEL(n), 0) // DEFAULT + * DT_PINCTRL_IDX_TO_NAME_TOKEN(DT_NODELABEL(n), 1) // F_O_O2 + * + * The same caveats and restrictions that apply to + * DT_STRING_UPPER_TOKEN()'s return value also apply here. + */ +#define DT_PINCTRL_IDX_TO_NAME_UPPER_TOKEN(node_id, pc_idx) \ + DT_CAT4(node_id, _PINCTRL_IDX_, pc_idx, _UPPER_TOKEN) + +/** + * @brief Get the number of phandles in a pinctrl property + * + * Example devicetree fragment: + * + * n1: node-1 { + * pinctrl-0 = <&foo &bar>; + * }; + * + * n2: node-2 { + * pinctrl-0 = <&baz>; + * }; + * + * Example usage: + * + * DT_NUM_PINCTRLS_BY_IDX(DT_NODELABEL(n1), 0) // 2 + * DT_NUM_PINCTRLS_BY_IDX(DT_NODELABEL(n2), 0) // 1 + * + * @param node_id node identifier with a pinctrl property + * @param pc_idx index of the pinctrl property itself + * @return number of phandles in the property with that index + */ +#define DT_NUM_PINCTRLS_BY_IDX(node_id, pc_idx) \ + DT_CAT4(node_id, _P_pinctrl_, pc_idx, _LEN) + +/** + * @brief Like DT_NUM_PINCTRLS_BY_IDX(), but by name instead + * + * Example devicetree fragment: + * + * n: node { + * pinctrl-0 = <&foo &bar>; + * pinctrl-1 = <&baz> + * pinctrl-names = "default", "sleep"; + * }; + * + * Example usage: + * + * DT_NUM_PINCTRLS_BY_NAME(DT_NODELABEL(n), default) // 2 + * DT_NUM_PINCTRLS_BY_NAME(DT_NODELABEL(n), sleep) // 1 + * + * @param node_id node identifier with a pinctrl property + * @param name lowercase-and-underscores name name of the pinctrl property + * @return number of phandles in the property with that name + */ +#define DT_NUM_PINCTRLS_BY_NAME(node_id, name) \ + DT_NUM_PINCTRLS_BY_IDX(node_id, DT_PINCTRL_NAME_TO_IDX(node_id, name)) + +/** + * @brief Get the number of pinctrl properties in a node + * + * This expands to 0 if there are no pinctrl-i properties. + * Otherwise, it expands to the number of such properties. + * + * Example devicetree fragment: + * + * n1: node-1 { + * pinctrl-0 = <...>; + * pinctrl-1 = <...>; + * }; + * + * n2: node-2 { + * }; + * + * Example usage: + * + * DT_NUM_PINCTRL_STATES(DT_NODELABEL(n1)) // 2 + * DT_NUM_PINCTRL_STATES(DT_NODELABEL(n2)) // 0 + * + * @param node_id node identifier; may or may not have any pinctrl properties + * @return number of pinctrl properties in the node + */ +#define DT_NUM_PINCTRL_STATES(node_id) DT_CAT(node_id, _PINCTRL_NUM) + +/** + * @brief Test if a node has a pinctrl property with an index + * + * This expands to 1 if the pinctrl-'idx' property exists. + * Otherwise, it expands to 0. + * + * Example devicetree fragment: + * + * n1: node-1 { + * pinctrl-0 = <...>; + * pinctrl-1 = <...>; + * }; + * + * n2: node-2 { + * }; + * + * Example usage: + * + * DT_PINCTRL_HAS_IDX(DT_NODELABEL(n1), 0) // 1 + * DT_PINCTRL_HAS_IDX(DT_NODELABEL(n1), 1) // 1 + * DT_PINCTRL_HAS_IDX(DT_NODELABEL(n1), 2) // 0 + * DT_PINCTRL_HAS_IDX(DT_NODELABEL(n2), 0) // 0 + * + * @param node_id node identifier; may or may not have any pinctrl properties + * @param pc_idx index of a pinctrl property whose existence to check + * @return 1 if the property exists, 0 otherwise + */ +#define DT_PINCTRL_HAS_IDX(node_id, pc_idx) \ + IS_ENABLED(DT_CAT4(node_id, _PINCTRL_IDX_, pc_idx, _EXISTS)) + +/** + * @brief Test if a node has a pinctrl property with a name + * + * This expands to 1 if the named pinctrl property exists. + * Otherwise, it expands to 0. + * + * Example devicetree fragment: + * + * n1: node-1 { + * pinctrl-0 = <...>; + * pinctrl-names = "default"; + * }; + * + * n2: node-2 { + * }; + * + * Example usage: + * + * DT_PINCTRL_HAS_NAME(DT_NODELABEL(n1), default) // 1 + * DT_PINCTRL_HAS_NAME(DT_NODELABEL(n1), sleep) // 0 + * DT_PINCTRL_HAS_NAME(DT_NODELABEL(n2), default) // 0 + * + * @param node_id node identifier; may or may not have any pinctrl properties + * @param name lowercase-and-underscores pinctrl property name to check + * @return 1 if the property exists, 0 otherwise + */ +#define DT_PINCTRL_HAS_NAME(node_id, name) \ + IS_ENABLED(DT_CAT4(node_id, _PINCTRL_NAME_, name, _EXISTS)) + +/** + * @brief Get a node identifier for a phandle in a pinctrl property by index + * for a DT_DRV_COMPAT instance + * + * This is equivalent to DT_PINCTRL_BY_IDX(DT_DRV_INST(inst), pc_idx, idx). + * + * @param inst instance number + * @param pc_idx index of the pinctrl property itself + * @param idx index into the value of the pinctrl property + * @return node identifier for the phandle at index 'idx' in 'pinctrl-'pc_idx'' + */ +#define DT_INST_PINCTRL_BY_IDX(inst, pc_idx, idx) \ + DT_PINCTRL_BY_IDX(DT_DRV_INST(inst), pc_idx, idx) + +/** + * @brief Get a node identifier from a pinctrl-0 property for a + * DT_DRV_COMPAT instance + * + * This is equivalent to: + * + * DT_PINCTRL_BY_IDX(DT_DRV_INST(inst), 0, idx) + * + * It is provided for convenience since pinctrl-0 is commonly used. + * + * @param inst instance number + * @param idx index into the pinctrl-0 property + * @return node identifier for the phandle at index idx in the pinctrl-0 + * property of that instance + */ +#define DT_INST_PINCTRL_0(inst, idx) \ + DT_PINCTRL_BY_IDX(DT_DRV_INST(inst), 0, idx) + +/** + * @brief Get a node identifier for a phandle inside a pinctrl node + * for a DT_DRV_COMPAT instance + * + * This is equivalent to DT_PINCTRL_BY_NAME(DT_DRV_INST(inst), name, idx). + * + * @param inst instance number + * @param name lowercase-and-underscores pinctrl property name + * @param idx index into the value of the named pinctrl property + * @return node identifier for the phandle at that index in the pinctrl + * property + */ +#define DT_INST_PINCTRL_BY_NAME(inst, name, idx) \ + DT_PINCTRL_BY_NAME(DT_DRV_INST(inst), name, idx) + +/** + * @brief Convert a pinctrl name to its corresponding index + * for a DT_DRV_COMPAT instance + * + * This is equivalent to DT_PINCTRL_NAME_TO_IDX(DT_DRV_INST(inst), + * name). + * + * @param inst instance number + * @param name lowercase-and-underscores name of the pinctrl whose index to get + * @return integer literal for the index of the pinctrl property with that name + */ +#define DT_INST_PINCTRL_NAME_TO_IDX(inst, name) \ + DT_PINCTRL_NAME_TO_IDX(DT_DRV_INST(inst), name) + +/** + * @brief Convert a pinctrl index to its name as an uppercased token + * + * This is equivalent to + * DT_PINCTRL_IDX_TO_NAME_TOKEN(DT_DRV_INST(inst), pc_idx). + * + * @param inst instance number + * @param pc_idx index of the pinctrl property itself + * @return name of the pin control property as a token + */ +#define DT_INST_PINCTRL_IDX_TO_NAME_TOKEN(inst, pc_idx) \ + DT_PINCTRL_IDX_TO_NAME_TOKEN(DT_DRV_INST(inst), pc_idx) + +/** + * @brief Convert a pinctrl index to its name as an uppercased token + * + * This is equivalent to + * DT_PINCTRL_IDX_TO_NAME_UPPER_TOKEN(DT_DRV_INST(inst), idx). + * + * @param inst instance number + * @param pc_idx index of the pinctrl property itself + * @return name of the pin control property as an uppercase token + */ +#define DT_INST_PINCTRL_IDX_TO_NAME_UPPER_TOKEN(inst, pc_idx) \ + DT_PINCTRL_IDX_TO_NAME_UPPER_TOKEN(DT_DRV_INST(inst), pc_idx) + +/** + * @brief Get the number of phandles in a pinctrl property + * for a DT_DRV_COMPAT instance + * + * This is equivalent to DT_NUM_PINCTRLS_BY_IDX(DT_DRV_INST(inst), + * pc_idx). + * + * @param inst instance number + * @param pc_idx index of the pinctrl property itself + * @return number of phandles in the property with that index + */ +#define DT_INST_NUM_PINCTRLS_BY_IDX(inst, pc_idx) \ + DT_NUM_PINCTRLS_BY_IDX(DT_DRV_INST(inst), pc_idx) + +/** + * @brief Like DT_INST_NUM_PINCTRLS_BY_IDX(), but by name instead + * + * This is equivalent to DT_NUM_PINCTRLS_BY_NAME(DT_DRV_INST(inst), + * name). + * + * @param inst instance number + * @param name lowercase-and-underscores name of the pinctrl property + * @return number of phandles in the property with that name + */ +#define DT_INST_NUM_PINCTRLS_BY_NAME(inst, name) \ + DT_NUM_PINCTRLS_BY_NAME(DT_DRV_INST(inst), name) + +/** + * @brief Get the number of pinctrl properties in a DT_DRV_COMPAT instance + * + * This is equivalent to DT_NUM_PINCTRL_STATES(DT_DRV_INST(inst)). + * + * @param inst instance number + * @return number of pinctrl properties in the instance + */ +#define DT_INST_NUM_PINCTRL_STATES(inst) \ + DT_NUM_PINCTRL_STATES(DT_DRV_INST(inst)) + +/** + * @brief Test if a DT_DRV_COMPAT instance has a pinctrl property + * with an index + * + * This is equivalent to DT_PINCTRL_HAS_IDX(DT_DRV_INST(inst), pc_idx). + * + * @param inst instance number + * @param pc_idx index of a pinctrl property whose existence to check + * @return 1 if the property exists, 0 otherwise + */ +#define DT_INST_PINCTRL_HAS_IDX(inst, pc_idx) \ + DT_PINCTRL_HAS_IDX(DT_DRV_INST(inst), pc_idx) + +/** + * @brief Test if a DT_DRV_COMPAT instance has a pinctrl property with a name + * + * This is equivalent to DT_PINCTRL_HAS_NAME(DT_DRV_INST(inst), name). + * + * @param inst instance number + * @param name lowercase-and-underscores pinctrl property name to check + * @return 1 if the property exists, 0 otherwise + */ +#define DT_INST_PINCTRL_HAS_NAME(inst, name) \ + DT_PINCTRL_HAS_NAME(DT_DRV_INST(inst), name) + + +/** + * @} + */ + +#endif /* ZEPHYR_INCLUDE_DEVICETREE_PINCTRL_H_ */ diff --git a/include/dt-bindings/pinctrl/b91-pinctrl.h b/include/dt-bindings/pinctrl/b91-pinctrl.h index 8878b953acd36..27f86a1a8d6bc 100644 --- a/include/dt-bindings/pinctrl/b91-pinctrl.h +++ b/include/dt-bindings/pinctrl/b91-pinctrl.h @@ -39,15 +39,15 @@ #define B91_PINMUX_GET_PIN(pinmux) (pinmux & 0xFFFF) #define B91_PINMUX_DT_INST_GET_ELEM(idx, x, inst) \ - DT_PROP_BY_PHANDLE_IDX(DT_DRV_INST(inst), pinctrl_##x, idx, pinmux), - -#define B91_PINMUX_DT_INST_GET_ARRAY(inst, x) \ - { COND_CODE_1(DT_INST_NODE_HAS_PROP(inst, pinctrl_##x), \ - (UTIL_LISTIFY(DT_INST_PROP_LEN(inst, pinctrl_##x), \ - B91_PINMUX_DT_INST_GET_ELEM, \ - x, \ - inst)), \ - ()) \ + DT_PROP(DT_INST_PINCTRL_BY_IDX(inst, x, idx), pinmux), + +#define B91_PINMUX_DT_INST_GET_ARRAY(inst, x) \ + { COND_CODE_1(DT_INST_PINCTRL_HAS_IDX(inst, x), \ + (UTIL_LISTIFY(DT_INST_NUM_PINCTRLS_BY_IDX(inst, x), \ + B91_PINMUX_DT_INST_GET_ELEM, \ + x, \ + inst)), \ + ()) \ } #endif /* ZEPHYR_B91_PINCTRL_COMMON_H_ */ diff --git a/scripts/dts/gen_defines.py b/scripts/dts/gen_defines.py index b30fe80e10fba..65e6d4a1bc71f 100755 --- a/scripts/dts/gen_defines.py +++ b/scripts/dts/gen_defines.py @@ -352,20 +352,17 @@ def write_special_props(node): # data cannot otherwise be obtained from write_vanilla_props() # results - global flash_area_num - - out_comment("Special property macros:") - # Macros that are special to the devicetree specification + out_comment("Macros for properties that are special in the specification:") write_regs(node) write_interrupts(node) write_compatibles(node) write_status(node) - if node.parent and "fixed-partitions" in node.parent.compats: - macro = f"{node.z_path_id}_PARTITION_ID" - out_dt_define(macro, flash_area_num) - flash_area_num += 1 + # Macros that are special to bindings inherited from Linux, which + # we can't capture with the current bindings language. + write_pinctrls(node) + write_fixed_partitions(node) def write_regs(node): # reg property: edtlib knows the right #address-cells and @@ -493,7 +490,7 @@ def write_child_functions(node): node.children.values())) def write_child_functions_status_okay(node): - # Writes macro that are helpers that will call a macro/function + # Writes macros that are helpers that will call a macro/function # for each child node with status "okay". functions = '' @@ -513,6 +510,48 @@ def write_status(node): out_dt_define(f"{node.z_path_id}_STATUS_{str2ident(node.status)}", 1) +def write_pinctrls(node): + # Write special macros for pinctrl- and pinctrl-names properties. + + out_comment("Pin control (pinctrl-, pinctrl-names) properties:") + + out_dt_define(f"{node.z_path_id}_PINCTRL_NUM", len(node.pinctrls)) + + if not node.pinctrls: + return + + for pc_idx, pinctrl in enumerate(node.pinctrls): + out_dt_define(f"{node.z_path_id}_PINCTRL_IDX_{pc_idx}_EXISTS", 1) + + if not pinctrl.name: + continue + + name = pinctrl.name_as_token + + # Below we rely on the fact that edtlib ensures the + # pinctrl- properties are contiguous, start from 0, + # and contain only phandles. + out_dt_define(f"{node.z_path_id}_PINCTRL_IDX_{pc_idx}_TOKEN", name) + out_dt_define(f"{node.z_path_id}_PINCTRL_IDX_{pc_idx}_UPPER_TOKEN", name.upper()) + out_dt_define(f"{node.z_path_id}_PINCTRL_NAME_{name}_EXISTS", 1) + out_dt_define(f"{node.z_path_id}_PINCTRL_NAME_{name}_IDX", pc_idx) + for idx, ph in enumerate(pinctrl.conf_nodes): + out_dt_define(f"{node.z_path_id}_PINCTRL_NAME_{name}_IDX_{idx}_PH", + f"DT_{ph.z_path_id}") + + +def write_fixed_partitions(node): + # Macros for child nodes of each fixed-partitions node. + + if not (node.parent and "fixed-partitions" in node.parent.compats): + return + + global flash_area_num + out_comment("fixed-partitions identifier:") + out_dt_define(f"{node.z_path_id}_PARTITION_ID", flash_area_num) + flash_area_num += 1 + + def write_vanilla_props(node): # Writes macros for any and all properties defined in the # "properties" section of the binding for the node. diff --git a/scripts/dts/python-devicetree/src/devicetree/edtlib.py b/scripts/dts/python-devicetree/src/devicetree/edtlib.py index 1d277a0f783fa..ceb3fda5faead 100644 --- a/scripts/dts/python-devicetree/src/devicetree/edtlib.py +++ b/scripts/dts/python-devicetree/src/devicetree/edtlib.py @@ -1385,12 +1385,21 @@ class PinCtrl: The name of the configuration, as given in pinctrl-names, or None if there is no pinctrl-names property + name_as_token: + Like 'name', but with non-alphanumeric characters converted to underscores. + conf_nodes: A list of Node instances for the pin configuration nodes, e.g. the nodes pointed at by &state_1 and &state_2 in pinctrl-0 = <&state_1 &state_2>; """ + + @property + def name_as_token(self): + "See the class docstring" + return _val_as_token(self.name) if self.name is not None else None + def __repr__(self): fields = [] @@ -1482,7 +1491,7 @@ def type(self): @property def val_as_token(self): "See the class docstring" - return re.sub(_NOT_ALPHANUM_OR_UNDERSCORE, '_', self.val) + return _val_as_token(self.val) @property def enum_index(self): @@ -2753,6 +2762,11 @@ def _err(msg): # Regular expression for non-alphanumeric-or-underscore characters. _NOT_ALPHANUM_OR_UNDERSCORE = re.compile(r'\W', re.ASCII) + +def _val_as_token(val): + return re.sub(_NOT_ALPHANUM_OR_UNDERSCORE, '_', val) + + # Custom PyYAML binding loader class to avoid modifying yaml.Loader directly, # which could interfere with YAML loading in clients class _BindingLoader(Loader): diff --git a/soc/arm/atmel_sam/common/atmel_sam_dt.h b/soc/arm/atmel_sam/common/atmel_sam_dt.h index 2ffa46356845a..ca6d1ef781170 100644 --- a/soc/arm/atmel_sam/common/atmel_sam_dt.h +++ b/soc/arm/atmel_sam/common/atmel_sam_dt.h @@ -15,30 +15,26 @@ /* Devicetree related macros to construct pin mux config data */ -/* Get a node id from a pinctrl-0 prop at index 'i' */ -#define NODE_ID_FROM_PINCTRL_0(node_id, i) \ - DT_PHANDLE_BY_IDX(node_id, pinctrl_0, i) - /* Get PIN associated with pinctrl-0 pin at index 'i' */ #define ATMEL_SAM_PIN(node_id, i) \ - DT_PHA(NODE_ID_FROM_PINCTRL_0(node_id, i), atmel_pins, pin) + DT_PHA(DT_PINCTRL_0(node_id, i), atmel_pins, pin) /* Get PIO register address associated with pinctrl-0 pin at index 'i' */ #define ATMEL_SAM_PIN_TO_PIO_REG_ADDR(node_id, i) \ - DT_REG_ADDR(DT_PHANDLE(NODE_ID_FROM_PINCTRL_0(node_id, i), atmel_pins)) + DT_REG_ADDR(DT_PHANDLE(DT_PINCTRL_0(node_id, i), atmel_pins)) /* Get peripheral id for PIO associated with pinctrl-0 pin at index 'i' */ #define ATMEL_SAM_PIN_2_PIO_PERIPH_ID(node_id, i) \ - DT_PROP_BY_PHANDLE(NODE_ID_FROM_PINCTRL_0(node_id, i),\ + DT_PROP_BY_PHANDLE(DT_PINCTRL_0(node_id, i),\ atmel_pins, peripheral_id) /* Get peripheral cfg associated wiith pinctrl-0 pin at index 'i' */ #define ATMEL_SAM_PIN_PERIPH(node_id, i) \ - DT_PHA(NODE_ID_FROM_PINCTRL_0(node_id, i), atmel_pins, peripheral) + DT_PHA(DT_PINCTRL_0(node_id, i), atmel_pins, peripheral) /* Helper function for ATMEL_SAM_PIN_FLAGS */ #define ATMEL_SAM_PIN_FLAG(node_id, i, flag) \ - DT_PROP(NODE_ID_FROM_PINCTRL_0(node_id, i), flag) + DT_PROP(DT_PINCTRL_0(node_id, i), flag) /* Convert DT flags to SoC flags */ #define ATMEL_SAM_PIN_FLAGS(node_id, i) \ @@ -81,7 +77,7 @@ #endif /* Get the number of pins for pinctrl-0 */ -#define ATMEL_SAM_DT_NUM_PINS(node_id) DT_PROP_LEN(node_id, pinctrl_0) +#define ATMEL_SAM_DT_NUM_PINS(node_id) DT_NUM_PINCTRLS_BY_IDX(node_id, 0) #define ATMEL_SAM_DT_INST_NUM_PINS(inst) \ ATMEL_SAM_DT_NUM_PINS(DT_DRV_INST(inst)) diff --git a/soc/arm/atmel_sam0/common/atmel_sam0_dt.h b/soc/arm/atmel_sam0/common/atmel_sam0_dt.h index d1dc6ef396b58..8d96c52eced56 100644 --- a/soc/arm/atmel_sam0/common/atmel_sam0_dt.h +++ b/soc/arm/atmel_sam0/common/atmel_sam0_dt.h @@ -50,25 +50,21 @@ /* Devicetree related macros to construct pin mux config data */ -/* Get a node id from a pinctrl-0 prop at index 'i' */ -#define NODE_ID_FROM_PINCTRL_0(node_id, i) \ - DT_PHANDLE_BY_IDX(node_id, pinctrl_0, i) - /* Get PIN associated with pinctrl-0 pin at index 'i' */ #define ATMEL_SAM0_PIN(node_id, i) \ - DT_PHA(NODE_ID_FROM_PINCTRL_0(node_id, i), atmel_pins, pin) + DT_PHA(DT_PINCTRL_0(node_id, i), atmel_pins, pin) /* Get PIO register address associated with pinctrl-0 pin at index 'i' */ #define ATMEL_SAM0_PIN_TO_PORT_REG_ADDR(node_id, i) \ - DT_REG_ADDR(DT_PHANDLE(NODE_ID_FROM_PINCTRL_0(node_id, i), atmel_pins)) + DT_REG_ADDR(DT_PHANDLE(DT_PINCTRL_0(node_id, i), atmel_pins)) /* Get peripheral cfg associated wiith pinctrl-0 pin at index 'i' */ #define ATMEL_SAM0_PIN_PERIPH(node_id, i) \ - DT_PHA(NODE_ID_FROM_PINCTRL_0(node_id, i), atmel_pins, peripheral) + DT_PHA(DT_PINCTRL_0(node_id, i), atmel_pins, peripheral) /* Helper function for ATMEL_SAM_PIN_FLAGS */ #define ATMEL_SAM0_PIN_FLAG(node_id, i, flag) \ - DT_PROP(NODE_ID_FROM_PINCTRL_0(node_id, i), flag) + DT_PROP(DT_PINCTRL_0(node_id, i), flag) /* Convert DT flags to SoC flags */ #define ATMEL_SAM0_PIN_FLAGS(node_id, i) \ @@ -88,7 +84,7 @@ } /* Get the number of pins for pinctrl-0 */ -#define ATMEL_SAM0_DT_NUM_PINS(node_id) DT_PROP_LEN(node_id, pinctrl_0) +#define ATMEL_SAM0_DT_NUM_PINS(node_id) DT_NUM_PINCTRLS_BY_IDX(node_id, 0) #define ATMEL_SAM0_DT_INST_NUM_PINS(inst) \ ATMEL_SAM0_DT_NUM_PINS(DT_DRV_INST(inst)) diff --git a/soc/arm/cypress/common/cypress_psoc6_dt.h b/soc/arm/cypress/common/cypress_psoc6_dt.h index 9f20a5f2209ec..a8bbe53aad526 100644 --- a/soc/arm/cypress/common/cypress_psoc6_dt.h +++ b/soc/arm/cypress/common/cypress_psoc6_dt.h @@ -106,25 +106,21 @@ * Devicetree related macros to construct pin control config data */ -/* Get a node id from a pinctrl-0 prop at index 'i' */ -#define NODE_ID_FROM_PINCTRL_0(inst, i) \ - DT_INST_PHANDLE_BY_IDX(inst, pinctrl_0, i) - /* Get GPIO register address associated with pinctrl-0 pin at index 'i' */ #define CY_PSOC6_PIN_TO_GPIO_REG_ADDR(inst, i) \ - DT_REG_ADDR(DT_PHANDLE(NODE_ID_FROM_PINCTRL_0(inst, i), cypress_pins)) + DT_REG_ADDR(DT_PHANDLE(DT_INST_PINCTRL_0(inst, i), cypress_pins)) /* Get PIN associated with pinctrl-0 pin at index 'i' */ #define CY_PSOC6_PIN(inst, i) \ - DT_PHA(NODE_ID_FROM_PINCTRL_0(inst, i), cypress_pins, pin) + DT_PHA(DT_INST_PINCTRL_0(inst, i), cypress_pins, pin) /* Get HSIOM value associated with pinctrl-0 pin at index 'i' */ #define CY_PSOC6_PIN_HSIOM(inst, i) \ - DT_PHA(NODE_ID_FROM_PINCTRL_0(inst, i), cypress_pins, hsiom) + DT_PHA(DT_INST_PINCTRL_0(inst, i), cypress_pins, hsiom) /* Helper function for CY_PSOC6_PIN_FLAGS */ #define CY_PSOC6_PIN_FLAG(inst, i, flag) \ - DT_PROP(NODE_ID_FROM_PINCTRL_0(inst, i), flag) + DT_PROP(DT_INST_PINCTRL_0(inst, i), flag) /* Convert DT flags to SoC flags */ #define CY_PSOC6_PIN_FLAGS(inst, i) \ @@ -151,7 +147,7 @@ } /* Get the number of pins for pinctrl-0 */ -#define CY_PSOC6_DT_INST_NUM_PINS(inst) DT_INST_PROP_LEN(inst, pinctrl_0) +#define CY_PSOC6_DT_INST_NUM_PINS(inst) DT_INST_NUM_PINCTRLS_BY_IDX(inst, 0) /* internal macro to structure things for use with UTIL_LISTIFY */ #define CY_PSOC6_PIN_ELEM(idx, inst) CY_PSOC6_DT_INST_PIN(inst, idx), diff --git a/soc/arm/nuvoton_npcx/common/soc_dt.h b/soc/arm/nuvoton_npcx/common/soc_dt.h index ff9bd44a31cc6..076546a279112 100644 --- a/soc/arm/nuvoton_npcx/common/soc_dt.h +++ b/soc/arm/nuvoton_npcx/common/soc_dt.h @@ -121,17 +121,6 @@ inst) \ } -/** - * @brief Get phandle from 'pinctrl-0' prop which type is 'phandles' at index - * 'i' - * - * @param inst instance number for compatible defined in DT_DRV_COMPAT. - * @param i index of 'pinctrl-0' prop which type is 'phandles' - * @return phandle from 'pinctrl-0' prop at index 'i' - */ -#define NPCX_DT_PHANDLE_FROM_PINCTRL(inst, i) \ - DT_INST_PHANDLE_BY_IDX(inst, pinctrl_0, i) - /** * @brief Construct a npcx_alt structure from 'pinctrl-0' property at index 'i' * @@ -139,21 +128,13 @@ * @param i index of 'pinctrl-0' prop which type is 'phandles' * @return npcx_alt item from 'pinctrl-0' property at index 'i' */ -#define NPCX_DT_ALT_ITEM_BY_IDX(inst, i) \ - { \ - .group = DT_PHA(NPCX_DT_PHANDLE_FROM_PINCTRL(inst, i), alts, group), \ - .bit = DT_PHA(NPCX_DT_PHANDLE_FROM_PINCTRL(inst, i), alts, bit), \ - .inverted = DT_PHA(NPCX_DT_PHANDLE_FROM_PINCTRL(inst, i), alts, inv),\ +#define NPCX_DT_ALT_ITEM_BY_IDX(inst, i) \ + { \ + .group = DT_PHA(DT_INST_PINCTRL_0(inst, i), alts, group), \ + .bit = DT_PHA(DT_INST_PINCTRL_0(inst, i), alts, bit), \ + .inverted = DT_PHA(DT_INST_PINCTRL_0(inst, i), alts, inv), \ }, -/** - * @brief Length of npcx_alt structures in 'pinctrl-0' property - * - * @param inst instance number for compatible defined in DT_DRV_COMPAT. - * @return length of 'pinctrl-0' property which type is 'phandles' - */ -#define NPCX_DT_ALT_ITEMS_LEN(inst) DT_INST_PROP_LEN(inst, pinctrl_0) - /** * @brief Macro function to construct npcx_alt item in UTIL_LISTIFY extension. * @@ -181,10 +162,10 @@ * @param inst instance number for compatible defined in DT_DRV_COMPAT. * @return an array of npcx_alt items. */ -#define NPCX_DT_ALT_ITEMS_LIST(inst) { \ - UTIL_LISTIFY(NPCX_DT_ALT_ITEMS_LEN(inst), \ - NPCX_DT_ALT_ITEMS_FUNC, \ - inst) \ +#define NPCX_DT_ALT_ITEMS_LIST(inst) { \ + UTIL_LISTIFY(DT_INST_NUM_PINCTRLS_BY_IDX(inst, 0), \ + NPCX_DT_ALT_ITEMS_FUNC, \ + inst) \ } /** @@ -221,7 +202,7 @@ * @return phandle from 'pinctrl-0' prop at index 'i' */ #define NPCX_DT_IO_PHANDLE_FROM_PINCTRL(io_comp, inst, i) \ - NPCX_DT_COMP_INST_PHANDLE_BY_IDX(io_comp, inst, pinctrl_0, i) + DT_PINCTRL_BY_IDX(NPCX_DT_COMP_INST(io_comp, inst), 0, i) /** * @brief Construct a npcx_alt structure from 'pinctrl-0' property at index 'i' @@ -229,7 +210,7 @@ * * @param io_comp compatible string in devicetree file for io-pads device * @param inst instance number for compatible defined in io_comp. - * @param i index of 'pinctrl_0' prop which type is 'phandles' + * @param i index of 'pinctrl-0' prop which type is 'phandles' * @return npcx_alt item from 'pinctrl-0' property at index 'i' */ #define NPCX_DT_IO_ALT_ITEM_BY_IDX(io_comp, inst, i) \ @@ -251,7 +232,7 @@ * @return length of 'pinctrl-0' property which type is 'phandles' */ #define NPCX_DT_IO_ALT_ITEMS_LEN(io_comp, inst) \ - DT_PROP_LEN(NPCX_DT_COMP_INST(io_comp, inst), pinctrl_0) + DT_NUM_PINCTRLS_BY_IDX(NPCX_DT_COMP_INST(io_comp, inst), 0) /** * @brief Macro function to construct npcx_alt item with specific compatible @@ -607,7 +588,7 @@ * @return phandle from 'pinctrl-0' prop at index 'i' */ #define NPCX_DT_PHANDLE_FROM_PSL_PINMUX_NODE(i) \ - DT_PHANDLE(NPCX_DT_PHANDLE_FROM_PSL_IN_NODE(i), pinctrl_0) + DT_PINCTRL_0(NPCX_DT_PHANDLE_FROM_PSL_IN_NODE(i), 0) /** * @brief Get phandle from 'polarity-0' prop which type is 'phandles' at index diff --git a/soc/arm/st_stm32/common/st_stm32_dt.h b/soc/arm/st_stm32/common/st_stm32_dt.h index 88b738ae52fd4..3b0547d1b5d33 100644 --- a/soc/arm/st_stm32/common/st_stm32_dt.h +++ b/soc/arm/st_stm32/common/st_stm32_dt.h @@ -32,7 +32,7 @@ * @return elements's node identifier */ #define ST_STM32_DT_INST_NODE_ID_FROM_PINCTRL(inst, x, i) \ - DT_INST_PHANDLE_BY_IDX(inst, pinctrl_##x, i) + DT_INST_PINCTRL_BY_IDX(inst, x, i) /** * @brief Internal: Get a node indentifier for an element in a @@ -44,7 +44,7 @@ * @return elements's node identifier */ #define ST_STM32_DT_NODE_ID_FROM_PINCTRL(name, x, i) \ - DT_PHANDLE_BY_IDX(DT_NODELABEL(name), pinctrl_##x, i) + DT_PINCTRL_BY_IDX(DT_NODELABEL(name), x, i) /** * @brief Internal: Get pinmux property of a node indentifier for an element @@ -238,7 +238,7 @@ * @param x index of targeted pinctrl- property (eg: pinctrl-) * @return number of element in property */ -#define ST_STM32_DT_INST_NUM_PINS(inst, x) DT_INST_PROP_LEN(inst, pinctrl_##x) +#define ST_STM32_DT_INST_NUM_PINS(inst, x) DT_INST_NUM_PINCTRLS_BY_IDX(inst, x) /** * @brief Internal: Return the number of elements of a pinctrl-x property @@ -252,7 +252,7 @@ * @return number of element in property */ #define ST_STM32_DT_NUM_PINS(name, x) \ - DT_PROP_LEN(DT_NODELABEL(name), pinctrl_##x) + DT_NUM_PINCTRLS_BY_IDX(DT_NODELABEL(name), x) /** * @brief Construct a soc_gpio_pinctrl array of a specific pcintrl property @@ -266,7 +266,7 @@ * @return array of soc_gpio_pinctrl */ #define ST_STM32_DT_INST_PINCTRL(inst, x) \ - { COND_CODE_1(DT_INST_NODE_HAS_PROP(inst, pinctrl_##x), \ + { COND_CODE_1(DT_INST_PINCTRL_HAS_IDX(inst, x), \ (UTIL_LISTIFY(ST_STM32_DT_INST_NUM_PINS(inst, x), \ ST_STM32_DT_INST_PIN_ELEM, \ x, \ @@ -287,7 +287,7 @@ * @return array of soc_gpio_pinctrl */ #define ST_STM32_DT_PINCTRL(name, x) \ - { COND_CODE_1(DT_NODE_HAS_PROP(DT_NODELABEL(name), pinctrl_##x),\ + { COND_CODE_1(DT_PINCTRL_HAS_IDX(DT_NODELABEL(name), x), \ (UTIL_LISTIFY(ST_STM32_DT_NUM_PINS(name, x), \ ST_STM32_DT_PIN_ELEM, \ x, \ diff --git a/soc/riscv/riscv-ite/common/soc_dt.h b/soc/riscv/riscv-ite/common/soc_dt.h index 188a7cf315c40..20bd900debe68 100644 --- a/soc/riscv/riscv-ite/common/soc_dt.h +++ b/soc/riscv/riscv-ite/common/soc_dt.h @@ -7,12 +7,12 @@ #ifndef _ITE_IT8XXX2_SOC_DT_H_ #define _ITE_IT8XXX2_SOC_DT_H_ -#define IT8XXX2_DEV_PINMUX(idx, inst) DEVICE_DT_GET(DT_PHANDLE(DT_PHANDLE_BY_IDX \ - (DT_DRV_INST(inst), pinctrl_0, idx), pinctrls)) -#define IT8XXX2_DEV_PIN(idx, inst) DT_PHA(DT_PHANDLE_BY_IDX \ - (DT_DRV_INST(inst), pinctrl_0, idx), pinctrls, pin) -#define IT8XXX2_DEV_ALT_FUNC(idx, inst) DT_PHA(DT_PHANDLE_BY_IDX \ - (DT_DRV_INST(inst), pinctrl_0, idx), pinctrls, alt_func) +#define IT8XXX2_DEV_PINMUX(idx, inst) DEVICE_DT_GET(DT_PHANDLE( \ + DT_INST_PINCTRL_0(inst, idx), pinctrls)) +#define IT8XXX2_DEV_PIN(idx, inst) DT_PHA( \ + DT_INST_PINCTRL_0(inst, idx), pinctrls, pin) +#define IT8XXX2_DEV_ALT_FUNC(idx, inst) DT_PHA( \ + DT_INST_PINCTRL_0(inst, idx), pinctrls, alt_func) /** * @brief Macro function to construct it8xxx2 alt item in UTIL_LISTIFY extension. @@ -35,10 +35,10 @@ * @param inst instance number for compatible defined in DT_DRV_COMPAT. * @return an array of it8xxx2 alt items. */ -#define IT8XXX2_DT_ALT_ITEMS_LIST(inst) { \ - UTIL_LISTIFY(DT_INST_PROP_LEN(inst, pinctrl_0), \ - IT8XXX2_DT_ALT_ITEMS_FUNC, \ - inst) \ +#define IT8XXX2_DT_ALT_ITEMS_LIST(inst) { \ + UTIL_LISTIFY(DT_INST_NUM_PINCTRLS_BY_IDX(inst, 0), \ + IT8XXX2_DT_ALT_ITEMS_FUNC, \ + inst) \ } #endif /* _ITE_IT8XXX2_SOC_DT_H_ */ diff --git a/tests/lib/devicetree/api/app.overlay b/tests/lib/devicetree/api/app.overlay index 61560df5a8c0c..bbf2a080cc0a0 100644 --- a/tests/lib/devicetree/api/app.overlay +++ b/tests/lib/devicetree/api/app.overlay @@ -24,6 +24,14 @@ #size-cells = < 0x1 >; interrupt-parent = <&test_intc>; + test_pinctrl: pin-controller { + compatible = "vnd,pinctrl"; + test_pincfg_a: pincfg-a {}; + test_pincfg_b: pincfg-b {}; + test_pincfg_c: pincfg-c {}; + test_pincfg_d: pincfg-d {}; + }; + test_arrays: array-holder { /* * vnd,undefined-compat is for DT_NODE_HAS_COMPAT_STATUS(..,okay). @@ -308,6 +316,10 @@ dma-names = "tx", "rx"; clocks = <&test_clk 3 7>, <&test_fixed_clk>, <&test_clk 8 2>; clock-names = "clk-a", "clk-fixed", "clk-b"; + pinctrl-0 = <&test_pincfg_a &test_pincfg_b>; + pinctrl-1 = <&test_pincfg_c &test_pincfg_d>; + pinctrl-2 = <&test_pincfg_d>; + pinctrl-names = "default", "sleep", "f.o.o2"; }; /* there should only be one of these */ diff --git a/tests/lib/devicetree/api/src/main.c b/tests/lib/devicetree/api/src/main.c index 3a49825b62a3a..ccc55d0721e99 100644 --- a/tests/lib/devicetree/api/src/main.c +++ b/tests/lib/devicetree/api/src/main.c @@ -1919,6 +1919,165 @@ static void test_same_node(void) zassert_false(DT_SAME_NODE(TEST_DEADBEEF, TEST_ABCD1234), ""); } +static void test_pinctrl(void) +{ +#undef DT_DRV_COMPAT +#define DT_DRV_COMPAT vnd_adc_temp_sensor + /* + * Tests when a node does have pinctrl properties. + */ + + /* + * node_id versions: + */ + + zassert_true(DT_SAME_NODE(DT_PINCTRL_BY_IDX(TEST_TEMP, 0, 1), + DT_NODELABEL(test_pincfg_b)), ""); + zassert_true(DT_SAME_NODE(DT_PINCTRL_BY_IDX(TEST_TEMP, 1, 0), + DT_NODELABEL(test_pincfg_c)), ""); + + zassert_true(DT_SAME_NODE(DT_PINCTRL_0(TEST_TEMP, 0), + DT_NODELABEL(test_pincfg_a)), ""); + + zassert_true(DT_SAME_NODE(DT_PINCTRL_BY_NAME(TEST_TEMP, default, 1), + DT_NODELABEL(test_pincfg_b)), ""); + zassert_true(DT_SAME_NODE(DT_PINCTRL_BY_NAME(TEST_TEMP, sleep, 0), + DT_NODELABEL(test_pincfg_c)), ""); + zassert_true(DT_SAME_NODE(DT_PINCTRL_BY_NAME(TEST_TEMP, f_o_o2, 0), + DT_NODELABEL(test_pincfg_d)), ""); + + zassert_equal(DT_PINCTRL_NAME_TO_IDX(TEST_TEMP, default), 0, ""); + zassert_equal(DT_PINCTRL_NAME_TO_IDX(TEST_TEMP, sleep), 1, ""); + zassert_equal(DT_PINCTRL_NAME_TO_IDX(TEST_TEMP, f_o_o2), 2, ""); + + zassert_equal(DT_NUM_PINCTRLS_BY_IDX(TEST_TEMP, 0), 2, ""); + + zassert_equal(DT_NUM_PINCTRLS_BY_NAME(TEST_TEMP, default), 2, ""); + zassert_equal(DT_NUM_PINCTRLS_BY_NAME(TEST_TEMP, f_o_o2), 1, ""); + + zassert_equal(DT_NUM_PINCTRL_STATES(TEST_TEMP), 3, ""); + + zassert_equal(DT_PINCTRL_HAS_IDX(TEST_TEMP, 0), 1, ""); + zassert_equal(DT_PINCTRL_HAS_IDX(TEST_TEMP, 1), 1, ""); + zassert_equal(DT_PINCTRL_HAS_IDX(TEST_TEMP, 2), 1, ""); + zassert_equal(DT_PINCTRL_HAS_IDX(TEST_TEMP, 3), 0, ""); + + zassert_equal(DT_PINCTRL_HAS_NAME(TEST_TEMP, default), 1, ""); + zassert_equal(DT_PINCTRL_HAS_NAME(TEST_TEMP, sleep), 1, ""); + zassert_equal(DT_PINCTRL_HAS_NAME(TEST_TEMP, f_o_o2), 1, ""); + zassert_equal(DT_PINCTRL_HAS_NAME(TEST_TEMP, bar), 0, ""); + +#undef MAKE_TOKEN +#define MAKE_TOKEN(pc_idx) \ + _CONCAT(NODE_ID_ENUM_, \ + DT_PINCTRL_IDX_TO_NAME_TOKEN(TEST_TEMP, pc_idx)) +#undef MAKE_UPPER_TOKEN +#define MAKE_UPPER_TOKEN(pc_idx) \ + _CONCAT(NODE_ID_ENUM_, \ + DT_PINCTRL_IDX_TO_NAME_UPPER_TOKEN(TEST_TEMP, pc_idx)) + enum { + MAKE_TOKEN(0) = 10, + MAKE_TOKEN(1) = 11, + MAKE_TOKEN(2) = 12, + MAKE_TOKEN(3) = 13, + + MAKE_UPPER_TOKEN(0) = 20, + MAKE_UPPER_TOKEN(1) = 21, + MAKE_UPPER_TOKEN(2) = 22, + MAKE_UPPER_TOKEN(3) = 23, + }; + + zassert_equal(NODE_ID_ENUM_default, 10, ""); + zassert_equal(NODE_ID_ENUM_sleep, 11, ""); + zassert_equal(NODE_ID_ENUM_f_o_o2, 12, ""); + + zassert_equal(NODE_ID_ENUM_DEFAULT, 20, ""); + zassert_equal(NODE_ID_ENUM_SLEEP, 21, ""); + zassert_equal(NODE_ID_ENUM_F_O_O2, 22, ""); + + /* + * inst versions: + */ + + zassert_true(DT_SAME_NODE(DT_INST_PINCTRL_BY_IDX(0, 0, 1), + DT_NODELABEL(test_pincfg_b)), ""); + zassert_true(DT_SAME_NODE(DT_INST_PINCTRL_BY_IDX(0, 1, 0), + DT_NODELABEL(test_pincfg_c)), ""); + + zassert_true(DT_SAME_NODE(DT_INST_PINCTRL_0(0, 0), + DT_NODELABEL(test_pincfg_a)), ""); + + zassert_true(DT_SAME_NODE(DT_INST_PINCTRL_BY_NAME(0, default, 1), + DT_NODELABEL(test_pincfg_b)), ""); + zassert_true(DT_SAME_NODE(DT_INST_PINCTRL_BY_NAME(0, sleep, 0), + DT_NODELABEL(test_pincfg_c)), ""); + zassert_true(DT_SAME_NODE(DT_INST_PINCTRL_BY_NAME(0, f_o_o2, 0), + DT_NODELABEL(test_pincfg_d)), ""); + + zassert_equal(DT_INST_PINCTRL_NAME_TO_IDX(0, default), 0, ""); + zassert_equal(DT_INST_PINCTRL_NAME_TO_IDX(0, sleep), 1, ""); + zassert_equal(DT_INST_PINCTRL_NAME_TO_IDX(0, f_o_o2), 2, ""); + + zassert_equal(DT_INST_NUM_PINCTRLS_BY_IDX(0, 0), 2, ""); + + zassert_equal(DT_INST_NUM_PINCTRLS_BY_NAME(0, default), 2, ""); + zassert_equal(DT_INST_NUM_PINCTRLS_BY_NAME(0, f_o_o2), 1, ""); + + zassert_equal(DT_INST_NUM_PINCTRL_STATES(0), 3, ""); + + zassert_equal(DT_INST_PINCTRL_HAS_IDX(0, 0), 1, ""); + zassert_equal(DT_INST_PINCTRL_HAS_IDX(0, 1), 1, ""); + zassert_equal(DT_INST_PINCTRL_HAS_IDX(0, 2), 1, ""); + zassert_equal(DT_INST_PINCTRL_HAS_IDX(0, 3), 0, ""); + + zassert_equal(DT_INST_PINCTRL_HAS_NAME(0, default), 1, ""); + zassert_equal(DT_INST_PINCTRL_HAS_NAME(0, sleep), 1, ""); + zassert_equal(DT_INST_PINCTRL_HAS_NAME(0, f_o_o2), 1, ""); + zassert_equal(DT_INST_PINCTRL_HAS_NAME(0, bar), 0, ""); + +#undef MAKE_TOKEN +#define MAKE_TOKEN(pc_idx) \ + _CONCAT(INST_ENUM_, \ + DT_INST_PINCTRL_IDX_TO_NAME_TOKEN(0, pc_idx)) +#undef MAKE_UPPER_TOKEN +#define MAKE_UPPER_TOKEN(pc_idx) \ + _CONCAT(INST_ENUM_, \ + DT_INST_PINCTRL_IDX_TO_NAME_UPPER_TOKEN(0, pc_idx)) + enum { + MAKE_TOKEN(0) = 10, + MAKE_TOKEN(1) = 11, + MAKE_TOKEN(2) = 12, + + MAKE_UPPER_TOKEN(0) = 20, + MAKE_UPPER_TOKEN(1) = 21, + MAKE_UPPER_TOKEN(2) = 22, + }; + + zassert_equal(INST_ENUM_default, 10, ""); + zassert_equal(INST_ENUM_sleep, 11, ""); + zassert_equal(INST_ENUM_f_o_o2, 12, ""); + + zassert_equal(INST_ENUM_DEFAULT, 20, ""); + zassert_equal(INST_ENUM_SLEEP, 21, ""); + zassert_equal(INST_ENUM_F_O_O2, 22, ""); + +#undef DT_DRV_COMPAT +#define DT_DRV_COMPAT vnd_reg_holder + /* + * Tests when a node does NOT have any pinctrl properties. + */ + + /* node_id versions */ + zassert_equal(DT_NUM_PINCTRL_STATES(TEST_REG), 0, ""); + zassert_equal(DT_PINCTRL_HAS_IDX(TEST_REG, 0), 0, ""); + zassert_equal(DT_PINCTRL_HAS_NAME(TEST_REG, f_o_o2), 0, ""); + + /* inst versions */ + zassert_equal(DT_INST_NUM_PINCTRL_STATES(0), 0, ""); + zassert_equal(DT_INST_PINCTRL_HAS_IDX(0, 0), 0, ""); + zassert_equal(DT_INST_PINCTRL_HAS_NAME(0, f_o_o2), 0, ""); +} + void test_main(void) { ztest_test_suite(devicetree_api, @@ -1960,7 +2119,8 @@ void test_main(void) ztest_unit_test(test_dep_ord), ztest_unit_test(test_path), ztest_unit_test(test_node_name), - ztest_unit_test(test_same_node) + ztest_unit_test(test_same_node), + ztest_unit_test(test_pinctrl) ); ztest_run_test_suite(devicetree_api); }