drivers/rtc/rtc-da9055.c

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

File Facts

System
Linux kernel
Corpus path
drivers/rtc/rtc-da9055.c
Extension
.c
Size
9310 bytes
Lines
400
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 da9055_rtc {
	struct rtc_device *rtc;
	struct da9055 *da9055;
	int alarm_enable;
};

static int da9055_rtc_enable_alarm(struct da9055_rtc *rtc, bool enable)
{
	int ret;
	if (enable) {
		ret = da9055_reg_update(rtc->da9055, DA9055_REG_ALARM_Y,
					DA9055_RTC_ALM_EN,
					DA9055_RTC_ALM_EN);
		if (ret != 0)
			dev_err(rtc->da9055->dev, "Failed to enable ALM: %d\n",
				ret);
		rtc->alarm_enable = 1;
	} else {
		ret = da9055_reg_update(rtc->da9055, DA9055_REG_ALARM_Y,
					DA9055_RTC_ALM_EN, 0);
		if (ret != 0)
			dev_err(rtc->da9055->dev,
				"Failed to disable ALM: %d\n", ret);
		rtc->alarm_enable = 0;
	}
	return ret;
}

static irqreturn_t da9055_rtc_alm_irq(int irq, void *data)
{
	struct da9055_rtc *rtc = data;

	da9055_rtc_enable_alarm(rtc, 0);
	rtc_update_irq(rtc->rtc, 1, RTC_IRQF | RTC_AF);

	return IRQ_HANDLED;
}

static int da9055_read_alarm(struct da9055 *da9055, struct rtc_time *rtc_tm)
{
	int ret;
	uint8_t v[5];

	ret = da9055_group_read(da9055, DA9055_REG_ALARM_MI, 5, v);
	if (ret != 0) {
		dev_err(da9055->dev, "Failed to group read ALM: %d\n", ret);
		return ret;
	}

	rtc_tm->tm_year = (v[4] & DA9055_RTC_ALM_YEAR) + 100;
	rtc_tm->tm_mon  = (v[3] & DA9055_RTC_ALM_MONTH) - 1;
	rtc_tm->tm_mday = v[2] & DA9055_RTC_ALM_DAY;
	rtc_tm->tm_hour = v[1] & DA9055_RTC_ALM_HOUR;
	rtc_tm->tm_min  = v[0] & DA9055_RTC_ALM_MIN;
	rtc_tm->tm_sec = 0;

	return rtc_valid_tm(rtc_tm);
}

static int da9055_set_alarm(struct da9055 *da9055, struct rtc_time *rtc_tm)
{
	int ret;
	uint8_t v[2];

	rtc_tm->tm_year -= 100;
	rtc_tm->tm_mon += 1;

	ret = da9055_reg_update(da9055, DA9055_REG_ALARM_MI,
				DA9055_RTC_ALM_MIN, rtc_tm->tm_min);
	if (ret != 0) {
		dev_err(da9055->dev, "Failed to write ALRM MIN: %d\n", ret);
		return ret;
	}

	v[0] = rtc_tm->tm_hour;
	v[1] = rtc_tm->tm_mday;

	ret = da9055_group_write(da9055, DA9055_REG_ALARM_H, 2, v);
	if (ret < 0)
		return ret;

	ret = da9055_reg_update(da9055, DA9055_REG_ALARM_MO,
				DA9055_RTC_ALM_MONTH, rtc_tm->tm_mon);
	if (ret < 0)
		dev_err(da9055->dev, "Failed to write ALM Month:%d\n", ret);

	ret = da9055_reg_update(da9055, DA9055_REG_ALARM_Y,
				DA9055_RTC_ALM_YEAR, rtc_tm->tm_year);
	if (ret < 0)
		dev_err(da9055->dev, "Failed to write ALM Year:%d\n", ret);

Annotation

Implementation Notes