Skip to content
Snippets Groups Projects
Commit 87e9963d authored by Heinrich Schuchardt's avatar Heinrich Schuchardt :speech_balloon:
Browse files

rtc: provide an emulated RTC


On a board without hardware clock this software real time clock can be
used. The build time is used to initialize the RTC. So you will have
to adjust the time either manually using the 'date' command  or use
the 'sntp' to update the RTC with the time from a network time server.
See CONFIG_CMD_SNTP and CONFIG_BOOTP_NTPSERVER. The RTC time is
advanced according to CPU ticks.

Signed-off-by: Heinrich Schuchardt's avatarHeinrich Schuchardt <xypron.glpk@gmx.de>
parent cbf0ffea
No related branches found
No related tags found
No related merge requests found
...@@ -678,6 +678,7 @@ S: Maintained ...@@ -678,6 +678,7 @@ S: Maintained
T: git https://gitlab.denx.de/u-boot/custodians/u-boot-efi.git T: git https://gitlab.denx.de/u-boot/custodians/u-boot-efi.git
F: doc/api/efi.rst F: doc/api/efi.rst
F: doc/uefi/* F: doc/uefi/*
F: drivers/rtc/emul_rtc.c
F: include/capitalization.h F: include/capitalization.h
F: include/charset.h F: include/charset.h
F: include/cp1250.h F: include/cp1250.h
......
...@@ -63,6 +63,17 @@ config RTC_DS3232 ...@@ -63,6 +63,17 @@ config RTC_DS3232
Support for Dallas Semiconductor (now Maxim) DS3232 compatible Support for Dallas Semiconductor (now Maxim) DS3232 compatible
Real Time Clock devices. Real Time Clock devices.
config RTC_EMULATION
bool "Enable emulated RTC"
depends on DM_RTC
help
On a board without hardware clock this software real time clock can be
used. The build time is used to initialize the RTC. So you will have
to adjust the time either manually using the 'date' command or use
the 'sntp' to update the RTC with the time from a network time server.
See CONFIG_CMD_SNTP and CONFIG_BOOTP_NTPSERVER. The RTC time is
advanced according to CPU ticks.
config RTC_ISL1208 config RTC_ISL1208
bool "Enable ISL1208 driver" bool "Enable ISL1208 driver"
depends on DM_RTC depends on DM_RTC
......
...@@ -22,6 +22,7 @@ obj-$(CONFIG_RTC_DS164x) += ds164x.o ...@@ -22,6 +22,7 @@ obj-$(CONFIG_RTC_DS164x) += ds164x.o
obj-$(CONFIG_RTC_DS174x) += ds174x.o obj-$(CONFIG_RTC_DS174x) += ds174x.o
obj-$(CONFIG_RTC_DS3231) += ds3231.o obj-$(CONFIG_RTC_DS3231) += ds3231.o
obj-$(CONFIG_RTC_DS3232) += ds3232.o obj-$(CONFIG_RTC_DS3232) += ds3232.o
obj-$(CONFIG_RTC_EMULATION) += emul_rtc.o
obj-$(CONFIG_RTC_FTRTC010) += ftrtc010.o obj-$(CONFIG_RTC_FTRTC010) += ftrtc010.o
obj-$(CONFIG_SANDBOX) += i2c_rtc_emul.o obj-$(CONFIG_SANDBOX) += i2c_rtc_emul.o
obj-$(CONFIG_RTC_IMXDI) += imxdi.o obj-$(CONFIG_RTC_IMXDI) += imxdi.o
......
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright 2020, Heinrich Schuchardt <xypron.glpk@gmx.de>
*
* This driver emulates a real time clock based on timer ticks.
*/
#include <common.h>
#include <div64.h>
#include <dm.h>
#include <generated/timestamp_autogenerated.h>
#include <rtc.h>
/**
* struct emul_rtc - private data for emulated RTC driver
*/
struct emul_rtc {
/**
* @offset_us: microseconds from 1970-01-01 to timer_get_us() base
*/
u64 offset_us;
/**
* @isdst: daylight saving time
*/
int isdst;
};
static int emul_rtc_get(struct udevice *dev, struct rtc_time *time)
{
struct emul_rtc *priv = dev_get_priv(dev);
u64 now;
if (!priv->offset_us) {
/* Use the build date as initial time */
priv->offset_us = U_BOOT_EPOCH * 1000000ULL - timer_get_us();
priv->isdst = -1;
}
now = timer_get_us() + priv->offset_us;
do_div(now, 1000000);
rtc_to_tm(now, time);
time->tm_isdst = priv->isdst;
return 0;
}
static int emul_rtc_set(struct udevice *dev, const struct rtc_time *time)
{
struct emul_rtc *priv = dev_get_priv(dev);
if (time->tm_year < 1970)
return -EINVAL;
priv->offset_us = rtc_mktime(time) * 1000000ULL - timer_get_us();
if (time->tm_isdst > 0)
priv->isdst = 1;
else if (time->tm_isdst < 0)
priv->isdst = -1;
else
priv->isdst = 0;
return 0;
}
static const struct rtc_ops emul_rtc_ops = {
.get = emul_rtc_get,
.set = emul_rtc_set,
};
U_BOOT_DRIVER(rtc_emul) = {
.name = "rtc_emul",
.id = UCLASS_RTC,
.ops = &emul_rtc_ops,
.priv_auto_alloc_size = sizeof(struct emul_rtc),
};
U_BOOT_DEVICE(rtc_emul) = {
.name = "rtc_emul",
};
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment