1
1
/*
2
- * Copyright 2024 NXP
2
+ * Copyright 2024-2025 NXP
3
3
*
4
4
* SPDX-License-Identifier: Apache-2.0
5
5
*/
@@ -15,7 +15,9 @@ struct nxp_irtc_config {
15
15
RTC_Type * base ;
16
16
void (* irq_config_func )(const struct device * dev );
17
17
bool is_output_clock_enabled ;
18
+ #if DT_ANY_INST_HAS_PROP_STATUS_OKAY (clock_src )
18
19
uint8_t clock_src ;
20
+ #endif
19
21
uint8_t alarm_match_flag ;
20
22
};
21
23
@@ -25,15 +27,15 @@ struct nxp_irtc_data {
25
27
rtc_alarm_callback alarm_callback ;
26
28
void * alarm_user_data ;
27
29
uint16_t alarm_mask ;
30
+ bool alarm_pending ;
28
31
#endif /* CONFIG_RTC_ALARM */
29
32
};
30
33
31
34
/* The IRTC Offset is 2112 instead of 1900 [2112 - 1900] -> [212] */
32
35
#define RTC_NXP_IRTC_YEAR_OFFSET 212
33
36
34
- #define RTC_NXP_GET_REG_FIELD (_reg , _name , _field ) \
35
- ((_reg->_name & RTC_##_name##_##_field##_MASK) >> \
36
- RTC_##_name##_##_field##_SHIFT)
37
+ #define RTC_NXP_GET_REG_FIELD (_reg , _name , _field ) \
38
+ ((_reg->_name & RTC_##_name##_##_field##_MASK) >> RTC_##_name##_##_field##_SHIFT)
37
39
38
40
/*
39
41
* The runtime where this is accessed is unknown so we force a lock on the registers then force an
@@ -62,6 +64,12 @@ static void nxp_irtc_unlock_registers(RTC_Type *reg)
62
64
63
65
static int nxp_irtc_set_time (const struct device * dev , const struct rtc_time * timeptr )
64
66
{
67
+ #if DT_PROP (DT_ALIAS (rtc ), share_counter )
68
+ ARG_UNUSED (dev );
69
+ ARG_UNUSED (timeptr );
70
+
71
+ return - EPERM ;
72
+ #else
65
73
const struct nxp_irtc_config * config = dev -> config ;
66
74
struct nxp_irtc_data * data = dev -> data ;
67
75
RTC_Type * irtc_reg = config -> base ;
@@ -79,12 +87,12 @@ static int nxp_irtc_set_time(const struct device *dev, const struct rtc_time *ti
79
87
nxp_irtc_unlock_registers (irtc_reg );
80
88
irtc_reg -> SECONDS = RTC_SECONDS_SEC_CNT (timeptr -> tm_sec );
81
89
82
- irtc_reg -> HOURMIN = RTC_HOURMIN_MIN_CNT ( timeptr -> tm_min ) |
83
- RTC_HOURMIN_HOUR_CNT (timeptr -> tm_hour );
90
+ irtc_reg -> HOURMIN =
91
+ RTC_HOURMIN_MIN_CNT ( timeptr -> tm_min ) | RTC_HOURMIN_HOUR_CNT (timeptr -> tm_hour );
84
92
85
93
/* 1 is valid for rtc_time.tm_wday property but is out of bounds for IRTC registers */
86
94
irtc_reg -> DAYS = RTC_DAYS_DAY_CNT (timeptr -> tm_mday ) |
87
- (timeptr -> tm_wday == -1 ? 0 : RTC_DAYS_DOW (timeptr -> tm_wday ));
95
+ (timeptr -> tm_wday == -1 ? 0 : RTC_DAYS_DOW (timeptr -> tm_wday ));
88
96
89
97
irtc_reg -> YEARMON = RTC_YEARMON_MON_CNT (calc_month ) | RTC_YEARMON_YROFST (calc_year );
90
98
@@ -96,6 +104,7 @@ static int nxp_irtc_set_time(const struct device *dev, const struct rtc_time *ti
96
104
irq_unlock (key );
97
105
98
106
return 0 ;
107
+ #endif
99
108
}
100
109
101
110
static int nxp_irtc_get_time (const struct device * dev , struct rtc_time * timeptr )
@@ -112,8 +121,8 @@ static int nxp_irtc_get_time(const struct device *dev, struct rtc_time *timeptr)
112
121
timeptr -> tm_wday = RTC_NXP_GET_REG_FIELD (irtc_reg , DAYS , DOW );
113
122
timeptr -> tm_mday = RTC_NXP_GET_REG_FIELD (irtc_reg , DAYS , DAY_CNT );
114
123
timeptr -> tm_mon = RTC_NXP_GET_REG_FIELD (irtc_reg , YEARMON , MON_CNT ) - 1 ;
115
- timeptr -> tm_year = ( int8_t ) RTC_NXP_GET_REG_FIELD ( irtc_reg , YEARMON , YROFST ) +
116
- RTC_NXP_IRTC_YEAR_OFFSET ;
124
+ timeptr -> tm_year =
125
+ ( int8_t ) RTC_NXP_GET_REG_FIELD ( irtc_reg , YEARMON , YROFST ) + RTC_NXP_IRTC_YEAR_OFFSET ;
117
126
if (data -> is_dst_enabled ) {
118
127
timeptr -> tm_isdst =
119
128
((irtc_reg -> CTRL & RTC_CTRL_DST_EN_MASK ) >> RTC_CTRL_DST_EN_SHIFT );
@@ -156,6 +165,8 @@ static int nxp_irtc_alarm_set_time(const struct device *dev, uint16_t id, uint16
156
165
return - EINVAL ;
157
166
}
158
167
168
+ data -> alarm_pending = false;
169
+
159
170
uint32_t key = irq_lock ();
160
171
161
172
nxp_irtc_unlock_registers (irtc_reg );
@@ -186,19 +197,25 @@ static int nxp_irtc_alarm_set_time(const struct device *dev, uint16_t id, uint16
186
197
}
187
198
188
199
/* Clearing out the ALARM Flag Field then setting the correct value */
189
- irtc_reg -> CTRL &= ~(0xC );
190
- switch (mask ) {
191
- case 0x0F :
192
- irtc_reg -> CTRL |= RTC_CTRL_ALM_MATCH (0x4 );
200
+ irtc_reg -> CTRL &= ~((uint16_t )RTC_CTRL_ALM_MATCH_MASK );
201
+ uint8_t year_month_day_mask = (mask & (BIT (3 ) | BIT (4 ) | BIT (5 ))) >> 3 ;
202
+
203
+ switch (year_month_day_mask ) {
204
+ case 0x00 :
205
+ irtc_reg -> CTRL |= RTC_CTRL_ALM_MATCH (0x0 );
206
+ break ;
207
+ case 0x01 :
208
+ irtc_reg -> CTRL |= RTC_CTRL_ALM_MATCH (0x1 );
193
209
break ;
194
- case 0x1F :
195
- irtc_reg -> CTRL |= RTC_CTRL_ALM_MATCH (0x8 );
210
+ case 0x03 :
211
+ irtc_reg -> CTRL |= RTC_CTRL_ALM_MATCH (0x2 );
196
212
break ;
197
- case 0x3F :
198
- irtc_reg -> CTRL |= RTC_CTRL_ALM_MATCH (0xC );
213
+ case 0x07 :
214
+ irtc_reg -> CTRL |= RTC_CTRL_ALM_MATCH (0x3 );
199
215
break ;
200
216
default :
201
- irtc_reg -> CTRL |= RTC_CTRL_ALM_MATCH (0x0 );
217
+ irq_unlock (key );
218
+ return - EINVAL ;
202
219
}
203
220
204
221
/* Enabling Alarm Interrupts */
@@ -218,39 +235,45 @@ static int nxp_irtc_alarm_get_time(const struct device *dev, uint16_t id, uint16
218
235
RTC_Type * irtc_reg = config -> base ;
219
236
uint16_t curr_alarm_mask = data -> alarm_mask ;
220
237
uint16_t return_mask = 0 ;
238
+ uint16_t tmp_hourmin = irtc_reg -> ALM_HOURMIN ;
239
+ uint16_t tmp_yearmon = irtc_reg -> ALM_YEARMON ;
221
240
222
241
if (id != 0 || !timeptr ) {
223
242
return - EINVAL ;
224
243
}
225
244
245
+ memset (timeptr , 0 , sizeof (struct rtc_time ));
246
+
226
247
if (curr_alarm_mask & RTC_ALARM_TIME_MASK_SECOND ) {
227
- timeptr -> tm_sec = RTC_NXP_GET_REG_FIELD (irtc_reg , ALM_SECONDS , ALM_SEC ) ;
248
+ timeptr -> tm_sec = (irtc_reg -> ALM_SECONDS ) & RTC_ALM_SECONDS_ALM_SEC_MASK ;
228
249
return_mask |= RTC_ALARM_TIME_MASK_SECOND ;
229
250
}
230
251
231
252
if (curr_alarm_mask & RTC_ALARM_TIME_MASK_MINUTE ) {
232
- timeptr -> tm_min = RTC_NXP_GET_REG_FIELD ( irtc_reg , HOURMIN , MIN_CNT ) ;
253
+ timeptr -> tm_min = tmp_hourmin & RTC_ALM_HOURMIN_ALM_MIN_MASK ;
233
254
return_mask |= RTC_ALARM_TIME_MASK_MINUTE ;
234
255
}
235
256
236
257
if (curr_alarm_mask & RTC_ALARM_TIME_MASK_HOUR ) {
237
- timeptr -> tm_hour = RTC_NXP_GET_REG_FIELD (irtc_reg , HOURMIN , HOUR_CNT );
258
+ timeptr -> tm_hour = ((tmp_hourmin & RTC_ALM_HOURMIN_ALM_HOUR_MASK ) >>
259
+ RTC_ALM_HOURMIN_ALM_HOUR_SHIFT );
238
260
return_mask |= RTC_ALARM_TIME_MASK_HOUR ;
239
261
}
240
262
241
263
if (curr_alarm_mask & RTC_ALARM_TIME_MASK_MONTHDAY ) {
242
- timeptr -> tm_mday = RTC_NXP_GET_REG_FIELD (irtc_reg , DAYS , DAY_CNT ) ;
264
+ timeptr -> tm_mday = (irtc_reg -> ALM_DAYS ) & RTC_ALM_DAYS_ALM_DAY_MASK ;
243
265
return_mask |= RTC_ALARM_TIME_MASK_MONTHDAY ;
244
266
}
245
267
246
268
if (curr_alarm_mask & RTC_ALARM_TIME_MASK_MONTH ) {
247
- timeptr -> tm_mon = RTC_NXP_GET_REG_FIELD ( irtc_reg , YEARMON , MON_CNT ) - 1 ;
269
+ timeptr -> tm_mon = ( tmp_yearmon & RTC_ALM_YEARMON_ALM_MON_MASK ) - 1 ;
248
270
return_mask |= RTC_ALARM_TIME_MASK_MONTH ;
249
271
}
250
272
251
273
if (curr_alarm_mask & RTC_ALARM_TIME_MASK_YEAR ) {
252
- timeptr -> tm_year = (int8_t )RTC_NXP_GET_REG_FIELD (irtc_reg , YEARMON , YROFST ) +
253
- RTC_NXP_IRTC_YEAR_OFFSET ;
274
+ timeptr -> tm_year = (int8_t )((tmp_yearmon & RTC_ALM_YEARMON_ALM_YEAR_MASK ) >>
275
+ RTC_ALM_YEARMON_ALM_YEAR_SHIFT ) +
276
+ RTC_NXP_IRTC_YEAR_OFFSET ;
254
277
return_mask |= RTC_ALARM_TIME_MASK_YEAR ;
255
278
}
256
279
@@ -262,13 +285,18 @@ static int nxp_irtc_alarm_get_time(const struct device *dev, uint16_t id, uint16
262
285
static int nxp_irtc_alarm_is_pending (const struct device * dev , uint16_t id )
263
286
{
264
287
struct nxp_irtc_data * data = dev -> data ;
265
- RTC_Type * irtc_reg = config -> base ;
288
+ int ret = 0 ;
266
289
267
290
if (id != 0 ) {
268
291
return - EINVAL ;
269
292
}
270
293
271
- return RTC_ISR_ALM_IS (0x4 );
294
+ __disable_irq ();
295
+ ret = data -> alarm_pending ? 1 : 0 ;
296
+ data -> alarm_pending = false;
297
+ __enable_irq ();
298
+
299
+ return ret ;
272
300
}
273
301
274
302
static int nxp_irtc_alarm_set_callback (const struct device * dev , uint16_t id ,
@@ -325,12 +353,32 @@ static int nxp_irtc_init(const struct device *dev)
325
353
{
326
354
const struct nxp_irtc_config * config = dev -> config ;
327
355
RTC_Type * irtc_reg = config -> base ;
356
+ uint16_t reg = 0 ;
357
+ #ifdef CONFIG_RTC_ALARM
358
+ struct nxp_irtc_data * data = dev -> data ;
359
+ #endif
328
360
329
361
nxp_irtc_unlock_registers (irtc_reg );
330
362
331
- /* set the control register bits */
332
- irtc_reg -> CTRL = RTC_CTRL_CLK_SEL (config -> clock_src ) |
333
- RTC_CTRL_CLKO_DIS (!config -> is_output_clock_enabled );
363
+ reg = irtc_reg -> CTRL ;
364
+ reg &= ~(uint16_t )RTC_CTRL_CLKO_DIS_MASK ;
365
+ #if DT_ANY_INST_HAS_PROP_STATUS_OKAY (clock_src )
366
+ reg &= ~(uint16_t )RTC_CTRL_CLK_SEL_MASK ;
367
+ #endif
368
+
369
+ reg |= RTC_CTRL_CLKO_DIS (!config -> is_output_clock_enabled );
370
+ #if DT_ANY_INST_HAS_PROP_STATUS_OKAY (clock_src )
371
+ reg |= RTC_CTRL_CLK_SEL (config -> clock_src );
372
+ #endif
373
+
374
+ irtc_reg -> CTRL = reg ;
375
+
376
+ #ifdef CONFIG_RTC_ALARM
377
+ data -> alarm_callback = NULL ;
378
+ data -> alarm_user_data = NULL ;
379
+ data -> alarm_mask = 0 ;
380
+ data -> alarm_pending = false;
381
+ #endif
334
382
335
383
config -> irq_config_func (dev );
336
384
@@ -348,9 +396,11 @@ static void nxp_irtc_isr(const struct device *dev)
348
396
nxp_irtc_unlock_registers (irtc_reg );
349
397
/* Clearing ISR Register since w1c */
350
398
irtc_reg -> ISR = irtc_reg -> ISR ;
351
-
352
399
if (data -> alarm_callback ) {
353
400
data -> alarm_callback (dev , 0 , data -> alarm_user_data );
401
+ data -> alarm_pending = false;
402
+ } else {
403
+ data -> alarm_pending = true;
354
404
}
355
405
irq_unlock (key );
356
406
#endif /* CONFIG_RTC_ALARM */
@@ -375,17 +425,40 @@ static DEVICE_API(rtc, rtc_nxp_irtc_driver_api) = {
375
425
#endif /* CONFIG_RTC_CALIBRATION */
376
426
};
377
427
378
- #define RTC_NXP_IRTC_DEVICE_INIT (n ) \
428
+ #define RTC_NXP_IRTC_IRQ_CONNECT (n , m ) \
429
+ do { \
430
+ IRQ_CONNECT(DT_INST_IRQ_BY_IDX(n, m, irq), DT_INST_IRQ_BY_IDX(n, m, priority), \
431
+ nxp_irtc_isr, DEVICE_DT_INST_GET(n), 0); \
432
+ irq_enable(DT_INST_IRQ_BY_IDX(n, m, irq)); \
433
+ } while (false)
434
+
435
+ #if DT_INST_IRQ_HAS_IDX (0 , 1 )
436
+ #define NXP_IRTC_CONFIG_FUNC (n ) \
379
437
static void nxp_irtc_config_func_##n(const struct device *dev) \
380
438
{ \
381
- IRQ_CONNECT(DT_INST_IRQN(n), DT_INST_IRQ(n, priority), nxp_irtc_isr, \
382
- DEVICE_DT_INST_GET(n), 0); \
383
- irq_enable(DT_INST_IRQN(n)); \
384
- } \
439
+ RTC_NXP_IRTC_IRQ_CONNECT(n, 0); \
440
+ RTC_NXP_IRTC_IRQ_CONNECT(n, 1); \
441
+ }
442
+ #else
443
+ #define NXP_IRTC_CONFIG_FUNC (n ) \
444
+ static void nxp_irtc_config_func_##n(const struct device *dev) \
445
+ { \
446
+ RTC_NXP_IRTC_IRQ_CONNECT(n, 0); \
447
+ }
448
+ #endif
449
+
450
+ #if DT_ANY_INST_HAS_PROP_STATUS_OKAY (clock_src )
451
+ #define NXP_IRTC_CLOCK_SELECTION_INIT (n ) .clock_src = DT_INST_PROP(n, clock_src),
452
+ #else
453
+ #define NXP_IRTC_CLOCK_SELECTION_INIT (n )
454
+ #endif
455
+
456
+ #define RTC_NXP_IRTC_DEVICE_INIT (n ) \
457
+ NXP_IRTC_CONFIG_FUNC(n) \
385
458
static const struct nxp_irtc_config nxp_irtc_config_##n = { \
386
459
.base = (RTC_Type *)DT_INST_REG_ADDR(n), \
387
- .clock_src = DT_INST_PROP(n, clock_src), \
388
- .is_output_clock_enabled = DT_INST_PROP(n, output_clk_en), \
460
+ NXP_IRTC_CLOCK_SELECTION_INIT(n) \
461
+ .is_output_clock_enabled = DT_INST_PROP(n, output_clk_en), \
389
462
.irq_config_func = nxp_irtc_config_func_##n, \
390
463
}; \
391
464
\
0 commit comments