1 /* 2 * Copyright 2022 Intel Corporation 3 * 4 * SPDX-License-Identifier: Apache-2.0 5 */ 6 7 #ifndef ZEPHYR_INCLUDE_DRIVERS_I3C_DEVICETREE_H_ 8 #define ZEPHYR_INCLUDE_DRIVERS_I3C_DEVICETREE_H_ 9 10 /** 11 * @brief I3C Devicetree related bits 12 * @defgroup i3c_devicetree I3C Devicetree related bits 13 * @ingroup i3c_interface 14 * @{ 15 */ 16 17 #include <stdint.h> 18 19 #include <zephyr/device.h> 20 #include <zephyr/devicetree.h> 21 #include <zephyr/sys/util.h> 22 23 #ifdef __cplusplus 24 extern "C" { 25 #endif 26 27 /** 28 * @brief Structure initializer for i3c_device_id from devicetree 29 * 30 * This helper macro expands to a static initializer for a <tt>struct 31 * i3c_device_id</tt> by reading the relevant device data from devicetree. 32 * 33 * @param node_id Devicetree node identifier for the I3C device whose 34 * struct i3c_device_id to create an initializer for 35 */ 36 #define I3C_DEVICE_ID_DT(node_id) \ 37 { \ 38 .pid = ((uint64_t)DT_PROP_BY_IDX(node_id, reg, 1) << 32)\ 39 | DT_PROP_BY_IDX(node_id, reg, 2), \ 40 } 41 42 /** 43 * @brief Structure initializer for i3c_device_id from devicetree instance 44 * 45 * This is equivalent to 46 * @code{.c} 47 * I3C_DEVICE_ID_DT(DT_DRV_INST(inst)) 48 * @endcode 49 * 50 * @param inst Devicetree instance number 51 */ 52 #define I3C_DEVICE_ID_DT_INST(inst) \ 53 I3C_DEVICE_ID_DT(DT_DRV_INST(inst)) 54 55 /** 56 * @brief Structure initializer for i3c_device_desc from devicetree 57 * 58 * This helper macro expands to a static initializer for a <tt>struct 59 * i3c_device_desc</tt> by reading the relevant bus and device data 60 * from the devicetree. 61 * 62 * @param node_id Devicetree node identifier for the I3C device whose 63 * struct i3c_device_desc to create an initializer for 64 */ 65 #define I3C_DEVICE_DESC_DT(node_id) \ 66 { \ 67 .bus = DEVICE_DT_GET(DT_BUS(node_id)), \ 68 .dev = DEVICE_DT_GET(node_id), \ 69 .static_addr = DT_PROP_BY_IDX(node_id, reg, 0), \ 70 .pid = ((uint64_t)DT_PROP_BY_IDX(node_id, reg, 1) << 32)\ 71 | DT_PROP_BY_IDX(node_id, reg, 2), \ 72 .init_dynamic_addr = \ 73 DT_PROP_OR(node_id, assigned_address, 0), \ 74 .supports_setaasa = DT_PROP(node_id, supports_setaasa), \ 75 }, 76 77 /** 78 * @brief Structure initializer for i3c_device_desc from devicetree instance 79 * 80 * This is equivalent to 81 * 82 * @code{.c} 83 * I3C_DEVICE_DESC_DT(DT_DRV_INST(inst)) 84 * @endcode 85 * 86 * @param inst Devicetree instance number 87 */ 88 #define I3C_DEVICE_DESC_DT_INST(inst) \ 89 I3C_DEVICE_DESC_DT(DT_DRV_INST(inst)) 90 91 /** 92 * @brief Structure initializer for i3c_device_desc from devicetree 93 * 94 * This is mainly used by I3C_DEVICE_ARRAY_DT() to only 95 * create a struct if and only if it is an I3C device. 96 */ 97 #define I3C_DEVICE_DESC_DT_FILTERED(node_id) \ 98 COND_CODE_0(DT_PROP_BY_IDX(node_id, reg, 1), \ 99 (), (I3C_DEVICE_DESC_DT(node_id))) 100 101 /** 102 * @brief Array initializer for a list of i3c_device_desc from devicetree 103 * 104 * This is a helper macro to generate an array for a list of i3c_device_desc 105 * from device tree. 106 * 107 * @param node_id Devicetree node identifier of the I3C controller 108 */ 109 #define I3C_DEVICE_ARRAY_DT(node_id) \ 110 { \ 111 DT_FOREACH_CHILD_STATUS_OKAY( \ 112 node_id, \ 113 I3C_DEVICE_DESC_DT_FILTERED) \ 114 } 115 116 /** 117 * @brief Array initializer for a list of i3c_device_desc from devicetree instance 118 * 119 * This is equivalent to 120 * @code{.c} 121 * I3C_DEVICE_ARRAY_DT(DT_DRV_INST(inst)) 122 * @endcode 123 * 124 * @param inst Devicetree instance number of the I3C controller 125 */ 126 #define I3C_DEVICE_ARRAY_DT_INST(inst) \ 127 I3C_DEVICE_ARRAY_DT(DT_DRV_INST(inst)) 128 129 /** 130 * @brief Like DEVICE_DT_DEFINE() with I3C target device specifics. 131 * 132 * Defines a I3C target device which implements the I3C target device API. 133 * 134 * @param node_id The devicetree node identifier. 135 * 136 * @param init_fn Name of the init function of the driver. 137 * 138 * @param pm PM device resources reference (`NULL` if device does not use PM). 139 * 140 * @param data Pointer to the device's private data. 141 * 142 * @param config The address to the structure containing the 143 * configuration information for this instance of the driver. 144 * 145 * @param level The initialization level. See SYS_INIT() for 146 * details. 147 * 148 * @param prio Priority within the selected initialization level. See 149 * SYS_INIT() for details. 150 * 151 * @param api Provides an initial pointer to the API function struct 152 * used by the driver. Can be NULL. 153 */ 154 #define I3C_DEVICE_DT_DEFINE(node_id, init_fn, pm, data, config, level, \ 155 prio, api, ...) \ 156 DEVICE_DT_DEFINE(node_id, init_fn, pm, data, config, level, \ 157 prio, api, __VA_ARGS__) 158 159 /** 160 * @brief Like I3C_TARGET_DT_DEFINE() for an instance of a DT_DRV_COMPAT compatible 161 * 162 * @param inst instance number. This is replaced by 163 * `DT_DRV_COMPAT(inst)` in the call to I3C_TARGET_DT_DEFINE(). 164 * 165 * @param ... other parameters as expected by I3C_TARGET_DT_DEFINE(). 166 */ 167 #define I3C_DEVICE_DT_INST_DEFINE(inst, ...) \ 168 I3C_DEVICE_DT_DEFINE(DT_DRV_INST(inst), __VA_ARGS__) 169 170 /** 171 * @brief Structure initializer for i3c_i2c_device_desc from devicetree 172 * 173 * This helper macro expands to a static initializer for a i3c_i2c_device_desc 174 * by reading the relevant bus and device data from the devicetree. 175 * 176 * @param node_id Devicetree node identifier for the I3C device whose 177 * struct i3c_i2c_device_desc to create an initializer for 178 */ 179 #define I3C_I2C_DEVICE_DESC_DT(node_id) \ 180 { \ 181 .bus = DEVICE_DT_GET(DT_BUS(node_id)), \ 182 .addr = DT_PROP_BY_IDX(node_id, reg, 0), \ 183 .lvr = DT_PROP_BY_IDX(node_id, reg, 2), \ 184 }, 185 186 /** 187 * @brief Structure initializer for i3c_i2c_device_desc from devicetree instance 188 * 189 * This is equivalent to 190 * @code{.c} 191 * I3C_I2C_DEVICE_DESC_DT(DT_DRV_INST(inst)) 192 * @endcode 193 * 194 * @param inst Devicetree instance number 195 */ 196 #define I3C_I2C_DEVICE_DESC_DT_INST(inst) \ 197 I3C_I2C_DEVICE_DESC_DT(DT_DRV_INST(inst)) 198 199 200 /** 201 * @brief Structure initializer for i3c_i2c_device_desc from devicetree 202 * 203 * This is mainly used by I3C_I2C_DEVICE_ARRAY_DT() to only 204 * create a struct if and only if it is an I2C device. 205 */ 206 #define I3C_I2C_DEVICE_DESC_DT_FILTERED(node_id) \ 207 COND_CODE_0(DT_PROP_BY_IDX(node_id, reg, 1), \ 208 (I3C_I2C_DEVICE_DESC_DT(node_id)), ()) 209 210 /** 211 * @brief Array initializer for a list of i3c_i2c_device_desc from devicetree 212 * 213 * This is a helper macro to generate an array for a list of 214 * i3c_i2c_device_desc from device tree. 215 * 216 * @param node_id Devicetree node identifier of the I3C controller 217 */ 218 #define I3C_I2C_DEVICE_ARRAY_DT(node_id) \ 219 { \ 220 DT_FOREACH_CHILD_STATUS_OKAY( \ 221 node_id, \ 222 I3C_I2C_DEVICE_DESC_DT_FILTERED) \ 223 } 224 225 /** 226 * @brief Array initializer for a list of i3c_i2c_device_desc from devicetree instance 227 * 228 * This is equivalent to 229 * @code{.c} 230 * I3C_I2C_DEVICE_ARRAY_DT(DT_DRV_INST(inst)) 231 * @endcode 232 * 233 * @param inst Devicetree instance number of the I3C controller 234 */ 235 #define I3C_I2C_DEVICE_ARRAY_DT_INST(inst) \ 236 I3C_I2C_DEVICE_ARRAY_DT(DT_DRV_INST(inst)) 237 238 #ifdef __cplusplus 239 } 240 #endif 241 242 /** 243 * @} 244 */ 245 246 #endif /* ZEPHYR_INCLUDE_DRIVERS_I3C_DEVICETREE_H_ */ 247