Skip to content

Commit 742261d

Browse files
Martinhoff-makerkartben
authored andcommitted
drivers: rtc: add silabs siwx91x rtc driver
Add the support of silabs siwx91x basic rtc driver. Signed-off-by: Martin Hoff <[email protected]>
1 parent 53d21f6 commit 742261d

File tree

8 files changed

+185
-0
lines changed

8 files changed

+185
-0
lines changed

drivers/clock_control/clock_control_silabs_siwx91x.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,10 @@ static int siwx91x_clock_on(const struct device *dev, clock_control_subsys_t sys
8585
case SIWX91X_CLK_QSPI:
8686
RSI_CLK_Qspi2ClkConfig(M4CLK, QSPI_ULPREFCLK, 0, 0, 0);
8787
break;
88+
case SIWX91X_CLK_RTC:
89+
/* Already done in sl_calendar_init()*/
90+
RSI_PS_NpssPeriPowerUp(SLPSS_PWRGATE_ULP_MCURTC | SLPSS_PWRGATE_ULP_TIMEPERIOD);
91+
break;
8892
default:
8993
return -EINVAL;
9094
}

drivers/rtc/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,3 +35,4 @@ zephyr_library_sources_ifdef(CONFIG_RTC_RV8803 rtc_rv8803.c)
3535
zephyr_library_sources_ifdef(CONFIG_RTC_BQ32002 rtc_bq32002.c)
3636
zephyr_library_sources_ifdef(CONFIG_RTC_RX8130CE rtc_rx8130ce.c)
3737
zephyr_library_sources_ifdef(CONFIG_RTC_DS1337 rtc_ds1337.c)
38+
zephyr_library_sources_ifdef(CONFIG_RTC_SILABS_SIWX91X rtc_silabs_siwx91x.c)

drivers/rtc/Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,5 +67,6 @@ source "drivers/rtc/Kconfig.rv8803"
6767
source "drivers/rtc/Kconfig.bq32002"
6868
source "drivers/rtc/Kconfig.rx8130ce"
6969
source "drivers/rtc/Kconfig.ds1337"
70+
source "drivers/rtc/Kconfig.siwx91x"
7071

7172
endif # RTC

drivers/rtc/Kconfig.siwx91x

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
# Copyright (c) 2025 Silicon Laboratories Inc.
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
config RTC_SILABS_SIWX91X
5+
bool "Silabs siwx91x RTC driver"
6+
default y
7+
depends on DT_HAS_SILABS_SIWX91X_RTC_ENABLED
8+
help
9+
Build the RTC driver for the Silabs SIWX91X SoC (Calendar
10+
hardware block as described in the reference manual).

drivers/rtc/rtc_silabs_siwx91x.c

Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
/*
2+
* SPDX-License-Identifier: Apache-2.0
3+
*
4+
* Copyright (c) 2025 Silicon Laboratories Inc.
5+
*/
6+
7+
#include <zephyr/devicetree.h>
8+
#include <zephyr/drivers/clock_control.h>
9+
#include <zephyr/drivers/rtc.h>
10+
#include <zephyr/logging/log.h>
11+
#include <zephyr/pm/device.h>
12+
#include <zephyr/sys/util.h>
13+
#include "rtc_utils.h"
14+
#include "sl_si91x_calendar.h"
15+
16+
#define DT_DRV_COMPAT silabs_siwx91x_rtc
17+
18+
LOG_MODULE_REGISTER(siwx91x_rtc, CONFIG_RTC_LOG_LEVEL);
19+
20+
#define TM_YEAR_REF 1900
21+
#define SIWX91X_RTC_YEAR_MAX 2399
22+
#define SIWX91X_RTC_YEAR_MIN 2000
23+
24+
struct siwx91x_rtc_config {
25+
const struct device *clock_dev;
26+
clock_control_subsys_t clock_subsys;
27+
};
28+
struct siwx91x_rtc_data {
29+
struct k_spinlock lock;
30+
};
31+
32+
static void rtc_time_to_siwx91x_time_set(const struct rtc_time *tm,
33+
sl_calendar_datetime_config_t *cldr)
34+
{
35+
int full_year = tm->tm_year + TM_YEAR_REF;
36+
37+
cldr->Year = (full_year % 100);
38+
cldr->Century = (full_year >= 2000) ? (full_year - 2000) / 100 : 0;
39+
cldr->Month = tm->tm_mon + 1;
40+
cldr->Day = tm->tm_mday;
41+
cldr->DayOfWeek = (RTC_DAY_OF_WEEK_T)tm->tm_wday;
42+
cldr->Hour = tm->tm_hour;
43+
cldr->Minute = tm->tm_min;
44+
cldr->Second = tm->tm_sec;
45+
cldr->MilliSeconds = tm->tm_nsec / NSEC_PER_MSEC;
46+
}
47+
48+
static void siwx91x_time_to_rtc_time_set(const sl_calendar_datetime_config_t *cldr,
49+
struct rtc_time *tm)
50+
{
51+
int full_year = 2000 + (cldr->Century * 100) + cldr->Year;
52+
53+
tm->tm_year = full_year - TM_YEAR_REF;
54+
tm->tm_mon = cldr->Month - 1;
55+
tm->tm_mday = cldr->Day;
56+
tm->tm_wday = (int)cldr->DayOfWeek;
57+
tm->tm_hour = cldr->Hour;
58+
tm->tm_min = cldr->Minute;
59+
tm->tm_sec = cldr->Second;
60+
tm->tm_nsec = cldr->MilliSeconds * NSEC_PER_MSEC;
61+
}
62+
63+
static int siwx91x_rtc_set_time(const struct device *dev, const struct rtc_time *timeptr)
64+
{
65+
sl_calendar_datetime_config_t siwx91x_time = {};
66+
struct siwx91x_rtc_data *data = dev->data;
67+
int year;
68+
int ret;
69+
70+
year = timeptr->tm_year + TM_YEAR_REF;
71+
if (year < SIWX91X_RTC_YEAR_MIN || year > SIWX91X_RTC_YEAR_MAX) {
72+
return -EINVAL;
73+
}
74+
75+
k_spinlock_key_t key = k_spin_lock(&data->lock);
76+
77+
LOG_DBG("Set RTC time: year = %d, mon = %d, mday = %d, wday = %d, hour = %d, "
78+
"min = %d, sec = %d",
79+
timeptr->tm_year, timeptr->tm_mon, timeptr->tm_mday, timeptr->tm_wday,
80+
timeptr->tm_hour, timeptr->tm_min, timeptr->tm_sec);
81+
82+
rtc_time_to_siwx91x_time_set(timeptr, &siwx91x_time);
83+
84+
ret = sl_si91x_calendar_set_date_time(&siwx91x_time);
85+
if (ret) {
86+
LOG_WRN("Set Timer returned an error - %d!", ret);
87+
}
88+
89+
k_spin_unlock(&data->lock, key);
90+
91+
return ret;
92+
}
93+
94+
static int siwx91x_rtc_get_time(const struct device *dev, struct rtc_time *timeptr)
95+
{
96+
sl_calendar_datetime_config_t siwx91x_time = {};
97+
struct siwx91x_rtc_data *data = dev->data;
98+
int ret;
99+
100+
k_spinlock_key_t key = k_spin_lock(&data->lock);
101+
102+
ret = sl_si91x_calendar_get_date_time(&siwx91x_time);
103+
if (ret != 0) {
104+
LOG_WRN("Get Timer returned an error - %d!", ret);
105+
goto unlock;
106+
}
107+
108+
siwx91x_time_to_rtc_time_set(&siwx91x_time, timeptr);
109+
110+
LOG_DBG("get time: year = %d, mon = %d, mday = %d, wday = %d, hour = %d, "
111+
"min = %d, sec = %d",
112+
timeptr->tm_year, timeptr->tm_mon, timeptr->tm_mday, timeptr->tm_wday,
113+
timeptr->tm_hour, timeptr->tm_min, timeptr->tm_sec);
114+
115+
unlock:
116+
k_spin_unlock(&data->lock, key);
117+
118+
return ret;
119+
}
120+
121+
static int siwx91x_rtc_init(const struct device *dev)
122+
{
123+
const struct siwx91x_rtc_config *config = dev->config;
124+
int ret;
125+
126+
ret = clock_control_on(config->clock_dev, config->clock_subsys);
127+
if (ret) {
128+
return ret;
129+
}
130+
131+
sl_si91x_calendar_init();
132+
133+
return 0;
134+
}
135+
136+
static DEVICE_API(rtc, siwx91x_rtc_driver_api) = {
137+
.set_time = siwx91x_rtc_set_time,
138+
.get_time = siwx91x_rtc_get_time,
139+
};
140+
141+
#define SIWX91X_RTC_INIT(inst) \
142+
static const struct siwx91x_rtc_config siwx91x_rtc_config_##inst = { \
143+
.clock_dev = DEVICE_DT_GET(DT_INST_CLOCKS_CTLR(inst)), \
144+
.clock_subsys = (clock_control_subsys_t)DT_INST_PHA(inst, clocks, clkid), \
145+
}; \
146+
\
147+
static struct siwx91x_rtc_data siwx91x_rtc_data##inst; \
148+
\
149+
DEVICE_DT_INST_DEFINE(inst, &siwx91x_rtc_init, NULL, &siwx91x_rtc_data##inst, \
150+
&siwx91x_rtc_config_##inst, POST_KERNEL, CONFIG_RTC_INIT_PRIORITY, \
151+
&siwx91x_rtc_driver_api);
152+
153+
DT_INST_FOREACH_STATUS_OKAY(SIWX91X_RTC_INIT)
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# Copyright (c) 2025 Silicon Labatoratories Inc.
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
description: Silabs Siwx91x RTC (Real-Time Counter)
5+
6+
compatible: "silabs,siwx91x-rtc"
7+
8+
include: rtc.yaml
9+
10+
properties:
11+
reg:
12+
required: true

include/zephyr/dt-bindings/clock/silabs/siwx91x-clock.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,5 +16,6 @@
1616
#define SIWX91X_CLK_PWM 9
1717
#define SIWX91X_CLK_GSPI 10
1818
#define SIWX91X_CLK_QSPI 11
19+
#define SIWX91X_CLK_RTC 12
1920

2021
#endif

modules/hal_silabs/wiseconnect/CMakeLists.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,10 @@ zephyr_library_sources(
4949
${WISECONNECT_DIR}/components/device/silabs/si91x/mcu/drivers/systemlevel/src/rsi_pll.c
5050
${WISECONNECT_DIR}/components/device/silabs/si91x/mcu/drivers/systemlevel/src/rsi_ulpss_clk.c
5151
${WISECONNECT_DIR}/components/device/silabs/si91x/mcu/drivers/systemlevel/src/rsi_wwdt.c
52+
${WISECONNECT_DIR}/components/device/silabs/si91x/mcu/drivers/systemlevel/src/rsi_rtc.c
53+
${WISECONNECT_DIR}/components/device/silabs/si91x/mcu/drivers/systemlevel/src/rsi_time_period.c
5254
${WISECONNECT_DIR}/components/device/silabs/si91x/mcu/drivers/service/clock_manager/src/sl_si91x_clock_manager.c
55+
${WISECONNECT_DIR}/components/device/silabs/si91x/mcu/drivers/unified_api/src/sl_si91x_calendar.c
5356
${WISECONNECT_DIR}/components/device/silabs/si91x/mcu/drivers/unified_api/src/sl_si91x_driver_gpio.c
5457
${WISECONNECT_DIR}/components/device/silabs/si91x/mcu/drivers/unified_api/src/sl_si91x_pwm.c
5558
${WISECONNECT_DIR}/components/device/silabs/si91x/mcu/drivers/unified_peripheral_drivers/src/sl_si91x_peripheral_gpio.c

0 commit comments

Comments
 (0)