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 <device.h>
11 #include <hal/nrf_clock.h>
12 #include <sys/onoff.h>
13 #include <drivers/clock_control.h>
14 
15 #ifdef __cplusplus
16 extern "C" {
17 #endif
18 
19 /** @brief Clocks handled by the CLOCK peripheral.
20  *
21  * Enum shall be used as a sys argument in clock_control API.
22  */
23 enum clock_control_nrf_type {
24 	CLOCK_CONTROL_NRF_TYPE_HFCLK,
25 	CLOCK_CONTROL_NRF_TYPE_LFCLK,
26 #if NRF_CLOCK_HAS_HFCLK192M
27 	CLOCK_CONTROL_NRF_TYPE_HFCLK192M,
28 #endif
29 #if NRF_CLOCK_HAS_HFCLKAUDIO
30 	CLOCK_CONTROL_NRF_TYPE_HFCLKAUDIO,
31 #endif
32 	CLOCK_CONTROL_NRF_TYPE_COUNT
33 };
34 
35 /* Define can be used with clock control API instead of enum directly to
36  * increase code readability.
37  */
38 #define CLOCK_CONTROL_NRF_SUBSYS_HF \
39 	((clock_control_subsys_t)CLOCK_CONTROL_NRF_TYPE_HFCLK)
40 #define CLOCK_CONTROL_NRF_SUBSYS_LF \
41 	((clock_control_subsys_t)CLOCK_CONTROL_NRF_TYPE_LFCLK)
42 #define CLOCK_CONTROL_NRF_SUBSYS_HF192M \
43 	((clock_control_subsys_t)CLOCK_CONTROL_NRF_TYPE_HFCLK192M)
44 #define CLOCK_CONTROL_NRF_SUBSYS_HFAUDIO \
45 	((clock_control_subsys_t)CLOCK_CONTROL_NRF_TYPE_HFCLKAUDIO)
46 
47 /** @brief LF clock start modes. */
48 enum nrf_lfclk_start_mode {
49 	CLOCK_CONTROL_NRF_LF_START_NOWAIT,
50 	CLOCK_CONTROL_NRF_LF_START_AVAILABLE,
51 	CLOCK_CONTROL_NRF_LF_START_STABLE,
52 };
53 
54 /* Define 32KHz clock source */
55 #ifdef CONFIG_CLOCK_CONTROL_NRF_K32SRC_RC
56 #define CLOCK_CONTROL_NRF_K32SRC NRF_CLOCK_LFCLK_RC
57 #endif
58 #ifdef CONFIG_CLOCK_CONTROL_NRF_K32SRC_XTAL
59 #define CLOCK_CONTROL_NRF_K32SRC NRF_CLOCK_LFCLK_Xtal
60 #endif
61 #ifdef CONFIG_CLOCK_CONTROL_NRF_K32SRC_SYNTH
62 #define CLOCK_CONTROL_NRF_K32SRC NRF_CLOCK_LFCLK_Synth
63 #endif
64 #ifdef CONFIG_CLOCK_CONTROL_NRF_K32SRC_EXT_LOW_SWING
65 #define CLOCK_CONTROL_NRF_K32SRC NRF_CLOCK_LFCLK_Xtal_Low_Swing
66 #endif
67 #ifdef CONFIG_CLOCK_CONTROL_NRF_K32SRC_EXT_FULL_SWING
68 #define CLOCK_CONTROL_NRF_K32SRC NRF_CLOCK_LFCLK_Xtal_Full_Swing
69 #endif
70 
71 /* Define 32KHz clock accuracy */
72 #ifdef CONFIG_CLOCK_CONTROL_NRF_K32SRC_500PPM
73 #define CLOCK_CONTROL_NRF_K32SRC_ACCURACY 0
74 #endif
75 #ifdef CONFIG_CLOCK_CONTROL_NRF_K32SRC_250PPM
76 #define CLOCK_CONTROL_NRF_K32SRC_ACCURACY 1
77 #endif
78 #ifdef CONFIG_CLOCK_CONTROL_NRF_K32SRC_150PPM
79 #define CLOCK_CONTROL_NRF_K32SRC_ACCURACY 2
80 #endif
81 #ifdef CONFIG_CLOCK_CONTROL_NRF_K32SRC_100PPM
82 #define CLOCK_CONTROL_NRF_K32SRC_ACCURACY 3
83 #endif
84 #ifdef CONFIG_CLOCK_CONTROL_NRF_K32SRC_75PPM
85 #define CLOCK_CONTROL_NRF_K32SRC_ACCURACY 4
86 #endif
87 #ifdef CONFIG_CLOCK_CONTROL_NRF_K32SRC_50PPM
88 #define CLOCK_CONTROL_NRF_K32SRC_ACCURACY 5
89 #endif
90 #ifdef CONFIG_CLOCK_CONTROL_NRF_K32SRC_30PPM
91 #define CLOCK_CONTROL_NRF_K32SRC_ACCURACY 6
92 #endif
93 #ifdef CONFIG_CLOCK_CONTROL_NRF_K32SRC_20PPM
94 #define CLOCK_CONTROL_NRF_K32SRC_ACCURACY 7
95 #endif
96 
97 /** @brief Force LF clock calibration. */
98 void z_nrf_clock_calibration_force_start(void);
99 
100 /** @brief Return number of calibrations performed.
101  *
102  * Valid when @ref CONFIG_CLOCK_CONTROL_NRF_CALIBRATION_DEBUG is set.
103  *
104  * @return Number of calibrations or -1 if feature is disabled.
105  */
106 int z_nrf_clock_calibration_count(void);
107 
108 /** @brief Return number of attempts when calibration was skipped.
109  *
110  * Valid when @ref CONFIG_CLOCK_CONTROL_NRF_CALIBRATION_DEBUG is set.
111  *
112  * @return Number of calibrations or -1 if feature is disabled.
113  */
114 int z_nrf_clock_calibration_skips_count(void);
115 
116 /** @brief Get onoff service for given clock subsystem.
117  *
118  * @param sys Subsystem.
119  *
120  * @return Service handler or NULL.
121  */
122 struct onoff_manager *z_nrf_clock_control_get_onoff(clock_control_subsys_t sys);
123 
124 /** @brief Permanently enable low frequency clock.
125  *
126  * Low frequency clock is usually enabled during application lifetime because
127  * of long startup time and low power consumption. Multiple modules can request
128  * it but never release.
129  *
130  * @param start_mode Specify if function should block until clock is available.
131  */
132 void z_nrf_clock_control_lf_on(enum nrf_lfclk_start_mode start_mode);
133 
134 /** @brief Request high frequency clock from Bluetooth Controller.
135  *
136  * Function is optimized for Bluetooth Controller which turns HF clock before
137  * each radio activity and has hard timing requirements but does not require
138  * any confirmation when clock is ready because it assumes that request is
139  * performed long enough before radio activity. Clock is released immediately
140  * after radio activity.
141  *
142  * Function does not perform any validation. It is the caller responsibility to
143  * ensure that every z_nrf_clock_bt_ctlr_hf_request matches
144  * z_nrf_clock_bt_ctlr_hf_release call.
145  */
146 void z_nrf_clock_bt_ctlr_hf_request(void);
147 
148 /** @brief Release high frequency clock from Bluetooth Controller.
149  *
150  * See z_nrf_clock_bt_ctlr_hf_request for details.
151  */
152 void z_nrf_clock_bt_ctlr_hf_release(void);
153 
154 #ifdef __cplusplus
155 }
156 #endif
157 
158 #endif /* ZEPHYR_INCLUDE_DRIVERS_CLOCK_CONTROL_NRF_CLOCK_CONTROL_H_ */
159