LCOV - code coverage report
Current view: top level - zephyr/drivers - clock_control.h Hit Total Coverage
Test: new.info Lines: 11 26 42.3 %
Date: 2024-12-22 00:14:23

          Line data    Source code
       1           1 : /* clock_control.h - public clock controller driver API */
       2             : 
       3             : /*
       4             :  * Copyright (c) 2015 Intel Corporation
       5             :  *
       6             :  * SPDX-License-Identifier: Apache-2.0
       7             :  */
       8             : 
       9             : /**
      10             :  * @file
      11             :  * @brief Public Clock Control APIs
      12             :  */
      13             : 
      14             : #ifndef ZEPHYR_INCLUDE_DRIVERS_CLOCK_CONTROL_H_
      15             : #define ZEPHYR_INCLUDE_DRIVERS_CLOCK_CONTROL_H_
      16             : 
      17             : /**
      18             :  * @brief Clock Control Interface
      19             :  * @defgroup clock_control_interface Clock Control Interface
      20             :  * @since 1.0
      21             :  * @version 1.0.0
      22             :  * @ingroup io_interfaces
      23             :  * @{
      24             :  */
      25             : 
      26             : #include <errno.h>
      27             : #include <stddef.h>
      28             : 
      29             : #include <zephyr/types.h>
      30             : #include <zephyr/device.h>
      31             : #include <zephyr/sys/__assert.h>
      32             : #include <zephyr/sys/slist.h>
      33             : 
      34             : #ifdef __cplusplus
      35             : extern "C" {
      36             : #endif
      37             : 
      38             : /* Clock control API */
      39             : 
      40             : /* Used to select all subsystem of a clock controller */
      41           0 : #define CLOCK_CONTROL_SUBSYS_ALL        NULL
      42             : 
      43             : /**
      44             :  * @brief Current clock status.
      45             :  */
      46           0 : enum clock_control_status {
      47             :         CLOCK_CONTROL_STATUS_STARTING,
      48             :         CLOCK_CONTROL_STATUS_OFF,
      49             :         CLOCK_CONTROL_STATUS_ON,
      50             :         CLOCK_CONTROL_STATUS_UNKNOWN
      51             : };
      52             : 
      53             : /**
      54             :  * clock_control_subsys_t is a type to identify a clock controller sub-system.
      55             :  * Such data pointed is opaque and relevant only to the clock controller
      56             :  * driver instance being used.
      57             :  */
      58           1 : typedef void *clock_control_subsys_t;
      59             : 
      60             : /**
      61             :  * clock_control_subsys_rate_t is a type to identify a clock
      62             :  * controller sub-system rate.  Such data pointed is opaque and
      63             :  * relevant only to set the clock controller rate of the driver
      64             :  * instance being used.
      65             :  */
      66           1 : typedef void *clock_control_subsys_rate_t;
      67             : 
      68             : /** @brief Callback called on clock started.
      69             :  *
      70             :  * @param dev           Device structure whose driver controls the clock.
      71             :  * @param subsys        Opaque data representing the clock.
      72             :  * @param user_data     User data.
      73             :  */
      74           1 : typedef void (*clock_control_cb_t)(const struct device *dev,
      75             :                                    clock_control_subsys_t subsys,
      76             :                                    void *user_data);
      77             : 
      78           0 : typedef int (*clock_control)(const struct device *dev,
      79             :                              clock_control_subsys_t sys);
      80             : 
      81           0 : typedef int (*clock_control_get)(const struct device *dev,
      82             :                                  clock_control_subsys_t sys,
      83             :                                  uint32_t *rate);
      84             : 
      85           0 : typedef int (*clock_control_async_on_fn)(const struct device *dev,
      86             :                                          clock_control_subsys_t sys,
      87             :                                          clock_control_cb_t cb,
      88             :                                          void *user_data);
      89             : 
      90             : typedef enum clock_control_status (*clock_control_get_status_fn)(
      91             :                                                     const struct device *dev,
      92             :                                                     clock_control_subsys_t sys);
      93             : 
      94           0 : typedef int (*clock_control_set)(const struct device *dev,
      95             :                                  clock_control_subsys_t sys,
      96             :                                  clock_control_subsys_rate_t rate);
      97             : 
      98           0 : typedef int (*clock_control_configure_fn)(const struct device *dev,
      99             :                                           clock_control_subsys_t sys,
     100             :                                           void *data);
     101             : 
     102           0 : __subsystem struct clock_control_driver_api {
     103           0 :         clock_control                   on;
     104           0 :         clock_control                   off;
     105           0 :         clock_control_async_on_fn       async_on;
     106           0 :         clock_control_get               get_rate;
     107           0 :         clock_control_get_status_fn     get_status;
     108           0 :         clock_control_set               set_rate;
     109           0 :         clock_control_configure_fn      configure;
     110             : };
     111             : 
     112             : /**
     113             :  * @brief Enable a clock controlled by the device
     114             :  *
     115             :  * On success, the clock is enabled and ready when this function
     116             :  * returns. This function may sleep, and thus can only be called from
     117             :  * thread context.
     118             :  *
     119             :  * Use @ref clock_control_async_on() for non-blocking operation.
     120             :  *
     121             :  * @param dev Device structure whose driver controls the clock.
     122             :  * @param sys Opaque data representing the clock.
     123             :  * @return 0 on success, negative errno on failure.
     124             :  */
     125           1 : static inline int clock_control_on(const struct device *dev,
     126             :                                    clock_control_subsys_t sys)
     127             : {
     128             :         const struct clock_control_driver_api *api =
     129             :                 (const struct clock_control_driver_api *)dev->api;
     130             : 
     131             :         return api->on(dev, sys);
     132             : }
     133             : 
     134             : /**
     135             :  * @brief Disable a clock controlled by the device
     136             :  *
     137             :  * This function is non-blocking and can be called from any context.
     138             :  * On success, the clock is disabled when this function returns.
     139             :  *
     140             :  * @param dev Device structure whose driver controls the clock
     141             :  * @param sys Opaque data representing the clock
     142             :  * @return 0 on success, negative errno on failure.
     143             :  */
     144           1 : static inline int clock_control_off(const struct device *dev,
     145             :                                     clock_control_subsys_t sys)
     146             : {
     147             :         const struct clock_control_driver_api *api =
     148             :                 (const struct clock_control_driver_api *)dev->api;
     149             : 
     150             :         return api->off(dev, sys);
     151             : }
     152             : 
     153             : /**
     154             :  * @brief Request clock to start with notification when clock has been started.
     155             :  *
     156             :  * Function is non-blocking and can be called from any context. User callback is
     157             :  * called when clock is started.
     158             :  *
     159             :  * @param dev       Device.
     160             :  * @param sys       A pointer to an opaque data representing the sub-system.
     161             :  * @param cb        Callback.
     162             :  * @param user_data User context passed to the callback.
     163             :  *
     164             :  * @retval 0 if start is successfully initiated.
     165             :  * @retval -EALREADY if clock was already started and is starting or running.
     166             :  * @retval -ENOTSUP If the requested mode of operation is not supported.
     167             :  * @retval -ENOSYS if the interface is not implemented.
     168             :  * @retval other negative errno on vendor specific error.
     169             :  */
     170           1 : static inline int clock_control_async_on(const struct device *dev,
     171             :                                          clock_control_subsys_t sys,
     172             :                                          clock_control_cb_t cb,
     173             :                                          void *user_data)
     174             : {
     175             :         const struct clock_control_driver_api *api =
     176             :                 (const struct clock_control_driver_api *)dev->api;
     177             : 
     178             :         if (api->async_on == NULL) {
     179             :                 return -ENOSYS;
     180             :         }
     181             : 
     182             :         return api->async_on(dev, sys, cb, user_data);
     183             : }
     184             : 
     185             : /**
     186             :  * @brief Get clock status.
     187             :  *
     188             :  * @param dev Device.
     189             :  * @param sys A pointer to an opaque data representing the sub-system.
     190             :  *
     191             :  * @return Status.
     192             :  */
     193           1 : static inline enum clock_control_status clock_control_get_status(const struct device *dev,
     194             :                                                                  clock_control_subsys_t sys)
     195             : {
     196             :         const struct clock_control_driver_api *api =
     197             :                 (const struct clock_control_driver_api *)dev->api;
     198             : 
     199             :         if (!api->get_status) {
     200             :                 return CLOCK_CONTROL_STATUS_UNKNOWN;
     201             :         }
     202             : 
     203             :         return api->get_status(dev, sys);
     204             : }
     205             : 
     206             : /**
     207             :  * @brief Obtain the clock rate of given sub-system
     208             :  * @param dev Pointer to the device structure for the clock controller driver
     209             :  *        instance
     210             :  * @param sys A pointer to an opaque data representing the sub-system
     211             :  * @param[out] rate Subsystem clock rate
     212             :  * @retval 0 on successful rate reading.
     213             :  * @retval -EAGAIN if rate cannot be read. Some drivers do not support returning the rate when the
     214             :  *         clock is off.
     215             :  * @retval -ENOTSUP if reading the clock rate is not supported for the given sub-system.
     216             :  * @retval -ENOSYS if the interface is not implemented.
     217             :  */
     218           1 : static inline int clock_control_get_rate(const struct device *dev,
     219             :                                          clock_control_subsys_t sys,
     220             :                                          uint32_t *rate)
     221             : {
     222             :         const struct clock_control_driver_api *api =
     223             :                 (const struct clock_control_driver_api *)dev->api;
     224             : 
     225             :         if (api->get_rate == NULL) {
     226             :                 return -ENOSYS;
     227             :         }
     228             : 
     229             :         return api->get_rate(dev, sys, rate);
     230             : }
     231             : 
     232             : /**
     233             :  * @brief Set the rate of the clock controlled by the device.
     234             :  *
     235             :  * On success, the new clock rate is set and ready when this function
     236             :  * returns. This function may sleep, and thus can only be called from
     237             :  * thread context.
     238             :  *
     239             :  * @param dev Device structure whose driver controls the clock.
     240             :  * @param sys Opaque data representing the clock.
     241             :  * @param rate Opaque data representing the clock rate to be used.
     242             :  *
     243             :  * @retval -EALREADY if clock was already in the given rate.
     244             :  * @retval -ENOTSUP If the requested mode of operation is not supported.
     245             :  * @retval -ENOSYS if the interface is not implemented.
     246             :  * @retval other negative errno on vendor specific error.
     247             :  */
     248           1 : static inline int clock_control_set_rate(const struct device *dev,
     249             :                 clock_control_subsys_t sys,
     250             :                 clock_control_subsys_rate_t rate)
     251             : {
     252             :         const struct clock_control_driver_api *api =
     253             :                 (const struct clock_control_driver_api *)dev->api;
     254             : 
     255             :         if (api->set_rate == NULL) {
     256             :                 return -ENOSYS;
     257             :         }
     258             : 
     259             :         return api->set_rate(dev, sys, rate);
     260             : }
     261             : 
     262             : /**
     263             :  * @brief Configure a source clock
     264             :  *
     265             :  * This function is non-blocking and can be called from any context.
     266             :  * On success, the selected clock is configured as per caller's request.
     267             :  *
     268             :  * It is caller's responsibility to ensure that subsequent calls to the API
     269             :  * provide the right information to allows clock_control driver to perform
     270             :  * the right action (such as using the right clock source on clock_control_get_rate
     271             :  * call).
     272             :  *
     273             :  * @p data is implementation specific and could be used to convey
     274             :  * supplementary information required for expected clock configuration.
     275             :  *
     276             :  * @param dev Device structure whose driver controls the clock
     277             :  * @param sys Opaque data representing the clock
     278             :  * @param data Opaque data providing additional input for clock configuration
     279             :  *
     280             :  * @retval 0 On success
     281             :  * @retval -ENOSYS If the device driver does not implement this call
     282             :  * @retval -errno Other negative errno on failure.
     283             :  */
     284           1 : static inline int clock_control_configure(const struct device *dev,
     285             :                                           clock_control_subsys_t sys,
     286             :                                           void *data)
     287             : {
     288             :         const struct clock_control_driver_api *api =
     289             :                 (const struct clock_control_driver_api *)dev->api;
     290             : 
     291             :         if (api->configure == NULL) {
     292             :                 return -ENOSYS;
     293             :         }
     294             : 
     295             :         return api->configure(dev, sys, data);
     296             : }
     297             : 
     298             : #ifdef __cplusplus
     299             : }
     300             : #endif
     301             : 
     302             : /**
     303             :  * @}
     304             :  */
     305             : 
     306             : #endif /* ZEPHYR_INCLUDE_DRIVERS_CLOCK_CONTROL_H_ */

Generated by: LCOV version 1.14