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