drivers/rtc/rtc-max8907.c

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

File Facts

System
Linux kernel
Corpus path
drivers/rtc/rtc-max8907.c
Extension
.c
Size
5157 bytes
Lines
221
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 max8907_rtc {
	struct max8907		*max8907;
	struct regmap		*regmap;
	struct rtc_device	*rtc_dev;
	int			irq;
};

static irqreturn_t max8907_irq_handler(int irq, void *data)
{
	struct max8907_rtc *rtc = data;

	regmap_write(rtc->regmap, MAX8907_REG_ALARM0_CNTL, 0);

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

	return IRQ_HANDLED;
}

static void regs_to_tm(u8 *regs, struct rtc_time *tm)
{
	tm->tm_year = bcd2bin(regs[RTC_YEAR2]) * 100 +
		bcd2bin(regs[RTC_YEAR1]) - 1900;
	tm->tm_mon = bcd2bin(regs[RTC_MONTH] & 0x1f) - 1;
	tm->tm_mday = bcd2bin(regs[RTC_DATE] & 0x3f);
	tm->tm_wday = (regs[RTC_WEEKDAY] & 0x07);
	if (regs[RTC_HOUR] & HOUR_12) {
		tm->tm_hour = bcd2bin(regs[RTC_HOUR] & 0x01f);
		if (tm->tm_hour == 12)
			tm->tm_hour = 0;
		if (regs[RTC_HOUR] & HOUR_AM_PM)
			tm->tm_hour += 12;
	} else {
		tm->tm_hour = bcd2bin(regs[RTC_HOUR] & 0x03f);
	}
	tm->tm_min = bcd2bin(regs[RTC_MIN] & 0x7f);
	tm->tm_sec = bcd2bin(regs[RTC_SEC] & 0x7f);
}

static void tm_to_regs(struct rtc_time *tm, u8 *regs)
{
	u8 high, low;

	high = (tm->tm_year + 1900) / 100;
	low = tm->tm_year % 100;
	regs[RTC_YEAR2] = bin2bcd(high);
	regs[RTC_YEAR1] = bin2bcd(low);
	regs[RTC_MONTH] = bin2bcd(tm->tm_mon + 1);
	regs[RTC_DATE] = bin2bcd(tm->tm_mday);
	regs[RTC_WEEKDAY] = tm->tm_wday;
	regs[RTC_HOUR] = bin2bcd(tm->tm_hour);
	regs[RTC_MIN] = bin2bcd(tm->tm_min);
	regs[RTC_SEC] = bin2bcd(tm->tm_sec);
}

static int max8907_rtc_read_time(struct device *dev, struct rtc_time *tm)
{
	struct max8907_rtc *rtc = dev_get_drvdata(dev);
	u8 regs[TIME_NUM];
	int ret;

	ret = regmap_bulk_read(rtc->regmap, MAX8907_REG_RTC_SEC, regs,
			       TIME_NUM);
	if (ret < 0)
		return ret;

	regs_to_tm(regs, tm);

	return 0;
}

static int max8907_rtc_set_time(struct device *dev, struct rtc_time *tm)
{
	struct max8907_rtc *rtc = dev_get_drvdata(dev);
	u8 regs[TIME_NUM];

	tm_to_regs(tm, regs);

	return regmap_bulk_write(rtc->regmap, MAX8907_REG_RTC_SEC, regs,
				 TIME_NUM);
}

static int max8907_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
{
	struct max8907_rtc *rtc = dev_get_drvdata(dev);
	u8 regs[TIME_NUM];
	unsigned int val;
	int ret;

	ret = regmap_bulk_read(rtc->regmap, MAX8907_REG_ALARM0_SEC, regs,
			       TIME_NUM);

Annotation

Implementation Notes