drivers/rtc/rtc-sunplus.c

Source file repositories/reference/linux-study-clean/drivers/rtc/rtc-sunplus.c

File Facts

System
Linux kernel
Corpus path
drivers/rtc/rtc-sunplus.c
Extension
.c
Size
10191 bytes
Lines
360
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.

Dependency Surface

Detected Declarations

Annotated Snippet

struct sunplus_rtc {
	struct rtc_device *rtc;
	struct resource *res;
	struct clk *rtcclk;
	struct reset_control *rstc;
	void __iomem *reg_base;
	int irq;
};

static void sp_get_seconds(struct device *dev, unsigned long *secs)
{
	struct sunplus_rtc *sp_rtc = dev_get_drvdata(dev);

	*secs = (unsigned long)readl(sp_rtc->reg_base + RTC_TIMER_OUT);
}

static void sp_set_seconds(struct device *dev, unsigned long secs)
{
	struct sunplus_rtc *sp_rtc = dev_get_drvdata(dev);

	writel((u32)secs, sp_rtc->reg_base + RTC_TIMER_SET);
}

static int sp_rtc_read_time(struct device *dev, struct rtc_time *tm)
{
	unsigned long secs;

	sp_get_seconds(dev, &secs);
	rtc_time64_to_tm(secs, tm);

	return 0;
}

static int sp_rtc_set_time(struct device *dev, struct rtc_time *tm)
{
	unsigned long secs;

	secs = rtc_tm_to_time64(tm);
	dev_dbg(dev, "%s, secs = %lu\n", __func__, secs);
	sp_set_seconds(dev, secs);

	return 0;
}

static int sp_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
{
	struct sunplus_rtc *sp_rtc = dev_get_drvdata(dev);
	unsigned long alarm_time;

	alarm_time = rtc_tm_to_time64(&alrm->time);
	dev_dbg(dev, "%s, alarm_time: %u\n", __func__, (u32)(alarm_time));
	writel((u32)alarm_time, sp_rtc->reg_base + RTC_ALARM_SET);

	return 0;
}

static int sp_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
{
	struct sunplus_rtc *sp_rtc = dev_get_drvdata(dev);
	unsigned int alarm_time;

	alarm_time = readl(sp_rtc->reg_base + RTC_ALARM_SET);
	dev_dbg(dev, "%s, alarm_time: %u\n", __func__, alarm_time);

	if (alarm_time == 0)
		alrm->enabled = 0;
	else
		alrm->enabled = 1;

	rtc_time64_to_tm((unsigned long)(alarm_time), &alrm->time);

	return 0;
}

static int sp_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
{
	struct sunplus_rtc *sp_rtc = dev_get_drvdata(dev);

	if (enabled)
		writel((TIMER_FREEZE_MASK_BIT | DIS_SYS_RST_RTC_MASK_BIT |
			RTC32K_MODE_RESET_MASK_BIT | ALARM_EN_OVERDUE_MASK_BIT |
			ALARM_EN_PMC_MASK_BIT | ALARM_EN_MASK_BIT) |
			(DIS_SYS_RST_RTC | ALARM_EN_OVERDUE | ALARM_EN_PMC | ALARM_EN),
			sp_rtc->reg_base + RTC_CTRL);
	else
		writel((ALARM_EN_OVERDUE_MASK_BIT | ALARM_EN_PMC_MASK_BIT | ALARM_EN_MASK_BIT) |
			0x0, sp_rtc->reg_base + RTC_CTRL);

	return 0;
}

Annotation

Implementation Notes