drivers/rtc/rtc-rk808.c
Source file repositories/reference/linux-study-clean/drivers/rtc/rtc-rk808.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/rtc/rtc-rk808.c- Extension
.c- Size
- 13135 bytes
- Lines
- 461
- Domain
- Driver Families
- Bucket
- drivers/rtc
- Inferred role
- Driver Families: implementation source
- Status
- source implementation candidate
Why This File Exists
Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Touches IRQ or DMA behavior; this matters for the representative real-device path.
- Allocates kernel memory; connect allocation flags and lifetime to context constraints.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/module.hlinux/kernel.hlinux/rtc.hlinux/bcd.hlinux/mfd/rk808.hlinux/platform_device.h
Detected Declarations
struct rk_rtc_compat_regstruct rk808_rtcfunction nov2dec_transitionsfunction rockchip_to_gregorianfunction gregorian_to_rockchipfunction rk808_rtc_readtimefunction rk808_rtc_set_timefunction rk808_rtc_readalarmfunction rk808_rtc_stop_alarmfunction rk808_rtc_start_alarmfunction rk808_rtc_setalarmfunction rk808_rtc_alarm_irq_enablefunction rk808_alarm_irqfunction rk808_rtc_suspendfunction rk808_rtc_resumefunction rk808_rtc_probe
Annotated Snippet
struct rk_rtc_compat_reg {
unsigned int ctrl_reg;
unsigned int status_reg;
unsigned int alarm_seconds_reg;
unsigned int int_reg;
unsigned int seconds_reg;
};
struct rk808_rtc {
struct regmap *regmap;
struct rtc_device *rtc;
struct rk_rtc_compat_reg *creg;
int irq;
};
/*
* The Rockchip calendar used by the RK808 counts November with 31 days. We use
* these translation functions to convert its dates to/from the Gregorian
* calendar used by the rest of the world. We arbitrarily define Jan 1st, 2016
* as the day when both calendars were in sync, and treat all other dates
* relative to that.
* NOTE: Other system software (e.g. firmware) that reads the same hardware must
* implement this exact same conversion algorithm, with the same anchor date.
*/
static time64_t nov2dec_transitions(struct rtc_time *tm)
{
return (tm->tm_year + 1900) - 2016 + (tm->tm_mon + 1 > 11 ? 1 : 0);
}
static void rockchip_to_gregorian(struct rtc_time *tm)
{
/* If it's Nov 31st, rtc_tm_to_time64() will count that like Dec 1st */
time64_t time = rtc_tm_to_time64(tm);
rtc_time64_to_tm(time + nov2dec_transitions(tm) * 86400, tm);
}
static void gregorian_to_rockchip(struct rtc_time *tm)
{
time64_t extra_days = nov2dec_transitions(tm);
time64_t time = rtc_tm_to_time64(tm);
rtc_time64_to_tm(time - extra_days * 86400, tm);
/* Compensate if we went back over Nov 31st (will work up to 2381) */
if (nov2dec_transitions(tm) < extra_days) {
if (tm->tm_mon + 1 == 11)
tm->tm_mday++; /* This may result in 31! */
else
rtc_time64_to_tm(time - (extra_days - 1) * 86400, tm);
}
}
/* Read current time and date in RTC */
static int rk808_rtc_readtime(struct device *dev, struct rtc_time *tm)
{
struct rk808_rtc *rk808_rtc = dev_get_drvdata(dev);
u8 rtc_data[NUM_TIME_REGS];
int ret;
/* Force an update of the shadowed registers right now */
ret = regmap_update_bits(rk808_rtc->regmap, rk808_rtc->creg->ctrl_reg,
BIT_RTC_CTRL_REG_RTC_GET_TIME,
BIT_RTC_CTRL_REG_RTC_GET_TIME);
if (ret) {
dev_err(dev, "Failed to update bits rtc_ctrl: %d\n", ret);
return ret;
}
/*
* After we set the GET_TIME bit, the rtc time can't be read
* immediately. So we should wait up to 31.25 us, about one cycle of
* 32khz. If we clear the GET_TIME bit here, the time of i2c transfer
* certainly more than 31.25us: 16 * 2.5us at 400kHz bus frequency.
*/
ret = regmap_update_bits(rk808_rtc->regmap, rk808_rtc->creg->ctrl_reg,
BIT_RTC_CTRL_REG_RTC_GET_TIME,
0);
if (ret) {
dev_err(dev, "Failed to update bits rtc_ctrl: %d\n", ret);
return ret;
}
ret = regmap_bulk_read(rk808_rtc->regmap, rk808_rtc->creg->seconds_reg,
rtc_data, NUM_TIME_REGS);
if (ret) {
dev_err(dev, "Failed to bulk read rtc_data: %d\n", ret);
return ret;
}
tm->tm_sec = bcd2bin(rtc_data[0] & SECONDS_REG_MSK);
tm->tm_min = bcd2bin(rtc_data[1] & MINUTES_REG_MAK);
Annotation
- Immediate include surface: `linux/module.h`, `linux/kernel.h`, `linux/rtc.h`, `linux/bcd.h`, `linux/mfd/rk808.h`, `linux/platform_device.h`.
- Detected declarations: `struct rk_rtc_compat_reg`, `struct rk808_rtc`, `function nov2dec_transitions`, `function rockchip_to_gregorian`, `function gregorian_to_rockchip`, `function rk808_rtc_readtime`, `function rk808_rtc_set_time`, `function rk808_rtc_readalarm`, `function rk808_rtc_stop_alarm`, `function rk808_rtc_start_alarm`.
- Atlas domain: Driver Families / drivers/rtc.
- Implementation status: source implementation candidate.
- IRQ or DMA behavior appears here, which is relevant to the selected PCIe/NVMe device path.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.