|
15 | 15 | #include <devicetree.h> |
16 | 16 | #include <toolchain.h> |
17 | 17 |
|
| 18 | +/** |
| 19 | + * @brief Get a PSEL value out of a foo-gpios or foo-pin devicetree property |
| 20 | + * |
| 21 | + * Many Nordic bindings have 'foo-pin' properties to specify a pin |
| 22 | + * configuration as a PSEL value directly instead of using a 'foo-gpios' |
| 23 | + * <&gpioX Y flags> style controller phandle + GPIO specifier. |
| 24 | + * |
| 25 | + * It would be better to use 'foo-gpios' properties instead. This type |
| 26 | + * of property is more in line with the recommended DT encoding for GPIOs. |
| 27 | + * |
| 28 | + * To allow for a smooth migration from 'foo-pin' to 'foo-gpios', this |
| 29 | + * helper macro can be used to get a PSEL value out of the devicetree |
| 30 | + * using whichever one of 'foo-gpios' or 'foo-pin' is in the DTS. |
| 31 | + * |
| 32 | + * Note that you can also use: |
| 33 | + * |
| 34 | + * - NRF_DT_PSEL_CHECK_*() to check the property configuration at build time |
| 35 | + * - NRF_DT_GPIOS_TO_PSEL() if you only have a 'foo-gpios' |
| 36 | + * |
| 37 | + * @param node_id node identifier |
| 38 | + * @param psel_prop lowercase-and-underscores old-style 'foo-pin' property |
| 39 | + * @param gpios_prop new-style 'foo-gpios' property |
| 40 | + * @param default_val the value returned if neither is set |
| 41 | + * @return PSEL register value taken from psel_prop or gpios_prop, whichever |
| 42 | + * is present in the DTS. If gpios_prop is present, it is converted |
| 43 | + * to a PSEL register value first. |
| 44 | + */ |
| 45 | +#define NRF_DT_PSEL(node_id, psel_prop, gpios_prop, default_val) \ |
| 46 | + COND_CODE_1(DT_NODE_HAS_PROP(node_id, psel_prop), \ |
| 47 | + (DT_PROP(node_id, psel_prop)), \ |
| 48 | + (COND_CODE_1( \ |
| 49 | + DT_NODE_HAS_PROP(node_id, gpios_prop), \ |
| 50 | + (NRF_DT_GPIOS_TO_PSEL(node_id, \ |
| 51 | + gpios_prop)), \ |
| 52 | + (default_val)))) |
| 53 | + |
| 54 | +/** |
| 55 | + * Error out the build if the devicetree node with identifier |
| 56 | + * 'node_id' has both a legacy psel-style property and a gpios |
| 57 | + * property. |
| 58 | + * |
| 59 | + * Otherwise, do nothing. |
| 60 | + * |
| 61 | + * @param node_id node identifier |
| 62 | + * @param psel_prop lowercase-and-underscores PSEL style property |
| 63 | + * @param psel_prop_name human-readable string name of psel_prop |
| 64 | + * @param gpios_prop lowercase-and-underscores foo-gpios style property |
| 65 | + * @param gpio_prop_name human-readable string name of gpios_prop |
| 66 | + */ |
| 67 | +#define NRF_DT_PSEL_CHECK_NOT_BOTH(node_id, psel_prop, psel_prop_name, \ |
| 68 | + gpios_prop, gpios_prop_name) \ |
| 69 | + BUILD_ASSERT( \ |
| 70 | + !(DT_NODE_HAS_PROP(node_id, psel_prop) && \ |
| 71 | + DT_NODE_HAS_PROP(node_id, gpios_prop)), \ |
| 72 | + "Devicetree node " DT_NODE_PATH(node_id) \ |
| 73 | + " has both of the " psel_prop_name \ |
| 74 | + " and " gpios_prop_name \ |
| 75 | + " properties set; you must remove one. " \ |
| 76 | + "Note: you can use /delete-property/ to delete properties.") |
| 77 | + |
| 78 | +/** |
| 79 | + * Like NRF_DT_PSEL_CHECK_NOT_BOTH, but instead checks that exactly one |
| 80 | + * of the properties is set. |
| 81 | + */ |
| 82 | +#define NRF_DT_PSEL_CHECK_EXACTLY_ONE(node_id, \ |
| 83 | + psel_prop, psel_prop_name, \ |
| 84 | + gpios_prop, gpios_prop_name) \ |
| 85 | + BUILD_ASSERT( \ |
| 86 | + (DT_NODE_HAS_PROP(node_id, psel_prop) ^ \ |
| 87 | + DT_NODE_HAS_PROP(node_id, gpios_prop)), \ |
| 88 | + "Devicetree node " DT_NODE_PATH(node_id) \ |
| 89 | + " must have exactly one of the " psel_prop_name \ |
| 90 | + " and " gpios_prop_name \ |
| 91 | + " properties set. " \ |
| 92 | + "Note: you can use /delete-property/ to delete properties.") |
| 93 | + |
18 | 94 | /** |
19 | 95 | * @brief Convert a devicetree GPIO phandle+specifier to PSEL value |
20 | 96 | * |
|
0 commit comments