1 /*
2  * Copyright (c) 2023 Prevas A/S
3  * Copyright (c) 2023 Syslinbit
4  * Copyright (c) 2024 STMicroelectronics
5  * Copyright (c) 2025 Alexander Kozhinov <ak.alexander.kozhinov@gmail.com>
6  *
7  * SPDX-License-Identifier: Apache-2.0
8  *
9  */
10 
11 #define DT_DRV_COMPAT st_stm32_rtc
12 
13 #include <errno.h>
14 #include <zephyr/device.h>
15 #include <zephyr/kernel.h>
16 #include <zephyr/init.h>
17 #include <zephyr/devicetree.h>
18 #include <zephyr/spinlock.h>
19 #include <zephyr/drivers/rtc.h>
20 #include <zephyr/drivers/clock_control/stm32_clock_control.h>
21 #include <zephyr/drivers/clock_control.h>
22 #include <zephyr/sys/util.h>
23 #include <soc.h>
24 #include <stm32_ll_pwr.h>
25 #include <stm32_ll_rcc.h>
26 #include <stm32_ll_rtc.h>
27 #ifdef CONFIG_RTC_ALARM
28 #include <zephyr/drivers/interrupt_controller/intc_exti_stm32.h>
29 #endif /* CONFIG_RTC_ALARM */
30 
31 #include <zephyr/logging/log.h>
32 #ifdef CONFIG_RTC_ALARM
33 #include <zephyr/irq.h>
34 #endif /* CONFIG_RTC_ALARM */
35 
36 #include <stm32_backup_domain.h>
37 #include <stm32_hsem.h>
38 
39 #include <stdbool.h>
40 #include "rtc_utils.h"
41 
42 #include "rtc_ll_stm32.h"
43 
44 LOG_MODULE_REGISTER(rtc_stm32, CONFIG_RTC_LOG_LEVEL);
45 
46 #if (defined(CONFIG_SOC_SERIES_STM32L1X) && !defined(RTC_SUBSECOND_SUPPORT)) \
47 	|| defined(CONFIG_SOC_SERIES_STM32F2X)
48 /* subsecond counting is not supported by some STM32L1x MCUs (Cat.1) & by STM32F2x SoC series */
49 #define HW_SUBSECOND_SUPPORT (0)
50 #else
51 #define HW_SUBSECOND_SUPPORT (1)
52 #endif
53 
54 /* RTC start time: 1st, Jan, 2000 */
55 #define RTC_YEAR_REF 2000
56 /* struct tm start time:   1st, Jan, 1900 */
57 #define TM_YEAR_REF 1900
58 
59 /* Convert part per billion calibration value to a number of clock pulses added or removed each
60  * 2^20 clock cycles so it is suitable for the CALR register fields
61  *
62  * nb_pulses = ppb * 2^20 / 10^9 = ppb * 2^11 / 5^9 = ppb * 2048 / 1953125
63  */
64 #define PPB_TO_NB_PULSES(ppb) DIV_ROUND_CLOSEST((ppb) * 2048, 1953125)
65 
66 /* Convert CALR register value (number of clock pulses added or removed each 2^20 clock cycles)
67  * to part ber billion calibration value
68  *
69  * ppb = nb_pulses * 10^9 / 2^20 = nb_pulses * 5^9 / 2^11 = nb_pulses * 1953125 / 2048
70  */
71 #define NB_PULSES_TO_PPB(pulses) DIV_ROUND_CLOSEST((pulses) * 1953125, 2048)
72 
73 /* CALP field can only be 512 or 0 as in reality CALP is a single bit field representing 512 pulses
74  * added every 2^20 clock cycles
75  */
76 #define MAX_CALP (512)
77 #define MAX_CALM (511)
78 
79 #define MAX_PPB NB_PULSES_TO_PPB(MAX_CALP)
80 #define MIN_PPB -NB_PULSES_TO_PPB(MAX_CALM)
81 
82 /* Timeout in microseconds used to wait for flags */
83 #define RTC_TIMEOUT 1000000
84 
85 #ifdef STM32_RTC_ALARM_ENABLED
86 #define RTC_STM32_ALARMS_COUNT	DT_INST_PROP(0, alarms_count)
87 
88 #define RTC_STM32_ALRM_A	0U
89 #define RTC_STM32_ALRM_B	1U
90 
91 /* Zephyr mask supported by RTC device, values from RTC_ALARM_TIME_MASK */
92 #define RTC_STM32_SUPPORTED_ALARM_FIELDS				\
93 	(RTC_ALARM_TIME_MASK_SECOND | RTC_ALARM_TIME_MASK_MINUTE	\
94 	| RTC_ALARM_TIME_MASK_HOUR | RTC_ALARM_TIME_MASK_WEEKDAY	\
95 	| RTC_ALARM_TIME_MASK_MONTHDAY)
96 
97 #define RTC_STM32_EXTI_LINE_NUM	DT_INST_PROP_OR(0, alrm_exti_line, 0)
98 
99 #endif /* STM32_RTC_ALARM_ENABLED */
100 
101 struct rtc_stm32_config {
102 	uint32_t async_prescaler;
103 	uint32_t sync_prescaler;
104 	const struct stm32_pclken *pclken;
105 #if DT_INST_NODE_HAS_PROP(0, calib_out_freq)
106 	uint32_t cal_out_freq;
107 #endif
108 #if DT_INST_CLOCKS_CELL_BY_IDX(0, 1, bus) == STM32_SRC_HSE
109 	uint32_t hse_prescaler;
110 #endif
111 };
112 
113 #ifdef STM32_RTC_ALARM_ENABLED
114 struct rtc_stm32_alrm {
115 	LL_RTC_AlarmTypeDef ll_rtc_alrm;
116 	/* user-defined alarm mask, values from RTC_ALARM_TIME_MASK */
117 	uint16_t user_mask;
118 	rtc_alarm_callback user_callback;
119 	void *user_data;
120 	bool is_pending;
121 };
122 #endif /* STM32_RTC_ALARM_ENABLED */
123 
124 struct rtc_stm32_data {
125 	struct k_spinlock lock;
126 #ifdef STM32_RTC_ALARM_ENABLED
127 	struct rtc_stm32_alrm rtc_alrm_a;
128 	struct rtc_stm32_alrm rtc_alrm_b;
129 #endif /* STM32_RTC_ALARM_ENABLED */
130 };
131 
132 #ifdef STM32_RTC_ALARM_ENABLED
133 
exti_enable_rtc_alarm_it(uint32_t line_num)134 static inline void exti_enable_rtc_alarm_it(uint32_t line_num)
135 {
136 #if defined(CONFIG_SOC_SERIES_STM32U5X) || defined(CONFIG_SOC_SERIES_STM32WBAX)
137 	/* in STM32U5 & STM32WBAX series, RTC Alarm event is not routed to EXTI */
138 #else
139 	int ret;
140 
141 	ret = stm32_exti_enable(line_num, STM32_EXTI_TRIG_RISING, STM32_EXTI_MODE_IT);
142 	if (ret != 0) {
143 		LOG_ERR("Failed to enable EXTI line number %d (error %d)", line_num, ret);
144 	}
145 #endif
146 }
147 
exti_clear_rtc_alarm_flag(uint32_t line_num)148 static inline void exti_clear_rtc_alarm_flag(uint32_t line_num)
149 {
150 #if defined(CONFIG_SOC_SERIES_STM32U5X) || defined(CONFIG_SOC_SERIES_STM32WBAX)
151 	/* in STM32U5 & STM32WBAX series, RTC Alarm (EXTI event) is not routed to EXTI */
152 #else
153 	if (stm32_exti_is_pending(line_num)) {
154 		stm32_exti_clear_pending(line_num);
155 	}
156 #endif
157 }
158 
159 #endif /* STM32_RTC_ALARM_ENABLED */
160 
rtc_stm32_configure(const struct device * dev)161 static int rtc_stm32_configure(const struct device *dev)
162 {
163 	const struct rtc_stm32_config *cfg = dev->config;
164 
165 	int err = 0;
166 
167 	uint32_t hour_format     = LL_RTC_GetHourFormat(RTC);
168 	uint32_t sync_prescaler  = LL_RTC_GetSynchPrescaler(RTC);
169 	uint32_t async_prescaler = LL_RTC_GetAsynchPrescaler(RTC);
170 
171 	LL_RTC_DisableWriteProtection(RTC);
172 
173 	/* configuration process requires to stop the RTC counter so do it
174 	 * only if needed to avoid inducing time drift at each reset
175 	 */
176 	if ((hour_format != LL_RTC_HOURFORMAT_24HOUR) ||
177 	    (sync_prescaler != cfg->sync_prescaler) ||
178 	    (async_prescaler != cfg->async_prescaler)) {
179 		ErrorStatus status = LL_RTC_EnterInitMode(RTC);
180 
181 		if (status == SUCCESS) {
182 			LL_RTC_SetHourFormat(RTC, LL_RTC_HOURFORMAT_24HOUR);
183 			LL_RTC_SetSynchPrescaler(RTC, cfg->sync_prescaler);
184 			LL_RTC_SetAsynchPrescaler(RTC, cfg->async_prescaler);
185 		} else {
186 			err = -EIO;
187 		}
188 
189 		LL_RTC_DisableInitMode(RTC);
190 	}
191 
192 #if DT_INST_NODE_HAS_PROP(0, calib_out_freq)
193 	LL_RTC_CAL_SetOutputFreq(RTC, cfg->cal_out_freq);
194 #else
195 	LL_RTC_CAL_SetOutputFreq(RTC, LL_RTC_CALIB_OUTPUT_NONE);
196 #endif
197 
198 #ifdef RTC_CR_BYPSHAD
199 	LL_RTC_EnableShadowRegBypass(RTC);
200 #endif /* RTC_CR_BYPSHAD */
201 
202 	LL_RTC_EnableWriteProtection(RTC);
203 
204 	return err;
205 }
206 
207 #ifdef STM32_RTC_ALARM_ENABLED
rtc_stm32_init_alarm(RTC_TypeDef * rtc,uint32_t format,LL_RTC_AlarmTypeDef * ll_alarm_struct,uint16_t id)208 static inline ErrorStatus rtc_stm32_init_alarm(RTC_TypeDef *rtc, uint32_t format,
209 					LL_RTC_AlarmTypeDef *ll_alarm_struct, uint16_t id)
210 {
211 	ll_alarm_struct->AlarmDateWeekDaySel = RTC_STM32_ALRM_DATEWEEKDAYSEL_DATE;
212 	/*
213 	 * RTC write protection is disabled & enabled again inside LL_RTC_ALMx_Init functions
214 	 * The LL_RTC_ALMx_Init does convert bin2bcd by itself
215 	 */
216 	if (id == RTC_STM32_ALRM_A) {
217 		return LL_RTC_ALMA_Init(rtc, format, ll_alarm_struct);
218 	}
219 #if RTC_STM32_ALARMS_COUNT > 1
220 	if (id == RTC_STM32_ALRM_B) {
221 		return LL_RTC_ALMB_Init(rtc, format, ll_alarm_struct);
222 	}
223 #endif /* RTC_STM32_ALARMS_COUNT > 1 */
224 
225 	return 0;
226 }
227 
rtc_stm32_clear_alarm_flag(RTC_TypeDef * rtc,uint16_t id)228 static inline void rtc_stm32_clear_alarm_flag(RTC_TypeDef *rtc, uint16_t id)
229 {
230 	if (id == RTC_STM32_ALRM_A) {
231 		LL_RTC_ClearFlag_ALRA(rtc);
232 		return;
233 	}
234 #if RTC_STM32_ALARMS_COUNT > 1
235 	if (id == RTC_STM32_ALRM_B) {
236 		LL_RTC_ClearFlag_ALRB(rtc);
237 	}
238 #endif /* RTC_STM32_ALARMS_COUNT > 1 */
239 }
240 
rtc_stm32_is_active_alarm(RTC_TypeDef * rtc,uint16_t id)241 static inline uint32_t rtc_stm32_is_active_alarm(RTC_TypeDef *rtc, uint16_t id)
242 {
243 	if (id == RTC_STM32_ALRM_A) {
244 		return LL_RTC_IsActiveFlag_ALRA(rtc);
245 	}
246 #if RTC_STM32_ALARMS_COUNT > 1
247 	if (id == RTC_STM32_ALRM_B) {
248 		return LL_RTC_IsActiveFlag_ALRB(rtc);
249 	}
250 #endif /* RTC_STM32_ALARMS_COUNT > 1 */
251 
252 	return 0;
253 }
254 
rtc_stm32_enable_interrupt_alarm(RTC_TypeDef * rtc,uint16_t id)255 static inline void rtc_stm32_enable_interrupt_alarm(RTC_TypeDef *rtc, uint16_t id)
256 {
257 	if (id == RTC_STM32_ALRM_A) {
258 		LL_RTC_EnableIT_ALRA(rtc);
259 		return;
260 	}
261 #if RTC_STM32_ALARMS_COUNT > 1
262 	if (id == RTC_STM32_ALRM_B) {
263 		LL_RTC_EnableIT_ALRB(rtc);
264 	}
265 #endif /* RTC_STM32_ALARMS_COUNT > 1 */
266 }
267 
rtc_stm32_disable_interrupt_alarm(RTC_TypeDef * rtc,uint16_t id)268 static inline void rtc_stm32_disable_interrupt_alarm(RTC_TypeDef *rtc, uint16_t id)
269 {
270 	if (id == RTC_STM32_ALRM_A) {
271 		LL_RTC_DisableIT_ALRA(rtc);
272 		return;
273 	}
274 #if RTC_STM32_ALARMS_COUNT > 1
275 	if (id == RTC_STM32_ALRM_B) {
276 		LL_RTC_DisableIT_ALRB(rtc);
277 	}
278 #endif /* RTC_STM32_ALARMS_COUNT > 1 */
279 }
280 
rtc_stm32_enable_alarm(RTC_TypeDef * rtc,uint16_t id)281 static inline void rtc_stm32_enable_alarm(RTC_TypeDef *rtc, uint16_t id)
282 {
283 	if (id == RTC_STM32_ALRM_A) {
284 		LL_RTC_ALMA_Enable(rtc);
285 		return;
286 	}
287 #if RTC_STM32_ALARMS_COUNT > 1
288 	if (id == RTC_STM32_ALRM_B) {
289 		LL_RTC_ALMB_Enable(rtc);
290 	}
291 #endif /* RTC_STM32_ALARMS_COUNT > 1 */
292 }
293 
rtc_stm32_disable_alarm(RTC_TypeDef * rtc,uint16_t id)294 static inline void rtc_stm32_disable_alarm(RTC_TypeDef *rtc, uint16_t id)
295 {
296 	if (id == RTC_STM32_ALRM_A) {
297 		LL_RTC_ALMA_Disable(rtc);
298 		return;
299 	}
300 #if RTC_STM32_ALARMS_COUNT > 1
301 	if (id == RTC_STM32_ALRM_B) {
302 		LL_RTC_ALMB_Disable(rtc);
303 	}
304 #endif /* RTC_STM32_ALARMS_COUNT > 1 */
305 }
306 
rtc_stm32_isr(const struct device * dev)307 void rtc_stm32_isr(const struct device *dev)
308 {
309 	struct rtc_stm32_data *data = dev->data;
310 	struct rtc_stm32_alrm *p_rtc_alrm;
311 	int id = 0;
312 
313 	for (id = 0; id < RTC_STM32_ALARMS_COUNT; id++) {
314 		if (rtc_stm32_is_active_alarm(RTC, (uint16_t)id) != 0) {
315 			stm32_backup_domain_enable_access();
316 			LL_RTC_DisableWriteProtection(RTC);
317 			rtc_stm32_clear_alarm_flag(RTC, (uint16_t)id);
318 			LL_RTC_EnableWriteProtection(RTC);
319 			stm32_backup_domain_disable_access();
320 
321 			if (id == RTC_STM32_ALRM_A) {
322 				p_rtc_alrm = &(data->rtc_alrm_a);
323 			} else {
324 				p_rtc_alrm = &(data->rtc_alrm_b);
325 			}
326 
327 			p_rtc_alrm->is_pending = true;
328 
329 			if (p_rtc_alrm->user_callback != NULL) {
330 				p_rtc_alrm->user_callback(dev, (uint16_t)id, p_rtc_alrm->user_data);
331 			}
332 		}
333 	}
334 
335 	exti_clear_rtc_alarm_flag(RTC_STM32_EXTI_LINE_NUM);
336 }
337 
rtc_stm32_irq_config(const struct device * dev)338 static void rtc_stm32_irq_config(const struct device *dev)
339 {
340 	IRQ_CONNECT(DT_INST_IRQN(0),
341 		    DT_INST_IRQ(0, priority),
342 		    rtc_stm32_isr, DEVICE_DT_INST_GET(0), 0);
343 	irq_enable(DT_INST_IRQN(0));
344 }
345 #endif /* STM32_RTC_ALARM_ENABLED */
346 
rtc_stm32_init(const struct device * dev)347 static int rtc_stm32_init(const struct device *dev)
348 {
349 	const struct device *const clk = DEVICE_DT_GET(STM32_CLOCK_CONTROL_NODE);
350 	const struct rtc_stm32_config *cfg = dev->config;
351 	__maybe_unused struct rtc_stm32_data *data = dev->data;
352 
353 	int err = 0;
354 
355 	if (!device_is_ready(clk)) {
356 		LOG_ERR("clock control device not ready");
357 		return -ENODEV;
358 	}
359 
360 	/* Enable RTC bus clock */
361 	if (clock_control_on(clk, (clock_control_subsys_t)&cfg->pclken[0]) != 0) {
362 		LOG_ERR("clock op failed\n");
363 		return -EIO;
364 	}
365 
366 #if defined(CONFIG_SOC_SERIES_STM32WB0X)
367 	/**
368 	 * The STM32WB0 series has no bit for clock gating of RTC's APB
369 	 * interface. On the other hand, the RTCEN bit that would control
370 	 * whether the RTC IP is clock gated or not exists, and has been
371 	 * placed in APB0ENR. The call to clock_control_on() that just
372 	 * completed should have set this bit to 1.
373 	 *
374 	 * However, according to RefMan, the software must wait two slow
375 	 * clock cycles before the IP is actually usable, due to clock
376 	 * resynchronization delays. Sadly, there is no hardware register
377 	 * we can poll to wait until RTC is ready...
378 	 *
379 	 * In worst case scenario of 24 kHz LSI, we have to wait for:
380 	 *		tREADY = (2 cycles / 24'000 Hz) ≅ 84µs
381 	 *
382 	 * Spin until that much time has elapsed, and RTC should be up.
383 	 *
384 	 * N.B.: we can't use k_busy_wait because it uses the SysTick
385 	 * as time base, but SysTick is initialized after the RTC...
386 	 */
387 	const uint32_t cycles_to_waste =
388 		84 * (CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC / USEC_PER_SEC);
389 	volatile uint32_t i = cycles_to_waste;
390 
391 	while (--i > 0) {
392 		/* Do nothing - loop itself burns enough cycles */
393 	}
394 #endif /* CONFIG_SOC_SERIES_STM32WB0X */
395 
396 	stm32_backup_domain_enable_access();
397 
398 #if DT_INST_CLOCKS_CELL_BY_IDX(0, 1, bus) == STM32_SRC_HSE
399 	/* Must be configured before selecting the RTC clock source */
400 	LL_RCC_SetRTC_HSEPrescaler(cfg->hse_prescaler);
401 #endif
402 	/* Enable RTC clock source */
403 	if (cfg->pclken[1].enr != NO_SEL) {
404 		err = clock_control_configure(clk, (clock_control_subsys_t)&cfg->pclken[1], NULL);
405 
406 		if (err < 0) {
407 			stm32_backup_domain_disable_access();
408 			LOG_ERR("clock configure failed\n");
409 			return -EIO;
410 		}
411 	}
412 
413 /*
414  * On STM32WBAX series, there is no bit in BCDR register to enable RTC.
415  * Enabling RTC is done directly via the RCC APB register bit.
416  * On STM32WB0 series, LL_RCC_EnableRTC is not provided by STM32CubeWB0,
417  * but RTC IP clock has already been turned on - skip the call as well.
418  */
419 #if !defined(CONFIG_SOC_SERIES_STM32WBAX) && !defined(CONFIG_SOC_SERIES_STM32WB0X)
420 	z_stm32_hsem_lock(CFG_HW_RCC_SEMID, HSEM_LOCK_DEFAULT_RETRY);
421 
422 	LL_RCC_EnableRTC();
423 
424 	z_stm32_hsem_unlock(CFG_HW_RCC_SEMID);
425 #endif /* CONFIG_SOC_SERIES_STM32WBAX */
426 
427 	err = rtc_stm32_configure(dev);
428 
429 	stm32_backup_domain_disable_access();
430 
431 #ifdef STM32_RTC_ALARM_ENABLED
432 	rtc_stm32_irq_config(dev);
433 
434 	exti_enable_rtc_alarm_it(RTC_STM32_EXTI_LINE_NUM);
435 
436 	K_SPINLOCK(&data->lock) {
437 		memset(&(data->rtc_alrm_a), 0, sizeof(struct rtc_stm32_alrm));
438 		memset(&(data->rtc_alrm_b), 0, sizeof(struct rtc_stm32_alrm));
439 	}
440 #endif /* CONFIG_RTC_ALARM */
441 
442 	return err;
443 }
444 
rtc_stm32_set_time(const struct device * dev,const struct rtc_time * timeptr)445 static int rtc_stm32_set_time(const struct device *dev, const struct rtc_time *timeptr)
446 {
447 	struct rtc_stm32_data *data = dev->data;
448 	LL_RTC_TimeTypeDef rtc_time;
449 	LL_RTC_DateTypeDef rtc_date;
450 	uint32_t real_year = timeptr->tm_year + TM_YEAR_REF;
451 
452 	if (real_year < RTC_YEAR_REF) {
453 		/* RTC does not support years before 2000 */
454 		return -EINVAL;
455 	}
456 
457 	if (timeptr->tm_wday == -1) {
458 		/* day of the week is expected */
459 		return -EINVAL;
460 	}
461 
462 	/* Enter Init mode inside the LL_RTC_Time and Date Init functions */
463 	rtc_time.Hours = bin2bcd(timeptr->tm_hour);
464 	rtc_time.Minutes = bin2bcd(timeptr->tm_min);
465 	rtc_time.Seconds = bin2bcd(timeptr->tm_sec);
466 
467 	/* Set Date after Time to be sure the DR is correctly updated on stm32F2 serie. */
468 	rtc_date.Year = bin2bcd((real_year - RTC_YEAR_REF));
469 	rtc_date.Month = bin2bcd((timeptr->tm_mon + 1));
470 	rtc_date.Day = bin2bcd(timeptr->tm_mday);
471 	rtc_date.WeekDay = ((timeptr->tm_wday == 0) ? (LL_RTC_WEEKDAY_SUNDAY) : (timeptr->tm_wday));
472 	/* WeekDay sunday (tm_wday = 0) is not represented by the same value in hardware,
473 	 * all the other values are consistent with what is expected by hardware.
474 	 */
475 
476 	LOG_DBG("Setting clock");
477 
478 	k_spinlock_key_t key = k_spin_lock(&data->lock);
479 
480 	stm32_backup_domain_enable_access();
481 
482 	LL_RTC_TIME_Init(RTC, LL_RTC_FORMAT_BCD, &rtc_time);
483 	LL_RTC_DATE_Init(RTC, LL_RTC_FORMAT_BCD, &rtc_date);
484 
485 	stm32_backup_domain_disable_access();
486 
487 #ifdef CONFIG_SOC_SERIES_STM32F2X
488 	/*
489 	 * Because stm32F2 serie has no shadow registers,
490 	 * wait until TR and DR registers are synchronised : flag RS
491 	 */
492 	while (LL_RTC_IsActiveFlag_RS(RTC) != 1) {
493 		;
494 	}
495 #endif /* CONFIG_SOC_SERIES_STM32F2X */
496 
497 	LOG_DBG("Calendar set : %d/%d/%d - %dh%dm%ds",
498 			LL_RTC_DATE_GetDay(RTC),
499 			LL_RTC_DATE_GetMonth(RTC),
500 			LL_RTC_DATE_GetYear(RTC),
501 			LL_RTC_TIME_GetHour(RTC),
502 			LL_RTC_TIME_GetMinute(RTC),
503 			LL_RTC_TIME_GetSecond(RTC)
504 	);
505 
506 	k_spin_unlock(&data->lock, key);
507 
508 	return 0;
509 }
510 
rtc_stm32_get_time(const struct device * dev,struct rtc_time * timeptr)511 static int rtc_stm32_get_time(const struct device *dev, struct rtc_time *timeptr)
512 {
513 	struct rtc_stm32_data *data = dev->data;
514 
515 	uint32_t rtc_date, rtc_time;
516 
517 #if HW_SUBSECOND_SUPPORT
518 	const struct rtc_stm32_config *cfg = dev->config;
519 	uint32_t rtc_subsecond;
520 #endif /* HW_SUBSECOND_SUPPORT */
521 
522 	if (timeptr == NULL) {
523 		LOG_ERR("NULL rtc_time pointer");
524 		return -EINVAL;
525 	}
526 
527 	k_spinlock_key_t key = k_spin_lock(&data->lock);
528 
529 	if (!LL_RTC_IsActiveFlag_INITS(RTC)) {
530 		/* INITS flag is set when the calendar has been initialiazed. This flag is
531 		 * reset only on backup domain reset, so it can be read after a system
532 		 * reset to check if the calendar has been initialized.
533 		 */
534 		k_spin_unlock(&data->lock, key);
535 		return -ENODATA;
536 	}
537 
538 	do {
539 		/* read date, time and subseconds and relaunch if a day increment occurred
540 		 * while doing so as it will result in an erroneous result otherwise
541 		 */
542 		rtc_date = LL_RTC_DATE_Get(RTC);
543 		do {
544 			/* read time and subseconds and relaunch if a second increment occurred
545 			 * while doing so as it will result in an erroneous result otherwise
546 			 */
547 			rtc_time      = LL_RTC_TIME_Get(RTC);
548 #if HW_SUBSECOND_SUPPORT
549 			rtc_subsecond = LL_RTC_TIME_GetSubSecond(RTC);
550 #endif /* HW_SUBSECOND_SUPPORT */
551 		} while (rtc_time != LL_RTC_TIME_Get(RTC));
552 	} while (rtc_date != LL_RTC_DATE_Get(RTC));
553 
554 	k_spin_unlock(&data->lock, key);
555 
556 	/* tm_year is the value since 1900 and Rtc year is from 2000 */
557 	timeptr->tm_year = bcd2bin(__LL_RTC_GET_YEAR(rtc_date)) + (RTC_YEAR_REF - TM_YEAR_REF);
558 	/* tm_mon allowed values are 0-11 */
559 	timeptr->tm_mon = bcd2bin(__LL_RTC_GET_MONTH(rtc_date)) - 1;
560 	timeptr->tm_mday = bcd2bin(__LL_RTC_GET_DAY(rtc_date));
561 
562 	int hw_wday = __LL_RTC_GET_WEEKDAY(rtc_date);
563 
564 	if (hw_wday == LL_RTC_WEEKDAY_SUNDAY) {
565 		/* LL_RTC_WEEKDAY_SUNDAY = 7 but a 0 is expected in tm_wday for sunday */
566 		timeptr->tm_wday = 0;
567 	} else {
568 		/* all other values are consistent between hardware and rtc_time structure */
569 		timeptr->tm_wday = hw_wday;
570 	}
571 
572 	timeptr->tm_hour = bcd2bin(__LL_RTC_GET_HOUR(rtc_time));
573 	timeptr->tm_min = bcd2bin(__LL_RTC_GET_MINUTE(rtc_time));
574 	timeptr->tm_sec = bcd2bin(__LL_RTC_GET_SECOND(rtc_time));
575 
576 #if HW_SUBSECOND_SUPPORT
577 	uint64_t temp = ((uint64_t)(cfg->sync_prescaler - rtc_subsecond)) * 1000000000L;
578 
579 	timeptr->tm_nsec = temp / (cfg->sync_prescaler + 1);
580 #else
581 	timeptr->tm_nsec = 0;
582 #endif
583 	/* unknown values */
584 	timeptr->tm_yday  = -1;
585 	timeptr->tm_isdst = -1;
586 
587 	/* __LL_RTC_GET_YEAR(rtc_date)is the real year (from 2000) */
588 	LOG_DBG("Calendar get : %d/%d/%d - %dh%dm%ds",
589 		timeptr->tm_mday,
590 		timeptr->tm_mon,
591 		__LL_RTC_GET_YEAR(rtc_date),
592 		timeptr->tm_hour,
593 		timeptr->tm_min,
594 		timeptr->tm_sec);
595 
596 	return 0;
597 }
598 
599 #ifdef STM32_RTC_ALARM_ENABLED
rtc_stm32_init_ll_alrm_struct(LL_RTC_AlarmTypeDef * p_rtc_alarm,const struct rtc_time * timeptr,uint16_t mask)600 static void rtc_stm32_init_ll_alrm_struct(LL_RTC_AlarmTypeDef *p_rtc_alarm,
601 					const struct rtc_time *timeptr, uint16_t mask)
602 {
603 	LL_RTC_TimeTypeDef *p_rtc_alrm_time = &(p_rtc_alarm->AlarmTime);
604 	uint32_t ll_mask = 0;
605 
606 	/*
607 	 * STM32 RTC Alarm LL mask should be set for all fields beyond the broadest one
608 	 * that's being matched with RTC calendar to trigger alarm periodically,
609 	 * the opposite of Zephyr RTC Alarm mask which is set for active fields.
610 	 */
611 	ll_mask = RTC_STM32_ALRM_MASK_ALL;
612 
613 	if (mask & RTC_ALARM_TIME_MASK_SECOND) {
614 		ll_mask &= ~RTC_STM32_ALRM_MASK_SECONDS;
615 		p_rtc_alrm_time->Seconds = bin2bcd(timeptr->tm_sec);
616 	}
617 
618 	if (mask & RTC_ALARM_TIME_MASK_MINUTE) {
619 		ll_mask &= ~RTC_STM32_ALRM_MASK_MINUTES;
620 		p_rtc_alrm_time->Minutes = bin2bcd(timeptr->tm_min);
621 	}
622 
623 	if (mask & RTC_ALARM_TIME_MASK_HOUR) {
624 		ll_mask &= ~RTC_STM32_ALRM_MASK_HOURS;
625 		p_rtc_alrm_time->Hours = bin2bcd(timeptr->tm_hour);
626 	}
627 
628 	if (mask & RTC_ALARM_TIME_MASK_WEEKDAY) {
629 		/* the Alarm Mask field compares with the day of the week */
630 		ll_mask &= ~RTC_STM32_ALRM_MASK_DATEWEEKDAY;
631 		p_rtc_alarm->AlarmDateWeekDaySel = RTC_STM32_ALRM_DATEWEEKDAYSEL_WEEKDAY;
632 
633 		if (timeptr->tm_wday == 0) {
634 			/* sunday (tm_wday = 0) is not represented by the same value in hardware */
635 			p_rtc_alarm->AlarmDateWeekDay = LL_RTC_WEEKDAY_SUNDAY;
636 		} else {
637 			/* all the other values are consistent with what is expected by hardware */
638 			p_rtc_alarm->AlarmDateWeekDay = bin2bcd(timeptr->tm_wday);
639 		}
640 
641 	} else if (mask & RTC_ALARM_TIME_MASK_MONTHDAY) {
642 		/* the Alarm compares with the day number & ignores the day of the week */
643 		ll_mask &= ~RTC_STM32_ALRM_MASK_DATEWEEKDAY;
644 		p_rtc_alarm->AlarmDateWeekDaySel = RTC_STM32_ALRM_DATEWEEKDAYSEL_DATE;
645 		p_rtc_alarm->AlarmDateWeekDay = bin2bcd(timeptr->tm_mday);
646 	}
647 
648 	p_rtc_alrm_time->TimeFormat = LL_RTC_TIME_FORMAT_AM_OR_24;
649 
650 	p_rtc_alarm->AlarmMask = ll_mask;
651 }
652 
rtc_stm32_get_ll_alrm_time(uint16_t id,struct rtc_time * timeptr)653 static inline void rtc_stm32_get_ll_alrm_time(uint16_t id, struct rtc_time *timeptr)
654 {
655 	if (id == RTC_STM32_ALRM_A) {
656 		timeptr->tm_sec = bcd2bin(LL_RTC_ALMA_GetSecond(RTC));
657 		timeptr->tm_min = bcd2bin(LL_RTC_ALMA_GetMinute(RTC));
658 		timeptr->tm_hour = bcd2bin(LL_RTC_ALMA_GetHour(RTC));
659 		timeptr->tm_wday = bcd2bin(LL_RTC_ALMA_GetWeekDay(RTC));
660 		timeptr->tm_mday = bcd2bin(LL_RTC_ALMA_GetDay(RTC));
661 		return;
662 	}
663 #if RTC_STM32_ALARMS_COUNT > 1
664 	if (id == RTC_STM32_ALRM_B) {
665 		timeptr->tm_sec = bcd2bin(LL_RTC_ALMB_GetSecond(RTC));
666 		timeptr->tm_min = bcd2bin(LL_RTC_ALMB_GetMinute(RTC));
667 		timeptr->tm_hour = bcd2bin(LL_RTC_ALMB_GetHour(RTC));
668 		timeptr->tm_wday = bcd2bin(LL_RTC_ALMB_GetWeekDay(RTC));
669 		timeptr->tm_mday = bcd2bin(LL_RTC_ALMB_GetDay(RTC));
670 	}
671 #endif /* RTC_STM32_ALARMS_COUNT > 1 */
672 }
673 
rtc_stm32_get_ll_alrm_mask(uint16_t id)674 static inline uint16_t rtc_stm32_get_ll_alrm_mask(uint16_t id)
675 {
676 	uint32_t ll_alarm_mask = 0;
677 	uint16_t zephyr_alarm_mask = 0;
678 	uint32_t week_day = 0;
679 
680 	/*
681 	 * STM32 RTC Alarm LL mask is set for all fields beyond the broadest one
682 	 * that's being matched with RTC calendar to trigger alarm periodically,
683 	 * the opposite of Zephyr RTC Alarm mask which is set for active fields.
684 	 */
685 
686 	if (id == RTC_STM32_ALRM_A) {
687 		ll_alarm_mask = LL_RTC_ALMA_GetMask(RTC);
688 	}
689 
690 #if RTC_STM32_ALARMS_COUNT > 1
691 	if (id == RTC_STM32_ALRM_B) {
692 		ll_alarm_mask = LL_RTC_ALMB_GetMask(RTC);
693 	}
694 #endif /* RTC_STM32_ALARMS_COUNT > 1 */
695 
696 	if ((ll_alarm_mask & RTC_STM32_ALRM_MASK_SECONDS) == 0x0) {
697 		zephyr_alarm_mask = RTC_ALARM_TIME_MASK_SECOND;
698 	}
699 	if ((ll_alarm_mask & RTC_STM32_ALRM_MASK_MINUTES) == 0x0) {
700 		zephyr_alarm_mask |= RTC_ALARM_TIME_MASK_MINUTE;
701 	}
702 	if ((ll_alarm_mask & RTC_STM32_ALRM_MASK_HOURS) == 0x0) {
703 		zephyr_alarm_mask |= RTC_ALARM_TIME_MASK_HOUR;
704 	}
705 	if ((ll_alarm_mask & RTC_STM32_ALRM_MASK_DATEWEEKDAY) == 0x0) {
706 		if (id == RTC_STM32_ALRM_A) {
707 			week_day = LL_RTC_ALMA_GetWeekDay(RTC);
708 		}
709 #if RTC_STM32_ALARMS_COUNT > 1
710 		if (id == RTC_STM32_ALRM_B) {
711 			week_day = LL_RTC_ALMB_GetWeekDay(RTC);
712 		}
713 #endif /* RTC_STM32_ALARMS_COUNT > 1 */
714 		if (week_day) {
715 			zephyr_alarm_mask |= RTC_ALARM_TIME_MASK_WEEKDAY;
716 		} else {
717 			zephyr_alarm_mask |= RTC_ALARM_TIME_MASK_MONTHDAY;
718 		}
719 	}
720 
721 	return zephyr_alarm_mask;
722 }
723 
rtc_stm32_alarm_get_supported_fields(const struct device * dev,uint16_t id,uint16_t * mask)724 static int rtc_stm32_alarm_get_supported_fields(const struct device *dev, uint16_t id,
725 					uint16_t *mask)
726 {
727 	if (mask == NULL) {
728 		LOG_ERR("NULL mask pointer");
729 		return -EINVAL;
730 	}
731 
732 	if ((id != RTC_STM32_ALRM_A) && (id != RTC_STM32_ALRM_B)) {
733 		LOG_ERR("invalid alarm ID %d", id);
734 		return -EINVAL;
735 	}
736 
737 	*mask = (uint16_t)RTC_STM32_SUPPORTED_ALARM_FIELDS;
738 
739 	return 0;
740 }
741 
rtc_stm32_alarm_get_time(const struct device * dev,uint16_t id,uint16_t * mask,struct rtc_time * timeptr)742 static int rtc_stm32_alarm_get_time(const struct device *dev, uint16_t id, uint16_t *mask,
743 			struct rtc_time *timeptr)
744 {
745 	struct rtc_stm32_data *data = dev->data;
746 	struct rtc_stm32_alrm *p_rtc_alrm;
747 	LL_RTC_AlarmTypeDef *p_ll_rtc_alarm;
748 	LL_RTC_TimeTypeDef *p_ll_rtc_alrm_time;
749 	int err = 0;
750 
751 	if ((mask == NULL) || (timeptr == NULL)) {
752 		LOG_ERR("NULL pointer");
753 		return -EINVAL;
754 	}
755 
756 	k_spinlock_key_t key = k_spin_lock(&data->lock);
757 
758 	if (id == RTC_STM32_ALRM_A) {
759 		p_rtc_alrm = &(data->rtc_alrm_a);
760 	} else if (id == RTC_STM32_ALRM_B) {
761 		p_rtc_alrm = &(data->rtc_alrm_b);
762 	} else {
763 		LOG_ERR("invalid alarm ID %d", id);
764 		err = -EINVAL;
765 		goto unlock;
766 	}
767 
768 	p_ll_rtc_alarm = &(p_rtc_alrm->ll_rtc_alrm);
769 	p_ll_rtc_alrm_time = &(p_ll_rtc_alarm->AlarmTime);
770 
771 	memset(timeptr, -1, sizeof(struct rtc_time));
772 
773 	rtc_stm32_get_ll_alrm_time(id, timeptr);
774 
775 	p_rtc_alrm->user_mask = rtc_stm32_get_ll_alrm_mask(id);
776 
777 	*mask = p_rtc_alrm->user_mask;
778 
779 	LOG_DBG("get alarm: mday = %d, wday = %d, hour = %d, min = %d, sec = %d, "
780 		"mask = 0x%04x", timeptr->tm_mday, timeptr->tm_wday, timeptr->tm_hour,
781 		timeptr->tm_min, timeptr->tm_sec, *mask);
782 
783 unlock:
784 	k_spin_unlock(&data->lock, key);
785 
786 	return err;
787 }
788 
rtc_stm32_alarm_set_time(const struct device * dev,uint16_t id,uint16_t mask,const struct rtc_time * timeptr)789 static int rtc_stm32_alarm_set_time(const struct device *dev, uint16_t id, uint16_t mask,
790 			const struct rtc_time *timeptr)
791 {
792 	struct rtc_stm32_data *data = dev->data;
793 	struct rtc_stm32_alrm *p_rtc_alrm;
794 	LL_RTC_AlarmTypeDef *p_ll_rtc_alarm;
795 	LL_RTC_TimeTypeDef *p_ll_rtc_alrm_time;
796 	int err = 0;
797 
798 	k_spinlock_key_t key = k_spin_lock(&data->lock);
799 
800 	if (id == RTC_STM32_ALRM_A) {
801 		p_rtc_alrm = &(data->rtc_alrm_a);
802 	} else if (id == RTC_STM32_ALRM_B) {
803 		p_rtc_alrm = &(data->rtc_alrm_b);
804 	} else {
805 		LOG_ERR("invalid alarm ID %d", id);
806 		err = -EINVAL;
807 		goto unlock;
808 	}
809 
810 	if ((mask == 0) && (timeptr == NULL)) {
811 		memset(&(p_rtc_alrm->ll_rtc_alrm), 0, sizeof(LL_RTC_AlarmTypeDef));
812 		p_rtc_alrm->user_callback = NULL;
813 		p_rtc_alrm->user_data = NULL;
814 		p_rtc_alrm->is_pending = false;
815 
816 		stm32_backup_domain_enable_access();
817 
818 		if (rtc_stm32_is_active_alarm(RTC, id)) {
819 			LL_RTC_DisableWriteProtection(RTC);
820 			rtc_stm32_disable_alarm(RTC, id);
821 			rtc_stm32_disable_interrupt_alarm(RTC, id);
822 			LL_RTC_EnableWriteProtection(RTC);
823 		}
824 		LOG_DBG("Alarm %d has been disabled", id);
825 		goto disable_bkup_access;
826 	}
827 
828 	if ((mask & ~RTC_STM32_SUPPORTED_ALARM_FIELDS) != 0) {
829 		LOG_ERR("unsupported alarm %d field mask 0x%04x", id, mask);
830 		err = -EINVAL;
831 		goto unlock;
832 	}
833 
834 	if (timeptr == NULL) {
835 		LOG_ERR("timeptr is invalid");
836 		err = -EINVAL;
837 		goto unlock;
838 	}
839 
840 	if (!rtc_utils_validate_rtc_time(timeptr, mask)) {
841 		LOG_DBG("One or multiple time values are invalid");
842 		err = -EINVAL;
843 		goto unlock;
844 	}
845 
846 	p_ll_rtc_alarm = &(p_rtc_alrm->ll_rtc_alrm);
847 	p_ll_rtc_alrm_time = &(p_ll_rtc_alarm->AlarmTime);
848 
849 	memset(p_ll_rtc_alrm_time, 0, sizeof(LL_RTC_TimeTypeDef));
850 	rtc_stm32_init_ll_alrm_struct(p_ll_rtc_alarm, timeptr, mask);
851 
852 	p_rtc_alrm->user_mask = mask;
853 
854 	LOG_DBG("set alarm %d : second = %d, min = %d, hour = %d,"
855 			" wday = %d, mday = %d, mask = 0x%04x",
856 			id, timeptr->tm_sec, timeptr->tm_min, timeptr->tm_hour,
857 			timeptr->tm_wday, timeptr->tm_mday, mask);
858 
859 	stm32_backup_domain_enable_access();
860 
861 	/* Disable the write protection for RTC registers */
862 	LL_RTC_DisableWriteProtection(RTC);
863 
864 	/* Disable ALARM so that the RTC_ISR_ALRAWF/RTC_ISR_ALRBWF is 0 */
865 	rtc_stm32_disable_alarm(RTC, id);
866 	rtc_stm32_disable_interrupt_alarm(RTC, id);
867 
868 #ifdef RTC_ISR_ALRAWF
869 	if (id == RTC_STM32_ALRM_A) {
870 		/* Wait till RTC ALRAWF flag is set before writing to RTC registers */
871 		while (!LL_RTC_IsActiveFlag_ALRAW(RTC)) {
872 			;
873 		}
874 	}
875 #endif /* RTC_ISR_ALRAWF */
876 
877 #ifdef RTC_ISR_ALRBWF
878 	if (id == RTC_STM32_ALRM_B) {
879 		/* Wait till RTC ALRBWF flag is set before writing to RTC registers */
880 		while (!LL_RTC_IsActiveFlag_ALRBW(RTC)) {
881 			;
882 		}
883 	}
884 #endif /* RTC_ISR_ALRBWF */
885 
886 	/* init Alarm */
887 	/* write protection is disabled & enabled again inside the LL_RTC_ALMx_Init function */
888 	if (rtc_stm32_init_alarm(RTC, LL_RTC_FORMAT_BCD, p_ll_rtc_alarm, id) != SUCCESS) {
889 		LOG_ERR("Could not initialize Alarm %d", id);
890 		err = -ECANCELED;
891 		goto disable_bkup_access;
892 	}
893 
894 	/* Disable the write protection for RTC registers */
895 	LL_RTC_DisableWriteProtection(RTC);
896 
897 	/* Enable Alarm */
898 	rtc_stm32_enable_alarm(RTC, id);
899 	/* Clear Alarm flag */
900 	rtc_stm32_clear_alarm_flag(RTC, id);
901 	/* Enable Alarm IT */
902 	rtc_stm32_enable_interrupt_alarm(RTC, id);
903 
904 	exti_enable_rtc_alarm_it(RTC_STM32_EXTI_LINE_NUM);
905 
906 	/* Enable the write protection for RTC registers */
907 	LL_RTC_EnableWriteProtection(RTC);
908 
909 disable_bkup_access:
910 	stm32_backup_domain_disable_access();
911 
912 unlock:
913 	k_spin_unlock(&data->lock, key);
914 
915 	if (id == RTC_STM32_ALRM_A) {
916 		LOG_DBG("Alarm A : %dh%dm%ds   mask = 0x%x",
917 			LL_RTC_ALMA_GetHour(RTC),
918 			LL_RTC_ALMA_GetMinute(RTC),
919 			LL_RTC_ALMA_GetSecond(RTC),
920 			LL_RTC_ALMA_GetMask(RTC));
921 	}
922 #ifdef RTC_ALARM_B
923 	if (id == RTC_STM32_ALRM_B) {
924 		LOG_DBG("Alarm B : %dh%dm%ds   mask = 0x%x",
925 			LL_RTC_ALMB_GetHour(RTC),
926 			LL_RTC_ALMB_GetMinute(RTC),
927 			LL_RTC_ALMB_GetSecond(RTC),
928 			LL_RTC_ALMB_GetMask(RTC));
929 	}
930 #endif /* #ifdef RTC_ALARM_B */
931 	return err;
932 }
933 
rtc_stm32_alarm_set_callback(const struct device * dev,uint16_t id,rtc_alarm_callback callback,void * user_data)934 static int rtc_stm32_alarm_set_callback(const struct device *dev, uint16_t id,
935 			rtc_alarm_callback callback, void *user_data)
936 {
937 	struct rtc_stm32_data *data = dev->data;
938 	struct rtc_stm32_alrm *p_rtc_alrm;
939 	int err = 0;
940 
941 	k_spinlock_key_t key = k_spin_lock(&data->lock);
942 
943 	if (id == RTC_STM32_ALRM_A) {
944 		p_rtc_alrm = &(data->rtc_alrm_a);
945 	} else if (id == RTC_STM32_ALRM_B) {
946 		p_rtc_alrm = &(data->rtc_alrm_b);
947 	} else {
948 		LOG_ERR("invalid alarm ID %d", id);
949 		err = -EINVAL;
950 		goto unlock;
951 	}
952 
953 	/* Passing the callback function and userdata filled by the user */
954 	p_rtc_alrm->user_callback = callback;
955 	p_rtc_alrm->user_data = user_data;
956 
957 unlock:
958 	k_spin_unlock(&data->lock, key);
959 
960 	return err;
961 }
962 
rtc_stm32_alarm_is_pending(const struct device * dev,uint16_t id)963 static int rtc_stm32_alarm_is_pending(const struct device *dev, uint16_t id)
964 {
965 	struct rtc_stm32_data *data = dev->data;
966 	struct rtc_stm32_alrm *p_rtc_alrm;
967 	int ret = 0;
968 
969 	k_spinlock_key_t key = k_spin_lock(&data->lock);
970 
971 	if (id == RTC_STM32_ALRM_A) {
972 		p_rtc_alrm = &(data->rtc_alrm_a);
973 	} else if (id == RTC_STM32_ALRM_B) {
974 		p_rtc_alrm = &(data->rtc_alrm_b);
975 	} else {
976 		LOG_ERR("invalid alarm ID %d", id);
977 		ret = -EINVAL;
978 		goto unlock;
979 	}
980 
981 	__disable_irq();
982 	ret = p_rtc_alrm->is_pending ? 1 : 0;
983 	p_rtc_alrm->is_pending = false;
984 	__enable_irq();
985 
986 unlock:
987 	k_spin_unlock(&data->lock, key);
988 	return ret;
989 }
990 #endif /* STM32_RTC_ALARM_ENABLED */
991 
992 #ifdef CONFIG_RTC_CALIBRATION
993 #if !defined(CONFIG_SOC_SERIES_STM32F2X) && \
994 	!(defined(CONFIG_SOC_SERIES_STM32L1X) && !defined(RTC_SMOOTHCALIB_SUPPORT))
rtc_stm32_set_calibration(const struct device * dev,int32_t calibration)995 static int rtc_stm32_set_calibration(const struct device *dev, int32_t calibration)
996 {
997 	ARG_UNUSED(dev);
998 
999 	/* Note : calibration is considered here to be ppb value to apply
1000 	 *        on clock period (not frequency) but with an opposite sign
1001 	 */
1002 
1003 	if ((calibration > MAX_PPB) || (calibration < MIN_PPB)) {
1004 		/* out of supported range */
1005 		return -EINVAL;
1006 	}
1007 
1008 	int32_t nb_pulses = PPB_TO_NB_PULSES(calibration);
1009 
1010 	/* we tested calibration against supported range
1011 	 * so theoretically nb_pulses is also within range
1012 	 */
1013 	__ASSERT_NO_MSG(nb_pulses <= MAX_CALP);
1014 	__ASSERT_NO_MSG(nb_pulses >= -MAX_CALM);
1015 
1016 	uint32_t calp, calm;
1017 
1018 	if (nb_pulses > 0) {
1019 		calp = LL_RTC_CALIB_INSERTPULSE_SET;
1020 		calm = MAX_CALP - nb_pulses;
1021 	} else {
1022 		calp = LL_RTC_CALIB_INSERTPULSE_NONE;
1023 		calm = -nb_pulses;
1024 	}
1025 
1026 	/* wait for recalibration to be ok if a previous recalibration occurred */
1027 	if (!WAIT_FOR(LL_RTC_IsActiveFlag_RECALP(RTC) == 0, 100000, k_msleep(1))) {
1028 		return -EIO;
1029 	}
1030 
1031 	stm32_backup_domain_enable_access();
1032 
1033 	LL_RTC_DisableWriteProtection(RTC);
1034 
1035 	MODIFY_REG(RTC->CALR, RTC_CALR_CALP | RTC_CALR_CALM, calp | calm);
1036 
1037 	LL_RTC_EnableWriteProtection(RTC);
1038 
1039 	stm32_backup_domain_disable_access();
1040 
1041 	return 0;
1042 }
1043 
rtc_stm32_get_calibration(const struct device * dev,int32_t * calibration)1044 static int rtc_stm32_get_calibration(const struct device *dev, int32_t *calibration)
1045 {
1046 	ARG_UNUSED(dev);
1047 
1048 	uint32_t calr = sys_read32((mem_addr_t) &RTC->CALR);
1049 
1050 	bool calp_enabled = READ_BIT(calr, RTC_CALR_CALP);
1051 	uint32_t calm = READ_BIT(calr, RTC_CALR_CALM);
1052 
1053 	int32_t nb_pulses = -((int32_t) calm);
1054 
1055 	if (calp_enabled) {
1056 		nb_pulses += MAX_CALP;
1057 	}
1058 
1059 	*calibration = NB_PULSES_TO_PPB(nb_pulses);
1060 
1061 	return 0;
1062 }
1063 #endif
1064 #endif /* CONFIG_RTC_CALIBRATION */
1065 
1066 static DEVICE_API(rtc, rtc_stm32_driver_api) = {
1067 	.set_time = rtc_stm32_set_time,
1068 	.get_time = rtc_stm32_get_time,
1069 #ifdef STM32_RTC_ALARM_ENABLED
1070 	.alarm_get_supported_fields = rtc_stm32_alarm_get_supported_fields,
1071 	.alarm_set_time = rtc_stm32_alarm_set_time,
1072 	.alarm_get_time = rtc_stm32_alarm_get_time,
1073 	.alarm_set_callback = rtc_stm32_alarm_set_callback,
1074 	.alarm_is_pending = rtc_stm32_alarm_is_pending,
1075 #endif /* STM32_RTC_ALARM_ENABLED */
1076 #ifdef CONFIG_RTC_CALIBRATION
1077 #if !defined(CONFIG_SOC_SERIES_STM32F2X) && \
1078 	!(defined(CONFIG_SOC_SERIES_STM32L1X) && !defined(RTC_SMOOTHCALIB_SUPPORT))
1079 	.set_calibration = rtc_stm32_set_calibration,
1080 	.get_calibration = rtc_stm32_get_calibration,
1081 #else
1082 #error RTC calibration for devices without smooth calibration feature is not supported yet
1083 #endif
1084 #endif /* CONFIG_RTC_CALIBRATION */
1085 };
1086 
1087 static const struct stm32_pclken rtc_clk[] = STM32_DT_INST_CLOCKS(0);
1088 
1089 BUILD_ASSERT(DT_INST_CLOCKS_HAS_IDX(0, 1), "RTC source clock not defined in the device tree");
1090 
1091 #if DT_INST_CLOCKS_CELL_BY_IDX(0, 1, bus) == STM32_SRC_HSE
1092 #if STM32_HSE_FREQ % MHZ(1) != 0
1093 #error RTC clock source HSE frequency should be whole MHz
1094 #elif STM32_HSE_FREQ < MHZ(16) && defined(LL_RCC_RTC_HSE_DIV_16)
1095 #define RTC_HSE_PRESCALER LL_RCC_RTC_HSE_DIV_16
1096 #define RTC_HSE_FREQUENCY (STM32_HSE_FREQ / 16)
1097 #elif STM32_HSE_FREQ < MHZ(32) && defined(LL_RCC_RTC_HSE_DIV_32)
1098 #define RTC_HSE_PRESCALER LL_RCC_RTC_HSE_DIV_32
1099 #define RTC_HSE_FREQUENCY (STM32_HSE_FREQ / 32)
1100 #elif STM32_HSE_FREQ < MHZ(64) && defined(LL_RCC_RTC_HSE_DIV_64)
1101 #define RTC_HSE_PRESCALER LL_RCC_RTC_HSE_DIV_64
1102 #define RTC_HSE_FREQUENCY (STM32_HSE_FREQ / 64)
1103 #else
1104 #error RTC does not support HSE frequency
1105 #endif
1106 #define RTC_HSE_ASYNC_PRESCALER 125
1107 #define RTC_HSE_SYNC_PRESCALER  (RTC_HSE_FREQUENCY / RTC_HSE_ASYNC_PRESCALER)
1108 #endif /* DT_INST_CLOCKS_CELL_BY_IDX(0, 1, bus) == STM32_SRC_HSE */
1109 
1110 static const struct rtc_stm32_config rtc_config = {
1111 #if DT_INST_CLOCKS_CELL_BY_IDX(0, 1, bus) == STM32_SRC_LSI
1112 	/* prescaler values for LSI @ 32 KHz */
1113 	.async_prescaler = DT_INST_PROP_OR(0, async_prescaler, 0x7F),
1114 	.sync_prescaler = DT_INST_PROP_OR(0, sync_prescaler, 0x00F9),
1115 #elif DT_INST_CLOCKS_CELL_BY_IDX(0, 1, bus) == STM32_SRC_LSE
1116 	/* prescaler values for LSE @ 32768 Hz */
1117 	.async_prescaler = DT_INST_PROP_OR(0, async_prescaler, 0x7F),
1118 	.sync_prescaler = DT_INST_PROP_OR(0, sync_prescaler, 0x00FF),
1119 #elif DT_INST_CLOCKS_CELL_BY_IDX(0, 1, bus) == STM32_SRC_HSE
1120 	/* prescaler values for HSE */
1121 	.async_prescaler = DT_INST_PROP_OR(0, async_prescaler, RTC_HSE_ASYNC_PRESCALER - 1),
1122 	.sync_prescaler = DT_INST_PROP_OR(0, sync_prescaler, RTC_HSE_SYNC_PRESCALER - 1),
1123 	.hse_prescaler = DT_INST_PROP_OR(0, hse_prescaler, RTC_HSE_PRESCALER),
1124 #else
1125 #error Invalid RTC SRC
1126 #endif
1127 	.pclken = rtc_clk,
1128 #if DT_INST_NODE_HAS_PROP(0, calib_out_freq)
1129 	.cal_out_freq = _CONCAT(_CONCAT(LL_RTC_CALIB_OUTPUT_, DT_INST_PROP(0, calib_out_freq)), HZ),
1130 #endif
1131 };
1132 
1133 static struct rtc_stm32_data rtc_data;
1134 
1135 DEVICE_DT_INST_DEFINE(0, &rtc_stm32_init, NULL, &rtc_data, &rtc_config, PRE_KERNEL_1,
1136 		      CONFIG_RTC_INIT_PRIORITY, &rtc_stm32_driver_api);
1137