Line data Source code
1 0 : /* 2 : * Copyright (c) 2016 Nordic Semiconductor ASA 3 : * 4 : * SPDX-License-Identifier: Apache-2.0 5 : */ 6 : 7 : #ifndef ZEPHYR_INCLUDE_DRIVERS_CLOCK_CONTROL_NRF_CLOCK_CONTROL_H_ 8 : #define ZEPHYR_INCLUDE_DRIVERS_CLOCK_CONTROL_NRF_CLOCK_CONTROL_H_ 9 : 10 : #include <zephyr/device.h> 11 : #ifdef NRF_CLOCK 12 : #include <hal/nrf_clock.h> 13 : #endif 14 : #include <zephyr/sys/onoff.h> 15 : #include <zephyr/drivers/clock_control.h> 16 : 17 : #ifdef __cplusplus 18 : extern "C" { 19 : #endif 20 : 21 : #if defined(CONFIG_CLOCK_CONTROL_NRF) 22 : 23 : /** @brief Clocks handled by the CLOCK peripheral. 24 : * 25 : * Enum shall be used as a sys argument in clock_control API. 26 : */ 27 : enum clock_control_nrf_type { 28 : CLOCK_CONTROL_NRF_TYPE_HFCLK, 29 : CLOCK_CONTROL_NRF_TYPE_LFCLK, 30 : #if NRF_CLOCK_HAS_HFCLK192M 31 : CLOCK_CONTROL_NRF_TYPE_HFCLK192M, 32 : #endif 33 : #if NRF_CLOCK_HAS_HFCLKAUDIO 34 : CLOCK_CONTROL_NRF_TYPE_HFCLKAUDIO, 35 : #endif 36 : CLOCK_CONTROL_NRF_TYPE_COUNT 37 : }; 38 : 39 : /* Define can be used with clock control API instead of enum directly to 40 : * increase code readability. 41 : */ 42 : #define CLOCK_CONTROL_NRF_SUBSYS_HF \ 43 : ((clock_control_subsys_t)CLOCK_CONTROL_NRF_TYPE_HFCLK) 44 : #define CLOCK_CONTROL_NRF_SUBSYS_LF \ 45 : ((clock_control_subsys_t)CLOCK_CONTROL_NRF_TYPE_LFCLK) 46 : #define CLOCK_CONTROL_NRF_SUBSYS_HF192M \ 47 : ((clock_control_subsys_t)CLOCK_CONTROL_NRF_TYPE_HFCLK192M) 48 : #define CLOCK_CONTROL_NRF_SUBSYS_HFAUDIO \ 49 : ((clock_control_subsys_t)CLOCK_CONTROL_NRF_TYPE_HFCLKAUDIO) 50 : 51 : /** @brief LF clock start modes. */ 52 : enum nrf_lfclk_start_mode { 53 : CLOCK_CONTROL_NRF_LF_START_NOWAIT, 54 : CLOCK_CONTROL_NRF_LF_START_AVAILABLE, 55 : CLOCK_CONTROL_NRF_LF_START_STABLE, 56 : }; 57 : 58 : /* Define 32KHz clock source */ 59 : #ifdef CONFIG_CLOCK_CONTROL_NRF_K32SRC_RC 60 : #define CLOCK_CONTROL_NRF_K32SRC NRF_CLOCK_LFCLK_RC 61 : #endif 62 : #ifdef CONFIG_CLOCK_CONTROL_NRF_K32SRC_XTAL 63 : #define CLOCK_CONTROL_NRF_K32SRC NRF_CLOCK_LFCLK_XTAL 64 : #endif 65 : #ifdef CONFIG_CLOCK_CONTROL_NRF_K32SRC_SYNTH 66 : #define CLOCK_CONTROL_NRF_K32SRC NRF_CLOCK_LFCLK_SYNTH 67 : #endif 68 : #ifdef CONFIG_CLOCK_CONTROL_NRF_K32SRC_EXT_LOW_SWING 69 : #define CLOCK_CONTROL_NRF_K32SRC NRF_CLOCK_LFCLK_XTAL_LOW_SWING 70 : #endif 71 : #ifdef CONFIG_CLOCK_CONTROL_NRF_K32SRC_EXT_FULL_SWING 72 : #define CLOCK_CONTROL_NRF_K32SRC NRF_CLOCK_LFCLK_XTAL_FULL_SWING 73 : #endif 74 : 75 : /* Define 32KHz clock accuracy */ 76 : #ifdef CONFIG_CLOCK_CONTROL_NRF_K32SRC_500PPM 77 : #define CLOCK_CONTROL_NRF_K32SRC_ACCURACY 0 78 : #endif 79 : #ifdef CONFIG_CLOCK_CONTROL_NRF_K32SRC_250PPM 80 : #define CLOCK_CONTROL_NRF_K32SRC_ACCURACY 1 81 : #endif 82 : #ifdef CONFIG_CLOCK_CONTROL_NRF_K32SRC_150PPM 83 : #define CLOCK_CONTROL_NRF_K32SRC_ACCURACY 2 84 : #endif 85 : #ifdef CONFIG_CLOCK_CONTROL_NRF_K32SRC_100PPM 86 : #define CLOCK_CONTROL_NRF_K32SRC_ACCURACY 3 87 : #endif 88 : #ifdef CONFIG_CLOCK_CONTROL_NRF_K32SRC_75PPM 89 : #define CLOCK_CONTROL_NRF_K32SRC_ACCURACY 4 90 : #endif 91 : #ifdef CONFIG_CLOCK_CONTROL_NRF_K32SRC_50PPM 92 : #define CLOCK_CONTROL_NRF_K32SRC_ACCURACY 5 93 : #endif 94 : #ifdef CONFIG_CLOCK_CONTROL_NRF_K32SRC_30PPM 95 : #define CLOCK_CONTROL_NRF_K32SRC_ACCURACY 6 96 : #endif 97 : #ifdef CONFIG_CLOCK_CONTROL_NRF_K32SRC_20PPM 98 : #define CLOCK_CONTROL_NRF_K32SRC_ACCURACY 7 99 : #endif 100 : 101 : /** @brief Force LF clock calibration. */ 102 : void z_nrf_clock_calibration_force_start(void); 103 : 104 : /** @brief Return number of calibrations performed. 105 : * 106 : * Valid when @kconfig{CONFIG_CLOCK_CONTROL_NRF_CALIBRATION_DEBUG} is set. 107 : * 108 : * @return Number of calibrations or -1 if feature is disabled. 109 : */ 110 : int z_nrf_clock_calibration_count(void); 111 : 112 : /** @brief Return number of attempts when calibration was skipped. 113 : * 114 : * Valid when @kconfig{CONFIG_CLOCK_CONTROL_NRF_CALIBRATION_DEBUG} is set. 115 : * 116 : * @return Number of calibrations or -1 if feature is disabled. 117 : */ 118 : int z_nrf_clock_calibration_skips_count(void); 119 : 120 : 121 : /** @brief Returns information if LF clock calibration is in progress. 122 : * 123 : * @return True if calibration is in progress, false otherwise. 124 : */ 125 : bool z_nrf_clock_calibration_is_in_progress(void); 126 : 127 : /** @brief Get onoff service for given clock subsystem. 128 : * 129 : * @param sys Subsystem. 130 : * 131 : * @return Service handler or NULL. 132 : */ 133 : struct onoff_manager *z_nrf_clock_control_get_onoff(clock_control_subsys_t sys); 134 : 135 : /** @brief Permanently enable low frequency clock. 136 : * 137 : * Low frequency clock is usually enabled during application lifetime because 138 : * of long startup time and low power consumption. Multiple modules can request 139 : * it but never release. 140 : * 141 : * @param start_mode Specify if function should block until clock is available. 142 : */ 143 : void z_nrf_clock_control_lf_on(enum nrf_lfclk_start_mode start_mode); 144 : 145 : /** @brief Request high frequency clock from Bluetooth Controller. 146 : * 147 : * Function is optimized for Bluetooth Controller which turns HF clock before 148 : * each radio activity and has hard timing requirements but does not require 149 : * any confirmation when clock is ready because it assumes that request is 150 : * performed long enough before radio activity. Clock is released immediately 151 : * after radio activity. 152 : * 153 : * Function does not perform any validation. It is the caller responsibility to 154 : * ensure that every z_nrf_clock_bt_ctlr_hf_request matches 155 : * z_nrf_clock_bt_ctlr_hf_release call. 156 : */ 157 : void z_nrf_clock_bt_ctlr_hf_request(void); 158 : 159 : /** @brief Release high frequency clock from Bluetooth Controller. 160 : * 161 : * See z_nrf_clock_bt_ctlr_hf_request for details. 162 : */ 163 : void z_nrf_clock_bt_ctlr_hf_release(void); 164 : 165 : #endif /* defined(CONFIG_CLOCK_CONTROL_NRF) */ 166 : 167 : 168 : #if defined(CONFIG_CLOCK_CONTROL_NRF2) 169 : 170 : /* Specifies to use the maximum available frequency for a given clock. */ 171 : #define NRF_CLOCK_CONTROL_FREQUENCY_MAX UINT32_MAX 172 : 173 : /* Specifies to use the maximum available accuracy for a given clock. */ 174 : #define NRF_CLOCK_CONTROL_ACCURACY_MAX 1 175 : /* Specifies the required clock accuracy in parts-per-million. */ 176 : #define NRF_CLOCK_CONTROL_ACCURACY_PPM(ppm) (ppm) 177 : 178 : /* Specifies that high precision of the clock is required. */ 179 : #define NRF_CLOCK_CONTROL_PRECISION_HIGH 1 180 : /* Specifies that default precision of the clock is sufficient. */ 181 : #define NRF_CLOCK_CONTROL_PRECISION_DEFAULT 0 182 : 183 : struct nrf_clock_spec { 184 : uint32_t frequency; 185 : uint16_t accuracy : 15; 186 : uint16_t precision : 1; 187 : }; 188 : 189 : __subsystem struct nrf_clock_control_driver_api { 190 : struct clock_control_driver_api std_api; 191 : 192 : int (*request)(const struct device *dev, 193 : const struct nrf_clock_spec *spec, 194 : struct onoff_client *cli); 195 : int (*release)(const struct device *dev, 196 : const struct nrf_clock_spec *spec); 197 : int (*cancel_or_release)(const struct device *dev, 198 : const struct nrf_clock_spec *spec, 199 : struct onoff_client *cli); 200 : }; 201 : 202 : /** 203 : * @brief Request a reservation to use a given clock with specified attributes. 204 : * 205 : * The return value indicates the success or failure of an attempt to initiate 206 : * an operation to request the clock be made available. If initiation of the 207 : * operation succeeds, the result of the request operation is provided through 208 : * the configured client notification method, possibly before this call returns. 209 : * 210 : * Note that the call to this function may succeed in a case where the actual 211 : * request fails. Always check the operation completion result. 212 : * 213 : * @param dev pointer to the clock device structure. 214 : * @param spec specification of minimal acceptable attributes, like frequency, 215 : * accuracy, and precision, required for the clock. 216 : * Value of 0 has the meaning of "default" and can be passed 217 : * instead of a given attribute if there is no strict requirement 218 : * in this regard. If there is no specific requirement for any of 219 : * the attributes, this parameter can be NULL. 220 : * @param cli pointer to client state providing instructions on synchronous 221 : * expectations and how to notify the client when the request 222 : * completes. Behavior is undefined if client passes a pointer 223 : * object associated with an incomplete service operation. 224 : * 225 : * @retval non-negative the observed state of the on-off service associated 226 : * with the clock machine at the time the request was 227 : * processed (see onoff_request()), if successful. 228 : * @retval -EIO if service has recorded an error. 229 : * @retval -EINVAL if the function parameters are invalid or the clock 230 : * attributes cannot be provided (e.g. the requested accuracy 231 : * is unavailable). 232 : * @retval -EAGAIN if the reference count would overflow. 233 : */ 234 : static inline 235 : int nrf_clock_control_request(const struct device *dev, 236 : const struct nrf_clock_spec *spec, 237 : struct onoff_client *cli) 238 : { 239 : const struct nrf_clock_control_driver_api *api = 240 : (const struct nrf_clock_control_driver_api *)dev->api; 241 : 242 : return api->request(dev, spec, cli); 243 : } 244 : 245 : /** 246 : * @brief Synchronously request a reservation to use a given clock with specified attributes. 247 : * 248 : * Function can only be called from thread context as it blocks until request is completed. 249 : * @see nrf_clock_control_request(). 250 : * 251 : * @param dev pointer to the clock device structure. 252 : * @param spec See nrf_clock_control_request(). 253 : * @param timeout Request timeout. 254 : * 255 : * @retval 0 if request is fulfilled. 256 : * @retval -EWOULDBLOCK if request is called from the interrupt context. 257 : * @retval negative See error codes returned by nrf_clock_control_request(). 258 : */ 259 : int nrf_clock_control_request_sync(const struct device *dev, 260 : const struct nrf_clock_spec *spec, 261 : k_timeout_t timeout); 262 : 263 : /** 264 : * @brief Release a reserved use of a clock. 265 : * 266 : * @param dev pointer to the clock device structure. 267 : * @param spec the same specification of the clock attributes that was used 268 : * in the reservation request (so that the clock control module 269 : * can keep track of what attributes are still requested). 270 : * 271 : * @retval non-negative the observed state of the on-off service associated 272 : * with the clock machine at the time the request was 273 : * processed (see onoff_release()), if successful. 274 : * @retval -EIO if service has recorded an error. 275 : * @retval -ENOTSUP if the service is not in a state that permits release. 276 : */ 277 : static inline 278 : int nrf_clock_control_release(const struct device *dev, 279 : const struct nrf_clock_spec *spec) 280 : { 281 : const struct nrf_clock_control_driver_api *api = 282 : (const struct nrf_clock_control_driver_api *)dev->api; 283 : 284 : return api->release(dev, spec); 285 : } 286 : 287 : /** 288 : * @brief Safely cancel a reservation request. 289 : * 290 : * It may be that a client has issued a reservation request but needs to 291 : * shut down before the request has completed. This function attempts to 292 : * cancel the request and issues a release if cancellation fails because 293 : * the request was completed. This synchronously ensures that ownership 294 : * data reverts to the client so is available for a future request. 295 : * 296 : * @param dev pointer to the clock device structure. 297 : * @param spec the same specification of the clock attributes that was used 298 : * in the reservation request. 299 : * @param cli a pointer to the same client state that was provided 300 : * when the operation to be cancelled was issued. 301 : * 302 : * @retval ONOFF_STATE_TO_ON if the cancellation occurred before the transition 303 : * completed. 304 : * @retval ONOFF_STATE_ON if the cancellation occurred after the transition 305 : * completed. 306 : * @retval -EINVAL if the parameters are invalid. 307 : * @retval negative other errors produced by onoff_release(). 308 : */ 309 : static inline 310 : int nrf_clock_control_cancel_or_release(const struct device *dev, 311 : const struct nrf_clock_spec *spec, 312 : struct onoff_client *cli) 313 : { 314 : const struct nrf_clock_control_driver_api *api = 315 : (const struct nrf_clock_control_driver_api *)dev->api; 316 : 317 : return api->cancel_or_release(dev, spec, cli); 318 : } 319 : 320 : /** @brief Request the HFXO from Zero Latency Interrupt context. 321 : * 322 : * Function is optimized for use in Zero Latency Interrupt context. 323 : * It does not give notification when the HFXO is ready, so each 324 : * user must put the request early enough to make sure the HFXO 325 : * ramp-up has finished on time. 326 : * 327 : * This function uses reference counting so the caller must ensure 328 : * that every nrf_clock_control_hfxo_request() call has a matching 329 : * nrf_clock_control_hfxo_release() call. 330 : */ 331 : void nrf_clock_control_hfxo_request(void); 332 : 333 : /** @brief Release the HFXO from Zero Latency Interrupt context. 334 : * 335 : * Function is optimized for use in Zero Latency Interrupt context. 336 : * 337 : * Calls to this function must be coupled with prior calls 338 : * to nrf_clock_control_hfxo_request(), because it uses basic 339 : * reference counting to make sure the HFXO is released when 340 : * there are no more pending requests. 341 : */ 342 : void nrf_clock_control_hfxo_release(void); 343 : 344 : #endif /* defined(CONFIG_CLOCK_CONTROL_NRF2) */ 345 : 346 : #ifdef __cplusplus 347 : } 348 : #endif 349 : 350 : #endif /* ZEPHYR_INCLUDE_DRIVERS_CLOCK_CONTROL_NRF_CLOCK_CONTROL_H_ */