1 /*
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
nrf_clock_control_request(const struct device * dev,const struct nrf_clock_spec * spec,struct onoff_client * cli)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
nrf_clock_control_release(const struct device * dev,const struct nrf_clock_spec * spec)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
nrf_clock_control_cancel_or_release(const struct device * dev,const struct nrf_clock_spec * spec,struct onoff_client * cli)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_ */
351