1 /**
2  * @file
3  * @brief Clocks Devicetree macro public API header file.
4  */
5 
6 /*
7  * Copyright (c) 2020, Linaro Ltd.
8  *
9  * SPDX-License-Identifier: Apache-2.0
10  */
11 
12 #ifndef ZEPHYR_INCLUDE_DEVICETREE_CLOCKS_H_
13 #define ZEPHYR_INCLUDE_DEVICETREE_CLOCKS_H_
14 
15 #ifdef __cplusplus
16 extern "C" {
17 #endif
18 
19 /**
20  * @defgroup devicetree-clocks Devicetree Clocks API
21  * @ingroup devicetree
22  * @{
23  */
24 
25 /**
26  * @brief Test if a node has a clocks phandle-array property at a given index
27  *
28  * This expands to 1 if the given index is valid clocks property phandle-array index.
29  * Otherwise, it expands to 0.
30  *
31  * Example devicetree fragment:
32  *
33  *     n1: node-1 {
34  *             clocks = <...>, <...>;
35  *     };
36  *
37  *     n2: node-2 {
38  *             clocks = <...>;
39  *     };
40  *
41  * Example usage:
42  *
43  *     DT_CLOCKS_HAS_IDX(DT_NODELABEL(n1), 0) // 1
44  *     DT_CLOCKS_HAS_IDX(DT_NODELABEL(n1), 1) // 1
45  *     DT_CLOCKS_HAS_IDX(DT_NODELABEL(n1), 2) // 0
46  *     DT_CLOCKS_HAS_IDX(DT_NODELABEL(n2), 1) // 0
47  *
48  * @param node_id node identifier; may or may not have any clocks property
49  * @param idx index of a clocks property phandle-array whose existence to check
50  * @return 1 if the index exists, 0 otherwise
51  */
52 #define DT_CLOCKS_HAS_IDX(node_id, idx) \
53 	DT_PROP_HAS_IDX(node_id, clocks, idx)
54 
55 /**
56  * @brief Test if a node has a clock-names array property holds a given name
57  *
58  * This expands to 1 if the name is available as clocks-name array property cell.
59  * Otherwise, it expands to 0.
60  *
61  * Example devicetree fragment:
62  *
63  *     n1: node-1 {
64  *             clocks = <...>, <...>;
65  *             clock-names = "alpha", "beta";
66  *     };
67  *
68  *     n2: node-2 {
69  *             clocks = <...>;
70  *             clock-names = "alpha";
71  *     };
72  *
73  * Example usage:
74  *
75  *     DT_CLOCKS_HAS_NAME(DT_NODELABEL(n1), alpha) // 1
76  *     DT_CLOCKS_HAS_NAME(DT_NODELABEL(n1), beta)  // 1
77  *     DT_CLOCKS_HAS_NAME(DT_NODELABEL(n2), beta)  // 0
78  *
79  * @param node_id node identifier; may or may not have any clock-names property.
80  * @param name lowercase-and-underscores clock-names cell value name to check
81  * @return 1 if the clock name exists, 0 otherwise
82  */
83 #define DT_CLOCKS_HAS_NAME(node_id, name) \
84 	DT_PROP_HAS_NAME(node_id, clocks, name)
85 
86 /**
87  * @brief Get the number of elements in a clocks property
88  *
89  * Example devicetree fragment:
90  *
91  *     n1: node-1 {
92  *             clocks = <&foo>, <&bar>;
93  *     };
94  *
95  *     n2: node-2 {
96  *             clocks = <&foo>;
97  *     };
98  *
99  * Example usage:
100  *
101  *     DT_NUM_CLOCKS(DT_NODELABEL(n1)) // 2
102  *     DT_NUM_CLOCKS(DT_NODELABEL(n2)) // 1
103  *
104  * @param node_id node identifier with a clocks property
105  * @return number of elements in the property
106  */
107 #define DT_NUM_CLOCKS(node_id) \
108 	DT_PROP_LEN(node_id, clocks)
109 
110 
111 /**
112  * @brief Get the node identifier for the controller phandle from a
113  *        "clocks" phandle-array property at an index
114  *
115  * Example devicetree fragment:
116  *
117  *     clk1: clock-controller@... { ... };
118  *
119  *     clk2: clock-controller@... { ... };
120  *
121  *     n: node {
122  *             clocks = <&clk1 10 20>, <&clk2 30 40>;
123  *     };
124  *
125  * Example usage:
126  *
127  *     DT_CLOCKS_CTLR_BY_IDX(DT_NODELABEL(n), 0)) // DT_NODELABEL(clk1)
128  *     DT_CLOCKS_CTLR_BY_IDX(DT_NODELABEL(n), 1)) // DT_NODELABEL(clk2)
129  *
130  * @param node_id node identifier
131  * @param idx logical index into "clocks"
132  * @return the node identifier for the clock controller referenced at
133  *         index "idx"
134  * @see DT_PHANDLE_BY_IDX()
135  */
136 #define DT_CLOCKS_CTLR_BY_IDX(node_id, idx) \
137 	DT_PHANDLE_BY_IDX(node_id, clocks, idx)
138 
139 /**
140  * @brief Equivalent to DT_CLOCKS_CTLR_BY_IDX(node_id, 0)
141  * @param node_id node identifier
142  * @return a node identifier for the clocks controller at index 0
143  *         in "clocks"
144  * @see DT_CLOCKS_CTLR_BY_IDX()
145  */
146 #define DT_CLOCKS_CTLR(node_id) DT_CLOCKS_CTLR_BY_IDX(node_id, 0)
147 
148 /**
149  * @brief Get the node identifier for the controller phandle from a
150  *        clocks phandle-array property by name
151  *
152  * Example devicetree fragment:
153  *
154  *     clk1: clock-controller@... { ... };
155  *
156  *     clk2: clock-controller@... { ... };
157  *
158  *     n: node {
159  *             clocks = <&clk1 10 20>, <&clk2 30 40>;
160  *             clock-names = "alpha", "beta";
161  *     };
162  *
163  * Example usage:
164  *
165  *     DT_CLOCKS_CTLR_BY_NAME(DT_NODELABEL(n), beta) // DT_NODELABEL(clk2)
166  *
167  * @param node_id node identifier
168  * @param name lowercase-and-underscores name of a clocks element
169  *             as defined by the node's clock-names property
170  * @return the node identifier for the clock controller referenced by name
171  * @see DT_PHANDLE_BY_NAME()
172  */
173 #define DT_CLOCKS_CTLR_BY_NAME(node_id, name) \
174 	DT_PHANDLE_BY_NAME(node_id, clocks, name)
175 
176 /**
177  * @brief Get a clock specifier's cell value at an index
178  *
179  * Example devicetree fragment:
180  *
181  *     clk1: clock-controller@... {
182  *             compatible = "vnd,clock";
183  *             #clock-cells = < 2 >;
184  *     };
185  *
186  *     n: node {
187  *             clocks = < &clk1 10 20 >, < &clk1 30 40 >;
188  *     };
189  *
190  * Bindings fragment for the vnd,clock compatible:
191  *
192  *     clock-cells:
193  *       - bus
194  *       - bits
195  *
196  * Example usage:
197  *
198  *     DT_CLOCKS_CELL_BY_IDX(DT_NODELABEL(n), 0, bus) // 10
199  *     DT_CLOCKS_CELL_BY_IDX(DT_NODELABEL(n), 1, bits) // 40
200  *
201  * @param node_id node identifier for a node with a clocks property
202  * @param idx logical index into clocks property
203  * @param cell lowercase-and-underscores cell name
204  * @return the cell value at index "idx"
205  * @see DT_PHA_BY_IDX()
206  */
207 #define DT_CLOCKS_CELL_BY_IDX(node_id, idx, cell) \
208 	DT_PHA_BY_IDX(node_id, clocks, idx, cell)
209 
210 /**
211  * @brief Get a clock specifier's cell value by name
212  *
213  * Example devicetree fragment:
214  *
215  *     clk1: clock-controller@... {
216  *             compatible = "vnd,clock";
217  *             #clock-cells = < 2 >;
218  *     };
219  *
220  *     n: node {
221  *             clocks = < &clk1 10 20 >, < &clk1 30 40 >;
222  *             clock-names = "alpha", "beta";
223  *     };
224  *
225  * Bindings fragment for the vnd,clock compatible:
226  *
227  *     clock-cells:
228  *       - bus
229  *       - bits
230  *
231  * Example usage:
232  *
233  *     DT_CLOCKS_CELL_BY_NAME(DT_NODELABEL(n), alpha, bus) // 10
234  *     DT_CLOCKS_CELL_BY_NAME(DT_NODELABEL(n), beta, bits) // 40
235  *
236  * @param node_id node identifier for a node with a clocks property
237  * @param name lowercase-and-underscores name of a clocks element
238  *             as defined by the node's clock-names property
239  * @param cell lowercase-and-underscores cell name
240  * @return the cell value in the specifier at the named element
241  * @see DT_PHA_BY_NAME()
242  */
243 #define DT_CLOCKS_CELL_BY_NAME(node_id, name, cell) \
244 	DT_PHA_BY_NAME(node_id, clocks, name, cell)
245 
246 /**
247  * @brief Equivalent to DT_CLOCKS_CELL_BY_IDX(node_id, 0, cell)
248  * @param node_id node identifier for a node with a clocks property
249  * @param cell lowercase-and-underscores cell name
250  * @return the cell value at index 0
251  * @see DT_CLOCKS_CELL_BY_IDX()
252  */
253 #define DT_CLOCKS_CELL(node_id, cell) DT_CLOCKS_CELL_BY_IDX(node_id, 0, cell)
254 
255 /**
256  * @brief Equivalent to DT_CLOCKS_HAS_IDX(DT_DRV_INST(inst), idx)
257  * @param inst DT_DRV_COMPAT instance number; may or may not have any clocks property
258  * @param idx index of a clocks property phandle-array whose existence to check
259  * @return 1 if the index exists, 0 otherwise
260  */
261 #define DT_INST_CLOCKS_HAS_IDX(inst, idx) \
262 	DT_CLOCKS_HAS_IDX(DT_DRV_INST(inst), idx)
263 
264 /**
265  * @brief Equivalent to DT_CLOCK_HAS_NAME(DT_DRV_INST(inst), name)
266  * @param inst DT_DRV_COMPAT instance number; may or may not have any clock-names property.
267  * @param name lowercase-and-underscores clock-names cell value name to check
268  * @return 1 if the clock name exists, 0 otherwise
269  */
270 #define DT_INST_CLOCKS_HAS_NAME(inst, name) \
271 	DT_CLOCKS_HAS_NAME(DT_DRV_INST(inst), name)
272 
273 /**
274  * @brief Equivalent to DT_NUM_CLOCKS(DT_DRV_INST(inst))
275  * @param inst instance number
276  * @return number of elements in the clocks property
277  */
278 #define DT_INST_NUM_CLOCKS(inst) \
279 	DT_NUM_CLOCKS(DT_DRV_INST(inst))
280 
281 /**
282  * @brief Get the node identifier for the controller phandle from a
283  *        "clocks" phandle-array property at an index
284  *
285  * @param inst instance number
286  * @param idx logical index into "clocks"
287  * @return the node identifier for the clock controller referenced at
288  *         index "idx"
289  * @see DT_CLOCKS_CTLR_BY_IDX()
290  */
291 #define DT_INST_CLOCKS_CTLR_BY_IDX(inst, idx) \
292 	DT_CLOCKS_CTLR_BY_IDX(DT_DRV_INST(inst), idx)
293 
294 /**
295  * @brief Equivalent to DT_INST_CLOCKS_CTLR_BY_IDX(inst, 0)
296  * @param inst instance number
297  * @return a node identifier for the clocks controller at index 0
298  *         in "clocks"
299  * @see DT_CLOCKS_CTLR()
300  */
301 #define DT_INST_CLOCKS_CTLR(inst) DT_INST_CLOCKS_CTLR_BY_IDX(inst, 0)
302 
303 /**
304  * @brief Get the node identifier for the controller phandle from a
305  *        clocks phandle-array property by name
306  *
307  * @param inst instance number
308  * @param name lowercase-and-underscores name of a clocks element
309  *             as defined by the node's clock-names property
310  * @return the node identifier for the clock controller referenced by
311  *         the named element
312  * @see DT_CLOCKS_CTLR_BY_NAME()
313  */
314 #define DT_INST_CLOCKS_CTLR_BY_NAME(inst, name) \
315 	DT_CLOCKS_CTLR_BY_NAME(DT_DRV_INST(inst), name)
316 
317 /**
318  * @brief Get a DT_DRV_COMPAT instance's clock specifier's cell value
319  *        at an index
320  * @param inst DT_DRV_COMPAT instance number
321  * @param idx logical index into clocks property
322  * @param cell lowercase-and-underscores cell name
323  * @return the cell value at index "idx"
324  * @see DT_CLOCKS_CELL_BY_IDX()
325  */
326 #define DT_INST_CLOCKS_CELL_BY_IDX(inst, idx, cell) \
327 	DT_CLOCKS_CELL_BY_IDX(DT_DRV_INST(inst), idx, cell)
328 
329 /**
330  * @brief Get a DT_DRV_COMPAT instance's clock specifier's cell value by name
331  * @param inst DT_DRV_COMPAT instance number
332  * @param name lowercase-and-underscores name of a clocks element
333  *             as defined by the node's clock-names property
334  * @param cell lowercase-and-underscores cell name
335  * @return the cell value in the specifier at the named element
336  * @see DT_CLOCKS_CELL_BY_NAME()
337  */
338 #define DT_INST_CLOCKS_CELL_BY_NAME(inst, name, cell) \
339 	DT_CLOCKS_CELL_BY_NAME(DT_DRV_INST(inst), name, cell)
340 
341 /**
342  * @brief Equivalent to DT_INST_CLOCKS_CELL_BY_IDX(inst, 0, cell)
343  * @param inst DT_DRV_COMPAT instance number
344  * @param cell lowercase-and-underscores cell name
345  * @return the value of the cell inside the specifier at index 0
346  */
347 #define DT_INST_CLOCKS_CELL(inst, cell) \
348 	DT_INST_CLOCKS_CELL_BY_IDX(inst, 0, cell)
349 
350 /**
351  * @}
352  */
353 
354 #ifdef __cplusplus
355 }
356 #endif
357 
358 #endif  /* ZEPHYR_INCLUDE_DEVICETREE_CLOCKS_H_ */
359