1 /*
2  * Copyright (c) 2021 Nordic Semiconductor ASA
3  * SPDX-License-Identifier: Apache-2.0
4  */
5 
6 #ifndef ZEPHYR_INCLUDE_DEVICETREE_PINCTRL_H_
7 #define ZEPHYR_INCLUDE_DEVICETREE_PINCTRL_H_
8 
9 /**
10  * @file
11  * @brief Devicetree pin control helpers
12  */
13 
14 /**
15  * @defgroup devicetree-pinctrl Pin control
16  * @ingroup devicetree
17  * @{
18  */
19 
20 /**
21  * @brief Get a node identifier for a phandle in a pinctrl property by index
22  *
23  * Example devicetree fragment:
24  *
25  *     n: node {
26  *             pinctrl-0 = <&foo &bar>;
27  *             pinctrl-1 = <&baz &blub>;
28  *     }
29  *
30  * Example usage:
31  *
32  *     DT_PINCTRL_BY_IDX(DT_NODELABEL(n), 0, 1) // DT_NODELABEL(bar)
33  *     DT_PINCTRL_BY_IDX(DT_NODELABEL(n), 1, 0) // DT_NODELABEL(baz)
34  *
35  * @param node_id node with a pinctrl-'pc_idx' property
36  * @param pc_idx index of the pinctrl property itself
37  * @param idx index into the value of the pinctrl property
38  * @return node identifier for the phandle at index 'idx' in 'pinctrl-'pc_idx''
39  */
40 #define DT_PINCTRL_BY_IDX(node_id, pc_idx, idx) \
41 	DT_CAT6(node_id, _P_pinctrl_, pc_idx, _IDX_, idx, _PH)
42 
43 /**
44  * @brief Get a node identifier from a pinctrl-0 property
45  *
46  * This is equivalent to:
47  *
48  *     DT_PINCTRL_BY_IDX(node_id, 0, idx)
49  *
50  * It is provided for convenience since pinctrl-0 is commonly used.
51  *
52  * @param node_id node with a pinctrl-0 property
53  * @param idx index into the pinctrl-0 property
54  * @return node identifier for the phandle at index idx in the pinctrl-0
55  *         property of that node
56  */
57 #define DT_PINCTRL_0(node_id, idx) DT_PINCTRL_BY_IDX(node_id, 0, idx)
58 
59 /**
60  * @brief Get a node identifier for a phandle inside a pinctrl node by name
61  *
62  * Example devicetree fragment:
63  *
64  *     n: node {
65  *             pinctrl-0 = <&foo &bar>;
66  *             pinctrl-1 = <&baz &blub>;
67  *             pinctrl-names = "default", "sleep";
68  *     };
69  *
70  * Example usage:
71  *
72  *     DT_PINCTRL_BY_NAME(DT_NODELABEL(n), default, 1) // DT_NODELABEL(bar)
73  *     DT_PINCTRL_BY_NAME(DT_NODELABEL(n), sleep, 0) // DT_NODELABEL(baz)
74  *
75  * @param node_id node with a named pinctrl property
76  * @param name lowercase-and-underscores pinctrl property name
77  * @param idx index into the value of the named pinctrl property
78  * @return node identifier for the phandle at that index in the pinctrl
79  *         property
80  */
81 #define DT_PINCTRL_BY_NAME(node_id, name, idx) \
82 	DT_CAT6(node_id, _PINCTRL_NAME_, name, _IDX_, idx, _PH)
83 
84 /**
85  * @brief Convert a pinctrl name to its corresponding index
86  *
87  * Example devicetree fragment:
88  *
89  *     n: node {
90  *             pinctrl-0 = <&foo &bar>;
91  *             pinctrl-1 = <&baz &blub>;
92  *             pinctrl-names = "default", "sleep";
93  *     };
94  *
95  * Example usage:
96  *
97  *     DT_PINCTRL_NAME_TO_IDX(DT_NODELABEL(n), default) // 0
98  *     DT_PINCTRL_NAME_TO_IDX(DT_NODELABEL(n), sleep)   // 1
99  *
100  * @param node_id node identifier with a named pinctrl property
101  * @param name lowercase-and-underscores name name of the pinctrl whose index to get
102  * @return integer literal for the index of the pinctrl property with that name
103  */
104 #define DT_PINCTRL_NAME_TO_IDX(node_id, name) \
105 	DT_CAT4(node_id, _PINCTRL_NAME_, name, _IDX)
106 
107 /**
108  * @brief Convert a pinctrl property index to its name as a token
109  *
110  * This allows you to get a pinctrl property's name, and "remove the
111  * quotes" from it.
112  *
113  * DT_PINCTRL_IDX_TO_NAME_TOKEN() can only be used if the node has a
114  * pinctrl-'pc_idx' property and a pinctrl-names property element for
115  * that index. It is an error to use it in other circumstances.
116  *
117  * Example devicetree fragment:
118  *
119  *     n: node {
120  *             pinctrl-0 = <...>;
121  *             pinctrl-1 = <...>;
122  *             pinctrl-names = "default", "f.o.o2";
123  *     };
124  *
125  * Example usage:
126  *
127  *     DT_PINCTRL_IDX_TO_NAME_TOKEN(DT_NODELABEL(n), 0) // default
128  *     DT_PINCTRL_IDX_TO_NAME_TOKEN(DT_NODELABEL(n), 1) // f_o_o2
129  *
130  * The same caveats and restrictions that apply to DT_STRING_TOKEN()'s
131  * return value also apply here.
132  *
133  * @param node_id node identifier
134  * @param pc_idx index of a pinctrl property in that node
135  * @return name of the pinctrl property, as a token, without any quotes
136  *         and with non-alphanumeric characters converted to underscores
137  */
138 #define DT_PINCTRL_IDX_TO_NAME_TOKEN(node_id, pc_idx) \
139 	DT_CAT4(node_id, _PINCTRL_IDX_, pc_idx, _TOKEN)
140 
141 /**
142  * @brief Like DT_PINCTRL_IDX_TO_NAME_TOKEN(), but with an uppercased result
143  *
144  * This does the a similar conversion as
145  * DT_PINCTRL_IDX_TO_NAME_TOKEN(node_id, pc_idx). The only difference
146  * is that alphabetical characters in the result are uppercased.
147  *
148  * Example devicetree fragment:
149  *
150  *     n: node {
151  *             pinctrl-0 = <...>;
152  *             pinctrl-1 = <...>;
153  *             pinctrl-names = "default", "f.o.o2";
154  *     };
155  *
156  * Example usage:
157  *
158  *     DT_PINCTRL_IDX_TO_NAME_TOKEN(DT_NODELABEL(n), 0) // DEFAULT
159  *     DT_PINCTRL_IDX_TO_NAME_TOKEN(DT_NODELABEL(n), 1) // F_O_O2
160  *
161  * The same caveats and restrictions that apply to
162  * DT_STRING_UPPER_TOKEN()'s return value also apply here.
163  */
164 #define DT_PINCTRL_IDX_TO_NAME_UPPER_TOKEN(node_id, pc_idx) \
165 	DT_CAT4(node_id, _PINCTRL_IDX_, pc_idx, _UPPER_TOKEN)
166 
167 /**
168  * @brief Get the number of phandles in a pinctrl property
169  *
170  * Example devicetree fragment:
171  *
172  *     n1: node-1 {
173  *             pinctrl-0 = <&foo &bar>;
174  *     };
175  *
176  *     n2: node-2 {
177  *             pinctrl-0 = <&baz>;
178  *     };
179  *
180  * Example usage:
181  *
182  *     DT_NUM_PINCTRLS_BY_IDX(DT_NODELABEL(n1), 0) // 2
183  *     DT_NUM_PINCTRLS_BY_IDX(DT_NODELABEL(n2), 0) // 1
184  *
185  * @param node_id node identifier with a pinctrl property
186  * @param pc_idx index of the pinctrl property itself
187  * @return number of phandles in the property with that index
188  */
189 #define DT_NUM_PINCTRLS_BY_IDX(node_id, pc_idx) \
190 	DT_CAT4(node_id, _P_pinctrl_, pc_idx, _LEN)
191 
192 /**
193  * @brief Like DT_NUM_PINCTRLS_BY_IDX(), but by name instead
194  *
195  * Example devicetree fragment:
196  *
197  *     n: node {
198  *             pinctrl-0 = <&foo &bar>;
199  *             pinctrl-1 = <&baz>
200  *             pinctrl-names = "default", "sleep";
201  *     };
202  *
203  * Example usage:
204  *
205  *     DT_NUM_PINCTRLS_BY_NAME(DT_NODELABEL(n), default) // 2
206  *     DT_NUM_PINCTRLS_BY_NAME(DT_NODELABEL(n), sleep)   // 1
207  *
208  * @param node_id node identifier with a pinctrl property
209  * @param name lowercase-and-underscores name name of the pinctrl property
210  * @return number of phandles in the property with that name
211  */
212 #define DT_NUM_PINCTRLS_BY_NAME(node_id, name) \
213 	DT_NUM_PINCTRLS_BY_IDX(node_id, DT_PINCTRL_NAME_TO_IDX(node_id, name))
214 
215 /**
216  * @brief Get the number of pinctrl properties in a node
217  *
218  * This expands to 0 if there are no pinctrl-i properties.
219  * Otherwise, it expands to the number of such properties.
220  *
221  * Example devicetree fragment:
222  *
223  *     n1: node-1 {
224  *             pinctrl-0 = <...>;
225  *             pinctrl-1 = <...>;
226  *     };
227  *
228  *     n2: node-2 {
229  *     };
230  *
231  * Example usage:
232  *
233  *     DT_NUM_PINCTRL_STATES(DT_NODELABEL(n1)) // 2
234  *     DT_NUM_PINCTRL_STATES(DT_NODELABEL(n2)) // 0
235  *
236  * @param node_id node identifier; may or may not have any pinctrl properties
237  * @return number of pinctrl properties in the node
238  */
239 #define DT_NUM_PINCTRL_STATES(node_id) DT_CAT(node_id, _PINCTRL_NUM)
240 
241 /**
242  * @brief Test if a node has a pinctrl property with an index
243  *
244  * This expands to 1 if the pinctrl-'idx' property exists.
245  * Otherwise, it expands to 0.
246  *
247  * Example devicetree fragment:
248  *
249  *     n1: node-1 {
250  *             pinctrl-0 = <...>;
251  *             pinctrl-1 = <...>;
252  *     };
253  *
254  *     n2: node-2 {
255  *     };
256  *
257  * Example usage:
258  *
259  *     DT_PINCTRL_HAS_IDX(DT_NODELABEL(n1), 0) // 1
260  *     DT_PINCTRL_HAS_IDX(DT_NODELABEL(n1), 1) // 1
261  *     DT_PINCTRL_HAS_IDX(DT_NODELABEL(n1), 2) // 0
262  *     DT_PINCTRL_HAS_IDX(DT_NODELABEL(n2), 0) // 0
263  *
264  * @param node_id node identifier; may or may not have any pinctrl properties
265  * @param pc_idx index of a pinctrl property whose existence to check
266  * @return 1 if the property exists, 0 otherwise
267  */
268 #define DT_PINCTRL_HAS_IDX(node_id, pc_idx) \
269 	IS_ENABLED(DT_CAT4(node_id, _PINCTRL_IDX_, pc_idx, _EXISTS))
270 
271 /**
272  * @brief Test if a node has a pinctrl property with a name
273  *
274  * This expands to 1 if the named pinctrl property exists.
275  * Otherwise, it expands to 0.
276  *
277  * Example devicetree fragment:
278  *
279  *     n1: node-1 {
280  *             pinctrl-0 = <...>;
281  *             pinctrl-names = "default";
282  *     };
283  *
284  *     n2: node-2 {
285  *     };
286  *
287  * Example usage:
288  *
289  *     DT_PINCTRL_HAS_NAME(DT_NODELABEL(n1), default) // 1
290  *     DT_PINCTRL_HAS_NAME(DT_NODELABEL(n1), sleep)   // 0
291  *     DT_PINCTRL_HAS_NAME(DT_NODELABEL(n2), default) // 0
292  *
293  * @param node_id node identifier; may or may not have any pinctrl properties
294  * @param name lowercase-and-underscores pinctrl property name to check
295  * @return 1 if the property exists, 0 otherwise
296  */
297 #define DT_PINCTRL_HAS_NAME(node_id, name) \
298 	IS_ENABLED(DT_CAT4(node_id, _PINCTRL_NAME_, name, _EXISTS))
299 
300 /**
301  * @brief Get a node identifier for a phandle in a pinctrl property by index
302  *        for a DT_DRV_COMPAT instance
303  *
304  * This is equivalent to DT_PINCTRL_BY_IDX(DT_DRV_INST(inst), pc_idx, idx).
305  *
306  * @param inst instance number
307  * @param pc_idx index of the pinctrl property itself
308  * @param idx index into the value of the pinctrl property
309  * @return node identifier for the phandle at index 'idx' in 'pinctrl-'pc_idx''
310  */
311 #define DT_INST_PINCTRL_BY_IDX(inst, pc_idx, idx) \
312 	DT_PINCTRL_BY_IDX(DT_DRV_INST(inst), pc_idx, idx)
313 
314 /**
315  * @brief Get a node identifier from a pinctrl-0 property for a
316  *        DT_DRV_COMPAT instance
317  *
318  * This is equivalent to:
319  *
320  *     DT_PINCTRL_BY_IDX(DT_DRV_INST(inst), 0, idx)
321  *
322  * It is provided for convenience since pinctrl-0 is commonly used.
323  *
324  * @param inst instance number
325  * @param idx index into the pinctrl-0 property
326  * @return node identifier for the phandle at index idx in the pinctrl-0
327  *         property of that instance
328  */
329 #define DT_INST_PINCTRL_0(inst, idx) \
330 	DT_PINCTRL_BY_IDX(DT_DRV_INST(inst), 0, idx)
331 
332 /**
333  * @brief Get a node identifier for a phandle inside a pinctrl node
334  *        for a DT_DRV_COMPAT instance
335  *
336  * This is equivalent to DT_PINCTRL_BY_NAME(DT_DRV_INST(inst), name, idx).
337  *
338  * @param inst instance number
339  * @param name lowercase-and-underscores pinctrl property name
340  * @param idx index into the value of the named pinctrl property
341  * @return node identifier for the phandle at that index in the pinctrl
342  *         property
343  */
344 #define DT_INST_PINCTRL_BY_NAME(inst, name, idx) \
345 	DT_PINCTRL_BY_NAME(DT_DRV_INST(inst), name, idx)
346 
347 /**
348  * @brief Convert a pinctrl name to its corresponding index
349  *        for a DT_DRV_COMPAT instance
350  *
351  * This is equivalent to DT_PINCTRL_NAME_TO_IDX(DT_DRV_INST(inst),
352  * name).
353  *
354  * @param inst instance number
355  * @param name lowercase-and-underscores name of the pinctrl whose index to get
356  * @return integer literal for the index of the pinctrl property with that name
357  */
358 #define DT_INST_PINCTRL_NAME_TO_IDX(inst, name) \
359 	DT_PINCTRL_NAME_TO_IDX(DT_DRV_INST(inst), name)
360 
361 /**
362  * @brief Convert a pinctrl index to its name as an uppercased token
363  *
364  * This is equivalent to
365  * DT_PINCTRL_IDX_TO_NAME_TOKEN(DT_DRV_INST(inst), pc_idx).
366  *
367  * @param inst instance number
368  * @param pc_idx index of the pinctrl property itself
369  * @return name of the pin control property as a token
370  */
371 #define DT_INST_PINCTRL_IDX_TO_NAME_TOKEN(inst, pc_idx) \
372 	DT_PINCTRL_IDX_TO_NAME_TOKEN(DT_DRV_INST(inst), pc_idx)
373 
374 /**
375  * @brief Convert a pinctrl index to its name as an uppercased token
376  *
377  * This is equivalent to
378  * DT_PINCTRL_IDX_TO_NAME_UPPER_TOKEN(DT_DRV_INST(inst), idx).
379  *
380  * @param inst instance number
381  * @param pc_idx index of the pinctrl property itself
382  * @return name of the pin control property as an uppercase token
383  */
384 #define DT_INST_PINCTRL_IDX_TO_NAME_UPPER_TOKEN(inst, pc_idx) \
385 	DT_PINCTRL_IDX_TO_NAME_UPPER_TOKEN(DT_DRV_INST(inst), pc_idx)
386 
387 /**
388  * @brief Get the number of phandles in a pinctrl property
389  *        for a DT_DRV_COMPAT instance
390  *
391  * This is equivalent to DT_NUM_PINCTRLS_BY_IDX(DT_DRV_INST(inst),
392  * pc_idx).
393  *
394  * @param inst instance number
395  * @param pc_idx index of the pinctrl property itself
396  * @return number of phandles in the property with that index
397  */
398 #define DT_INST_NUM_PINCTRLS_BY_IDX(inst, pc_idx) \
399 	DT_NUM_PINCTRLS_BY_IDX(DT_DRV_INST(inst), pc_idx)
400 
401 /**
402  * @brief Like DT_INST_NUM_PINCTRLS_BY_IDX(), but by name instead
403  *
404  * This is equivalent to DT_NUM_PINCTRLS_BY_NAME(DT_DRV_INST(inst),
405  * name).
406  *
407  * @param inst instance number
408  * @param name lowercase-and-underscores name of the pinctrl property
409  * @return number of phandles in the property with that name
410  */
411 #define DT_INST_NUM_PINCTRLS_BY_NAME(inst, name) \
412 	DT_NUM_PINCTRLS_BY_NAME(DT_DRV_INST(inst), name)
413 
414 /**
415  * @brief Get the number of pinctrl properties in a DT_DRV_COMPAT instance
416  *
417  * This is equivalent to DT_NUM_PINCTRL_STATES(DT_DRV_INST(inst)).
418  *
419  * @param inst instance number
420  * @return number of pinctrl properties in the instance
421  */
422 #define DT_INST_NUM_PINCTRL_STATES(inst) \
423 	DT_NUM_PINCTRL_STATES(DT_DRV_INST(inst))
424 
425 /**
426  * @brief Test if a DT_DRV_COMPAT instance has a pinctrl property
427  *        with an index
428  *
429  * This is equivalent to DT_PINCTRL_HAS_IDX(DT_DRV_INST(inst), pc_idx).
430  *
431  * @param inst instance number
432  * @param pc_idx index of a pinctrl property whose existence to check
433  * @return 1 if the property exists, 0 otherwise
434  */
435 #define DT_INST_PINCTRL_HAS_IDX(inst, pc_idx) \
436 	DT_PINCTRL_HAS_IDX(DT_DRV_INST(inst), pc_idx)
437 
438 /**
439  * @brief Test if a DT_DRV_COMPAT instance has a pinctrl property with a name
440  *
441  * This is equivalent to DT_PINCTRL_HAS_NAME(DT_DRV_INST(inst), name).
442  *
443  * @param inst instance number
444  * @param name lowercase-and-underscores pinctrl property name to check
445  * @return 1 if the property exists, 0 otherwise
446  */
447 #define DT_INST_PINCTRL_HAS_NAME(inst, name) \
448 	DT_PINCTRL_HAS_NAME(DT_DRV_INST(inst), name)
449 
450 
451 /**
452  * @}
453  */
454 
455 #endif  /* ZEPHYR_INCLUDE_DEVICETREE_PINCTRL_H_ */
456