drivers: rtc: add silabs siwx91x rtc driver
Add the support of silabs siwx91x basic rtc driver. Signed-off-by: Martin Hoff <martin.hoff@silabs.com>
This commit is contained in:
parent
53d21f6d3d
commit
742261ddaa
8 changed files with 185 additions and 0 deletions
|
@ -85,6 +85,10 @@ static int siwx91x_clock_on(const struct device *dev, clock_control_subsys_t sys
|
||||||
case SIWX91X_CLK_QSPI:
|
case SIWX91X_CLK_QSPI:
|
||||||
RSI_CLK_Qspi2ClkConfig(M4CLK, QSPI_ULPREFCLK, 0, 0, 0);
|
RSI_CLK_Qspi2ClkConfig(M4CLK, QSPI_ULPREFCLK, 0, 0, 0);
|
||||||
break;
|
break;
|
||||||
|
case SIWX91X_CLK_RTC:
|
||||||
|
/* Already done in sl_calendar_init()*/
|
||||||
|
RSI_PS_NpssPeriPowerUp(SLPSS_PWRGATE_ULP_MCURTC | SLPSS_PWRGATE_ULP_TIMEPERIOD);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,3 +35,4 @@ zephyr_library_sources_ifdef(CONFIG_RTC_RV8803 rtc_rv8803.c)
|
||||||
zephyr_library_sources_ifdef(CONFIG_RTC_BQ32002 rtc_bq32002.c)
|
zephyr_library_sources_ifdef(CONFIG_RTC_BQ32002 rtc_bq32002.c)
|
||||||
zephyr_library_sources_ifdef(CONFIG_RTC_RX8130CE rtc_rx8130ce.c)
|
zephyr_library_sources_ifdef(CONFIG_RTC_RX8130CE rtc_rx8130ce.c)
|
||||||
zephyr_library_sources_ifdef(CONFIG_RTC_DS1337 rtc_ds1337.c)
|
zephyr_library_sources_ifdef(CONFIG_RTC_DS1337 rtc_ds1337.c)
|
||||||
|
zephyr_library_sources_ifdef(CONFIG_RTC_SILABS_SIWX91X rtc_silabs_siwx91x.c)
|
||||||
|
|
|
@ -67,5 +67,6 @@ source "drivers/rtc/Kconfig.rv8803"
|
||||||
source "drivers/rtc/Kconfig.bq32002"
|
source "drivers/rtc/Kconfig.bq32002"
|
||||||
source "drivers/rtc/Kconfig.rx8130ce"
|
source "drivers/rtc/Kconfig.rx8130ce"
|
||||||
source "drivers/rtc/Kconfig.ds1337"
|
source "drivers/rtc/Kconfig.ds1337"
|
||||||
|
source "drivers/rtc/Kconfig.siwx91x"
|
||||||
|
|
||||||
endif # RTC
|
endif # RTC
|
||||||
|
|
10
drivers/rtc/Kconfig.siwx91x
Normal file
10
drivers/rtc/Kconfig.siwx91x
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
# Copyright (c) 2025 Silicon Laboratories Inc.
|
||||||
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
config RTC_SILABS_SIWX91X
|
||||||
|
bool "Silabs siwx91x RTC driver"
|
||||||
|
default y
|
||||||
|
depends on DT_HAS_SILABS_SIWX91X_RTC_ENABLED
|
||||||
|
help
|
||||||
|
Build the RTC driver for the Silabs SIWX91X SoC (Calendar
|
||||||
|
hardware block as described in the reference manual).
|
153
drivers/rtc/rtc_silabs_siwx91x.c
Normal file
153
drivers/rtc/rtc_silabs_siwx91x.c
Normal file
|
@ -0,0 +1,153 @@
|
||||||
|
/*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Copyright (c) 2025 Silicon Laboratories Inc.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <zephyr/devicetree.h>
|
||||||
|
#include <zephyr/drivers/clock_control.h>
|
||||||
|
#include <zephyr/drivers/rtc.h>
|
||||||
|
#include <zephyr/logging/log.h>
|
||||||
|
#include <zephyr/pm/device.h>
|
||||||
|
#include <zephyr/sys/util.h>
|
||||||
|
#include "rtc_utils.h"
|
||||||
|
#include "sl_si91x_calendar.h"
|
||||||
|
|
||||||
|
#define DT_DRV_COMPAT silabs_siwx91x_rtc
|
||||||
|
|
||||||
|
LOG_MODULE_REGISTER(siwx91x_rtc, CONFIG_RTC_LOG_LEVEL);
|
||||||
|
|
||||||
|
#define TM_YEAR_REF 1900
|
||||||
|
#define SIWX91X_RTC_YEAR_MAX 2399
|
||||||
|
#define SIWX91X_RTC_YEAR_MIN 2000
|
||||||
|
|
||||||
|
struct siwx91x_rtc_config {
|
||||||
|
const struct device *clock_dev;
|
||||||
|
clock_control_subsys_t clock_subsys;
|
||||||
|
};
|
||||||
|
struct siwx91x_rtc_data {
|
||||||
|
struct k_spinlock lock;
|
||||||
|
};
|
||||||
|
|
||||||
|
static void rtc_time_to_siwx91x_time_set(const struct rtc_time *tm,
|
||||||
|
sl_calendar_datetime_config_t *cldr)
|
||||||
|
{
|
||||||
|
int full_year = tm->tm_year + TM_YEAR_REF;
|
||||||
|
|
||||||
|
cldr->Year = (full_year % 100);
|
||||||
|
cldr->Century = (full_year >= 2000) ? (full_year - 2000) / 100 : 0;
|
||||||
|
cldr->Month = tm->tm_mon + 1;
|
||||||
|
cldr->Day = tm->tm_mday;
|
||||||
|
cldr->DayOfWeek = (RTC_DAY_OF_WEEK_T)tm->tm_wday;
|
||||||
|
cldr->Hour = tm->tm_hour;
|
||||||
|
cldr->Minute = tm->tm_min;
|
||||||
|
cldr->Second = tm->tm_sec;
|
||||||
|
cldr->MilliSeconds = tm->tm_nsec / NSEC_PER_MSEC;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void siwx91x_time_to_rtc_time_set(const sl_calendar_datetime_config_t *cldr,
|
||||||
|
struct rtc_time *tm)
|
||||||
|
{
|
||||||
|
int full_year = 2000 + (cldr->Century * 100) + cldr->Year;
|
||||||
|
|
||||||
|
tm->tm_year = full_year - TM_YEAR_REF;
|
||||||
|
tm->tm_mon = cldr->Month - 1;
|
||||||
|
tm->tm_mday = cldr->Day;
|
||||||
|
tm->tm_wday = (int)cldr->DayOfWeek;
|
||||||
|
tm->tm_hour = cldr->Hour;
|
||||||
|
tm->tm_min = cldr->Minute;
|
||||||
|
tm->tm_sec = cldr->Second;
|
||||||
|
tm->tm_nsec = cldr->MilliSeconds * NSEC_PER_MSEC;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int siwx91x_rtc_set_time(const struct device *dev, const struct rtc_time *timeptr)
|
||||||
|
{
|
||||||
|
sl_calendar_datetime_config_t siwx91x_time = {};
|
||||||
|
struct siwx91x_rtc_data *data = dev->data;
|
||||||
|
int year;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
year = timeptr->tm_year + TM_YEAR_REF;
|
||||||
|
if (year < SIWX91X_RTC_YEAR_MIN || year > SIWX91X_RTC_YEAR_MAX) {
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
k_spinlock_key_t key = k_spin_lock(&data->lock);
|
||||||
|
|
||||||
|
LOG_DBG("Set RTC time: year = %d, mon = %d, mday = %d, wday = %d, hour = %d, "
|
||||||
|
"min = %d, sec = %d",
|
||||||
|
timeptr->tm_year, timeptr->tm_mon, timeptr->tm_mday, timeptr->tm_wday,
|
||||||
|
timeptr->tm_hour, timeptr->tm_min, timeptr->tm_sec);
|
||||||
|
|
||||||
|
rtc_time_to_siwx91x_time_set(timeptr, &siwx91x_time);
|
||||||
|
|
||||||
|
ret = sl_si91x_calendar_set_date_time(&siwx91x_time);
|
||||||
|
if (ret) {
|
||||||
|
LOG_WRN("Set Timer returned an error - %d!", ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
k_spin_unlock(&data->lock, key);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int siwx91x_rtc_get_time(const struct device *dev, struct rtc_time *timeptr)
|
||||||
|
{
|
||||||
|
sl_calendar_datetime_config_t siwx91x_time = {};
|
||||||
|
struct siwx91x_rtc_data *data = dev->data;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
k_spinlock_key_t key = k_spin_lock(&data->lock);
|
||||||
|
|
||||||
|
ret = sl_si91x_calendar_get_date_time(&siwx91x_time);
|
||||||
|
if (ret != 0) {
|
||||||
|
LOG_WRN("Get Timer returned an error - %d!", ret);
|
||||||
|
goto unlock;
|
||||||
|
}
|
||||||
|
|
||||||
|
siwx91x_time_to_rtc_time_set(&siwx91x_time, timeptr);
|
||||||
|
|
||||||
|
LOG_DBG("get time: year = %d, mon = %d, mday = %d, wday = %d, hour = %d, "
|
||||||
|
"min = %d, sec = %d",
|
||||||
|
timeptr->tm_year, timeptr->tm_mon, timeptr->tm_mday, timeptr->tm_wday,
|
||||||
|
timeptr->tm_hour, timeptr->tm_min, timeptr->tm_sec);
|
||||||
|
|
||||||
|
unlock:
|
||||||
|
k_spin_unlock(&data->lock, key);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int siwx91x_rtc_init(const struct device *dev)
|
||||||
|
{
|
||||||
|
const struct siwx91x_rtc_config *config = dev->config;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = clock_control_on(config->clock_dev, config->clock_subsys);
|
||||||
|
if (ret) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
sl_si91x_calendar_init();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static DEVICE_API(rtc, siwx91x_rtc_driver_api) = {
|
||||||
|
.set_time = siwx91x_rtc_set_time,
|
||||||
|
.get_time = siwx91x_rtc_get_time,
|
||||||
|
};
|
||||||
|
|
||||||
|
#define SIWX91X_RTC_INIT(inst) \
|
||||||
|
static const struct siwx91x_rtc_config siwx91x_rtc_config_##inst = { \
|
||||||
|
.clock_dev = DEVICE_DT_GET(DT_INST_CLOCKS_CTLR(inst)), \
|
||||||
|
.clock_subsys = (clock_control_subsys_t)DT_INST_PHA(inst, clocks, clkid), \
|
||||||
|
}; \
|
||||||
|
\
|
||||||
|
static struct siwx91x_rtc_data siwx91x_rtc_data##inst; \
|
||||||
|
\
|
||||||
|
DEVICE_DT_INST_DEFINE(inst, &siwx91x_rtc_init, NULL, &siwx91x_rtc_data##inst, \
|
||||||
|
&siwx91x_rtc_config_##inst, POST_KERNEL, CONFIG_RTC_INIT_PRIORITY, \
|
||||||
|
&siwx91x_rtc_driver_api);
|
||||||
|
|
||||||
|
DT_INST_FOREACH_STATUS_OKAY(SIWX91X_RTC_INIT)
|
12
dts/bindings/rtc/silabs,siwx91x-rtc.yaml
Normal file
12
dts/bindings/rtc/silabs,siwx91x-rtc.yaml
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
# Copyright (c) 2025 Silicon Labatoratories Inc.
|
||||||
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
description: Silabs Siwx91x RTC (Real-Time Counter)
|
||||||
|
|
||||||
|
compatible: "silabs,siwx91x-rtc"
|
||||||
|
|
||||||
|
include: rtc.yaml
|
||||||
|
|
||||||
|
properties:
|
||||||
|
reg:
|
||||||
|
required: true
|
|
@ -16,5 +16,6 @@
|
||||||
#define SIWX91X_CLK_PWM 9
|
#define SIWX91X_CLK_PWM 9
|
||||||
#define SIWX91X_CLK_GSPI 10
|
#define SIWX91X_CLK_GSPI 10
|
||||||
#define SIWX91X_CLK_QSPI 11
|
#define SIWX91X_CLK_QSPI 11
|
||||||
|
#define SIWX91X_CLK_RTC 12
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -49,7 +49,10 @@ zephyr_library_sources(
|
||||||
${WISECONNECT_DIR}/components/device/silabs/si91x/mcu/drivers/systemlevel/src/rsi_pll.c
|
${WISECONNECT_DIR}/components/device/silabs/si91x/mcu/drivers/systemlevel/src/rsi_pll.c
|
||||||
${WISECONNECT_DIR}/components/device/silabs/si91x/mcu/drivers/systemlevel/src/rsi_ulpss_clk.c
|
${WISECONNECT_DIR}/components/device/silabs/si91x/mcu/drivers/systemlevel/src/rsi_ulpss_clk.c
|
||||||
${WISECONNECT_DIR}/components/device/silabs/si91x/mcu/drivers/systemlevel/src/rsi_wwdt.c
|
${WISECONNECT_DIR}/components/device/silabs/si91x/mcu/drivers/systemlevel/src/rsi_wwdt.c
|
||||||
|
${WISECONNECT_DIR}/components/device/silabs/si91x/mcu/drivers/systemlevel/src/rsi_rtc.c
|
||||||
|
${WISECONNECT_DIR}/components/device/silabs/si91x/mcu/drivers/systemlevel/src/rsi_time_period.c
|
||||||
${WISECONNECT_DIR}/components/device/silabs/si91x/mcu/drivers/service/clock_manager/src/sl_si91x_clock_manager.c
|
${WISECONNECT_DIR}/components/device/silabs/si91x/mcu/drivers/service/clock_manager/src/sl_si91x_clock_manager.c
|
||||||
|
${WISECONNECT_DIR}/components/device/silabs/si91x/mcu/drivers/unified_api/src/sl_si91x_calendar.c
|
||||||
${WISECONNECT_DIR}/components/device/silabs/si91x/mcu/drivers/unified_api/src/sl_si91x_driver_gpio.c
|
${WISECONNECT_DIR}/components/device/silabs/si91x/mcu/drivers/unified_api/src/sl_si91x_driver_gpio.c
|
||||||
${WISECONNECT_DIR}/components/device/silabs/si91x/mcu/drivers/unified_api/src/sl_si91x_pwm.c
|
${WISECONNECT_DIR}/components/device/silabs/si91x/mcu/drivers/unified_api/src/sl_si91x_pwm.c
|
||||||
${WISECONNECT_DIR}/components/device/silabs/si91x/mcu/drivers/unified_peripheral_drivers/src/sl_si91x_peripheral_gpio.c
|
${WISECONNECT_DIR}/components/device/silabs/si91x/mcu/drivers/unified_peripheral_drivers/src/sl_si91x_peripheral_gpio.c
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue