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