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