LCOV - code coverage report
Current view: top level - zephyr/drivers - pinctrl.h Hit Total Coverage
Test: new.info Lines: 25 25 100.0 %
Date: 2025-01-09 18:14:39

          Line data    Source code
       1           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           1 : #define PINCTRL_STATE_DEFAULT 0U
      43             : /** Sleep state (state used when the device is in low power mode). */
      44           1 : #define PINCTRL_STATE_SLEEP 1U
      45             : 
      46             : /** This and higher values refer to custom private states. */
      47           1 : #define PINCTRL_STATE_PRIV_START 2U
      48             : 
      49             : /** @} */
      50             : 
      51             : /** Pin control state configuration. */
      52           1 : struct pinctrl_state {
      53             :         /** Pin configurations. */
      54           1 :         const pinctrl_soc_pin_t *pins;
      55             :         /** Number of pin configurations. */
      56           1 :         uint8_t pin_cnt;
      57             :         /** State identifier (see @ref PINCTRL_STATES). */
      58           1 :         uint8_t id;
      59             : };
      60             : 
      61             : /** Pin controller configuration for a given device. */
      62           1 : 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           1 :         uintptr_t reg;
      69             : #endif /* defined(CONFIG_PINCTRL_STORE_REG) || defined(__DOXYGEN__) */
      70             :         /** List of state configurations. */
      71           1 :         const struct pinctrl_state *states;
      72             :         /** Number of state configurations. */
      73           1 :         uint8_t state_cnt;
      74             : };
      75             : 
      76             : /** Utility macro to indicate no register is used. */
      77           1 : #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             :                 .pins = Z_PINCTRL_STATE_PINS_NAME(state_idx, node_id),         \
     161             :                 .pin_cnt = ARRAY_SIZE(Z_PINCTRL_STATE_PINS_NAME(state_idx,     \
     162             :                                                                 node_id)),      \
     163             :                 .id = Z_PINCTRL_STATE_ID(state_idx, 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           1 : #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           1 : #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           1 : #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           1 : #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           1 : #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           1 : 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           1 : 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             :  */
     318           1 : 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             :  */
     344           1 : 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           1 : #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           1 : #define PINCTRL_DT_STATE_INIT(prop, state)                                     \
     416             :         {                                                                      \
     417             :                 .pins = prop ## _pins,                                         \
     418             :                 .pin_cnt = ARRAY_SIZE(prop ## _pins),                          \
     419             :                 .id = state                                                    \
     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           1 : int pinctrl_update_states(struct pinctrl_dev_config *config,
     440             :                           const struct pinctrl_state *states,
     441             :                           uint8_t state_cnt);
     442             : 
     443             : /** @} */
     444             : #else
     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_ */

Generated by: LCOV version 1.14