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