1 /*
2 * Copyright (c) 2021 Nordic Semiconductor ASA
3 * SPDX-License-Identifier: Apache-2.0
4 */
5
6 /**
7 * @file
8 * Public APIs for pin control drivers
9 */
10
11 #ifndef ZEPHYR_INCLUDE_DRIVERS_PINCTRL_H_
12 #define ZEPHYR_INCLUDE_DRIVERS_PINCTRL_H_
13
14 /**
15 * @brief Pin Controller Interface
16 * @defgroup pinctrl_interface Pin Controller Interface
17 * @since 3.0
18 * @version 0.1.0
19 * @ingroup io_interfaces
20 * @{
21 */
22
23 #include <errno.h>
24
25 #include <zephyr/device.h>
26 #include <zephyr/devicetree.h>
27 #include <zephyr/devicetree/pinctrl.h>
28 #include <pinctrl_soc.h>
29 #include <zephyr/sys/util.h>
30
31 #ifdef __cplusplus
32 extern "C" {
33 #endif
34
35 /**
36 * @name Pin control states
37 * @anchor PINCTRL_STATES
38 * @{
39 */
40
41 /** Default state (state used when the device is in operational state). */
42 #define PINCTRL_STATE_DEFAULT 0U
43 /** Sleep state (state used when the device is in low power mode). */
44 #define PINCTRL_STATE_SLEEP 1U
45
46 /** This and higher values refer to custom private states. */
47 #define PINCTRL_STATE_PRIV_START 2U
48
49 /** @} */
50
51 /** Pin control state configuration. */
52 struct pinctrl_state {
53 /** Pin configurations. */
54 const pinctrl_soc_pin_t *pins;
55 /** Number of pin configurations. */
56 uint8_t pin_cnt;
57 /** State identifier (see @ref PINCTRL_STATES). */
58 uint8_t id;
59 };
60
61 /** Pin controller configuration for a given device. */
62 struct pinctrl_dev_config {
63 #if defined(CONFIG_PINCTRL_STORE_REG) || defined(__DOXYGEN__)
64 /**
65 * Device address (only available if @kconfig{CONFIG_PINCTRL_STORE_REG}
66 * is enabled).
67 */
68 uintptr_t reg;
69 #endif /* defined(CONFIG_PINCTRL_STORE_REG) || defined(__DOXYGEN__) */
70 /** List of state configurations. */
71 const struct pinctrl_state *states;
72 /** Number of state configurations. */
73 uint8_t state_cnt;
74 };
75
76 /** Utility macro to indicate no register is used. */
77 #define PINCTRL_REG_NONE 0U
78
79 /** @cond INTERNAL_HIDDEN */
80
81 #if !defined(CONFIG_PM) && !defined(CONFIG_PM_DEVICE)
82 /** Out of power management configurations, ignore "sleep" state. */
83 #define PINCTRL_SKIP_SLEEP 1
84 #endif
85
86 /**
87 * @brief Obtain the state identifier for the given node and state index.
88 *
89 * @param state_idx State index.
90 * @param node_id Node identifier.
91 */
92 #define Z_PINCTRL_STATE_ID(state_idx, node_id) \
93 _CONCAT(PINCTRL_STATE_, \
94 DT_PINCTRL_IDX_TO_NAME_UPPER_TOKEN(node_id, state_idx))
95
96 /**
97 * @brief Obtain the variable name storing pinctrl config for the given DT node
98 * identifier.
99 *
100 * @param node_id Node identifier.
101 */
102 #define Z_PINCTRL_DEV_CONFIG_NAME(node_id) \
103 _CONCAT(__pinctrl_dev_config, DEVICE_DT_NAME_GET(node_id))
104
105 /**
106 * @brief Obtain the variable name storing pinctrl states for the given DT node
107 * identifier.
108 *
109 * @param node_id Node identifier.
110 */
111 #define Z_PINCTRL_STATES_NAME(node_id) \
112 _CONCAT(__pinctrl_states, DEVICE_DT_NAME_GET(node_id))
113
114 /**
115 * @brief Obtain the variable name storing pinctrl pins for the given DT node
116 * identifier and state index.
117 *
118 * @param state_idx State index.
119 * @param node_id Node identifier.
120 */
121 #define Z_PINCTRL_STATE_PINS_NAME(state_idx, node_id) \
122 _CONCAT(__pinctrl_state_pins_ ## state_idx, DEVICE_DT_NAME_GET(node_id))
123
124 /**
125 * @brief Utility macro to check if given state has to be skipped.
126 *
127 * If a certain state has to be skipped, a macro named PINCTRL_SKIP_<STATE>
128 * can be defined evaluating to 1. This can be useful, for example, to
129 * automatically ignore the sleep state if no device power management is
130 * enabled.
131 *
132 * @param state_idx State index.
133 * @param node_id Node identifier.
134 */
135 #define Z_PINCTRL_SKIP_STATE(state_idx, node_id) \
136 _CONCAT(PINCTRL_SKIP_, \
137 DT_PINCTRL_IDX_TO_NAME_UPPER_TOKEN(node_id, state_idx))
138
139 /**
140 * @brief Helper macro to define pins for a given pin control state.
141 *
142 * @param state_idx State index.
143 * @param node_id Node identifier.
144 */
145 #define Z_PINCTRL_STATE_PINS_DEFINE(state_idx, node_id) \
146 COND_CODE_1(Z_PINCTRL_SKIP_STATE(state_idx, node_id), (), \
147 (static const pinctrl_soc_pin_t \
148 Z_PINCTRL_STATE_PINS_NAME(state_idx, node_id)[] = \
149 Z_PINCTRL_STATE_PINS_INIT(node_id, pinctrl_ ## state_idx)))
150
151 /**
152 * @brief Helper macro to initialize a pin control state.
153 *
154 * @param state_idx State index.
155 * @param node_id Node identifier.
156 */
157 #define Z_PINCTRL_STATE_INIT(state_idx, node_id) \
158 COND_CODE_1(Z_PINCTRL_SKIP_STATE(state_idx, node_id), (), \
159 ({ \
160 .id = Z_PINCTRL_STATE_ID(state_idx, node_id), \
161 .pins = Z_PINCTRL_STATE_PINS_NAME(state_idx, node_id), \
162 .pin_cnt = ARRAY_SIZE(Z_PINCTRL_STATE_PINS_NAME(state_idx, \
163 node_id)) \
164 }))
165
166 /**
167 * @brief Define all the states for the given node identifier.
168 *
169 * @param node_id Node identifier.
170 */
171 #define Z_PINCTRL_STATES_DEFINE(node_id) \
172 static const struct pinctrl_state \
173 Z_PINCTRL_STATES_NAME(node_id)[] = { \
174 LISTIFY(DT_NUM_PINCTRL_STATES(node_id), \
175 Z_PINCTRL_STATE_INIT, (,), node_id) \
176 };
177
178 #ifdef CONFIG_PINCTRL_STORE_REG
179 /**
180 * @brief Helper macro to initialize pin control config.
181 *
182 * @param node_id Node identifier.
183 */
184 #define Z_PINCTRL_DEV_CONFIG_INIT(node_id) \
185 { \
186 .reg = DT_REG_ADDR(node_id), \
187 .states = Z_PINCTRL_STATES_NAME(node_id), \
188 .state_cnt = ARRAY_SIZE(Z_PINCTRL_STATES_NAME(node_id)), \
189 }
190 #else
191 #define Z_PINCTRL_DEV_CONFIG_INIT(node_id) \
192 { \
193 .states = Z_PINCTRL_STATES_NAME(node_id), \
194 .state_cnt = ARRAY_SIZE(Z_PINCTRL_STATES_NAME(node_id)), \
195 }
196 #endif
197
198 #ifdef CONFIG_PINCTRL_NON_STATIC
199 #define Z_PINCTRL_DEV_CONFIG_STATIC
200 #else
201 #define Z_PINCTRL_DEV_CONFIG_STATIC static
202 #endif
203
204 #ifdef CONFIG_PINCTRL_DYNAMIC
205 #define Z_PINCTRL_DEV_CONFIG_CONST
206 #else
207 #define Z_PINCTRL_DEV_CONFIG_CONST const
208 #endif
209
210 /** @endcond */
211
212 #if defined(CONFIG_PINCTRL_NON_STATIC) || defined(__DOXYGEN__)
213 /**
214 * @brief Declare pin control configuration for a given node identifier.
215 *
216 * This macro should be used by tests or applications using runtime pin control
217 * to declare the pin control configuration for a device.
218 * #PINCTRL_DT_DEV_CONFIG_GET can later be used to obtain a reference to such
219 * configuration.
220 *
221 * Only available if @kconfig{CONFIG_PINCTRL_NON_STATIC} is selected.
222 *
223 * @param node_id Node identifier.
224 */
225 #define PINCTRL_DT_DEV_CONFIG_DECLARE(node_id) \
226 extern Z_PINCTRL_DEV_CONFIG_CONST struct pinctrl_dev_config \
227 Z_PINCTRL_DEV_CONFIG_NAME(node_id)
228 #endif /* defined(CONFIG_PINCTRL_NON_STATIC) || defined(__DOXYGEN__) */
229
230 /**
231 * @brief Define all pin control information for the given node identifier.
232 *
233 * This helper macro should be called together with device definition. It
234 * defines and initializes the pin control configuration for the device
235 * represented by node_id. Each pin control state (pinctrl-0, ..., pinctrl-N) is
236 * also defined and initialized. Note that states marked to be skipped will not
237 * be defined (refer to Z_PINCTRL_SKIP_STATE for more details).
238 *
239 * @param node_id Node identifier.
240 */
241 #define PINCTRL_DT_DEFINE(node_id) \
242 LISTIFY(DT_NUM_PINCTRL_STATES(node_id), \
243 Z_PINCTRL_STATE_PINS_DEFINE, (;), node_id); \
244 Z_PINCTRL_STATES_DEFINE(node_id) \
245 Z_PINCTRL_DEV_CONFIG_STATIC Z_PINCTRL_DEV_CONFIG_CONST \
246 struct pinctrl_dev_config Z_PINCTRL_DEV_CONFIG_NAME(node_id) = \
247 Z_PINCTRL_DEV_CONFIG_INIT(node_id)
248
249 /**
250 * @brief Define all pin control information for the given compatible index.
251 *
252 * @param inst Instance number.
253 *
254 * @see #PINCTRL_DT_DEFINE
255 */
256 #define PINCTRL_DT_INST_DEFINE(inst) PINCTRL_DT_DEFINE(DT_DRV_INST(inst))
257
258 /**
259 * @brief Obtain a reference to the pin control configuration given a node
260 * identifier.
261 *
262 * @param node_id Node identifier.
263 */
264 #define PINCTRL_DT_DEV_CONFIG_GET(node_id) &Z_PINCTRL_DEV_CONFIG_NAME(node_id)
265
266 /**
267 * @brief Obtain a reference to the pin control configuration given current
268 * compatible instance number.
269 *
270 * @param inst Instance number.
271 *
272 * @see #PINCTRL_DT_DEV_CONFIG_GET
273 */
274 #define PINCTRL_DT_INST_DEV_CONFIG_GET(inst) \
275 PINCTRL_DT_DEV_CONFIG_GET(DT_DRV_INST(inst))
276
277 /**
278 * @brief Find the state configuration for the given state id.
279 *
280 * @param config Pin controller configuration.
281 * @param id Pin controller state id (see @ref PINCTRL_STATES).
282 * @param state Found state.
283 *
284 * @retval 0 If state has been found.
285 * @retval -ENOENT If the state has not been found.
286 */
287 int pinctrl_lookup_state(const struct pinctrl_dev_config *config, uint8_t id,
288 const struct pinctrl_state **state);
289
290 /**
291 * @brief Configure a set of pins.
292 *
293 * This function will configure the necessary hardware blocks to make the
294 * configuration immediately effective.
295 *
296 * @warning This function must never be used to configure pins used by an
297 * instantiated device driver.
298 *
299 * @param pins List of pins to be configured.
300 * @param pin_cnt Number of pins.
301 * @param reg Device register (optional, use #PINCTRL_REG_NONE if not used).
302 *
303 * @retval 0 If succeeded
304 * @retval -errno Negative errno for other failures.
305 */
306 int pinctrl_configure_pins(const pinctrl_soc_pin_t *pins, uint8_t pin_cnt,
307 uintptr_t reg);
308
309 /**
310 * @brief Apply a state directly from the provided state configuration.
311 *
312 * @param config Pin control configuration.
313 * @param state State.
314 *
315 * @retval 0 If succeeded
316 * @retval -errno Negative errno for other failures.
317 */
pinctrl_apply_state_direct(const struct pinctrl_dev_config * config,const struct pinctrl_state * state)318 static inline int pinctrl_apply_state_direct(
319 const struct pinctrl_dev_config *config,
320 const struct pinctrl_state *state)
321 {
322 uintptr_t reg;
323
324 #ifdef CONFIG_PINCTRL_STORE_REG
325 reg = config->reg;
326 #else
327 ARG_UNUSED(config);
328 reg = PINCTRL_REG_NONE;
329 #endif
330
331 return pinctrl_configure_pins(state->pins, state->pin_cnt, reg);
332 }
333
334 /**
335 * @brief Apply a state from the given device configuration.
336 *
337 * @param config Pin control configuration.
338 * @param id Id of the state to be applied (see @ref PINCTRL_STATES).
339 *
340 * @retval 0 If succeeded.
341 * @retval -ENOENT If given state id does not exist.
342 * @retval -errno Negative errno for other failures.
343 */
pinctrl_apply_state(const struct pinctrl_dev_config * config,uint8_t id)344 static inline int pinctrl_apply_state(const struct pinctrl_dev_config *config,
345 uint8_t id)
346 {
347 int ret;
348 const struct pinctrl_state *state;
349
350 ret = pinctrl_lookup_state(config, id, &state);
351 if (ret < 0) {
352 return ret;
353 }
354
355 return pinctrl_apply_state_direct(config, state);
356 }
357
358 #if defined(CONFIG_PINCTRL_DYNAMIC) || defined(__DOXYGEN__)
359 /**
360 * @defgroup pinctrl_interface_dynamic Dynamic Pin Control
361 * @{
362 */
363
364 /**
365 * @brief Helper macro to define the pins of a pin control state from
366 * Devicetree.
367 *
368 * The name of the defined state pins variable is the same used by @p prop. This
369 * macro is expected to be used in conjunction with #PINCTRL_DT_STATE_INIT.
370 *
371 * @param node_id Node identifier containing @p prop.
372 * @param prop Property within @p node_id containing state configuration.
373 *
374 * @see #PINCTRL_DT_STATE_INIT
375 */
376 #define PINCTRL_DT_STATE_PINS_DEFINE(node_id, prop) \
377 static const pinctrl_soc_pin_t prop ## _pins[] = \
378 Z_PINCTRL_STATE_PINS_INIT(node_id, prop); \
379
380 /**
381 * @brief Utility macro to initialize a pin control state.
382 *
383 * This macro should be used in conjunction with #PINCTRL_DT_STATE_PINS_DEFINE
384 * when using dynamic pin control to define an alternative state configuration
385 * stored in Devicetree.
386 *
387 * Example:
388 *
389 * @code{.devicetree}
390 * // board.dts
391 *
392 * /{
393 * zephyr,user {
394 * // uart0_alt_default node contains alternative pin config
395 * uart0_alt_default = <&uart0_alt_default>;
396 * };
397 * };
398 * @endcode
399 *
400 * @code{.c}
401 * // application
402 *
403 * PINCTRL_DT_STATE_PINS_DEFINE(DT_PATH(zephyr_user), uart0_alt_default);
404 *
405 * static const struct pinctrl_state uart0_alt[] = {
406 * PINCTRL_DT_STATE_INIT(uart0_alt_default, PINCTRL_STATE_DEFAULT)
407 * };
408 * @endcode
409 *
410 * @param prop Property name in Devicetree containing state configuration.
411 * @param state State represented by @p prop (see @ref PINCTRL_STATES).
412 *
413 * @see #PINCTRL_DT_STATE_PINS_DEFINE
414 */
415 #define PINCTRL_DT_STATE_INIT(prop, state) \
416 { \
417 .id = state, \
418 .pins = prop ## _pins, \
419 .pin_cnt = ARRAY_SIZE(prop ## _pins) \
420 }
421
422 /**
423 * @brief Update states with a new set.
424 *
425 * @note In order to guarantee device drivers correct operation the same states
426 * have to be provided. For example, if @c default and @c sleep are in the
427 * current list of states, it is expected that the new array of states also
428 * contains both.
429 *
430 * @param config Pin control configuration.
431 * @param states New states to be set.
432 * @param state_cnt Number of new states to be set.
433 *
434 * @retval -EINVAL If the new configuration does not contain the same states as
435 * the current active configuration.
436 * @retval -ENOSYS If the functionality is not available.
437 * @retval 0 On success.
438 */
439 int pinctrl_update_states(struct pinctrl_dev_config *config,
440 const struct pinctrl_state *states,
441 uint8_t state_cnt);
442
443 /** @} */
444 #else
pinctrl_update_states(struct pinctrl_dev_config * config,const struct pinctrl_state * states,uint8_t state_cnt)445 static inline int pinctrl_update_states(
446 struct pinctrl_dev_config *config,
447 const struct pinctrl_state *states, uint8_t state_cnt)
448 {
449 ARG_UNUSED(config);
450 ARG_UNUSED(states);
451 ARG_UNUSED(state_cnt);
452 return -ENOSYS;
453 }
454 #endif /* defined(CONFIG_PINCTRL_DYNAMIC) || defined(__DOXYGEN__) */
455
456 #ifdef __cplusplus
457 }
458 #endif
459
460 /**
461 * @}
462 */
463
464 #endif /* ZEPHYR_INCLUDE_DRIVERS_PINCTRL_H_ */
465