drivers/rtc/rtc-bd70528.c

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

File Facts

System
Linux kernel
Corpus path
drivers/rtc/rtc-bd70528.c
Extension
.c
Size
9173 bytes
Lines
365
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 bd70528_rtc_day {
	u8 sec;
	u8 min;
	u8 hour;
} __packed;

struct bd70528_rtc_data {
	struct bd70528_rtc_day time;
	u8 week;
	u8 day;
	u8 month;
	u8 year;
} __packed;

struct bd71828_rtc_alm {
	struct bd70528_rtc_data alm0;
	struct bd70528_rtc_data alm1;
	u8 alm_mask;
	u8 alm1_mask;
} __packed;

struct bd70528_rtc {
	struct rohm_regmap_dev *parent;
	struct regmap *regmap;
	struct device *dev;
	u8 reg_time_start;
	u8 bd718xx_alm_block_start;
};

static inline void tmday2rtc(struct rtc_time *t, struct bd70528_rtc_day *d)
{
	d->sec &= ~BD70528_MASK_RTC_SEC;
	d->min &= ~BD70528_MASK_RTC_MINUTE;
	d->hour &= ~BD70528_MASK_RTC_HOUR;
	d->sec |= bin2bcd(t->tm_sec);
	d->min |= bin2bcd(t->tm_min);
	d->hour |= bin2bcd(t->tm_hour);
}

static inline void tm2rtc(struct rtc_time *t, struct bd70528_rtc_data *r)
{
	r->day &= ~BD70528_MASK_RTC_DAY;
	r->week &= ~BD70528_MASK_RTC_WEEK;
	r->month &= ~BD70528_MASK_RTC_MONTH;
	/*
	 * PM and 24H bits are not used by Wake - thus we clear them
	 * here and not in tmday2rtc() which is also used by wake.
	 */
	r->time.hour &= ~(BD70528_MASK_RTC_HOUR_PM | BD70528_MASK_RTC_HOUR_24H);

	tmday2rtc(t, &r->time);
	/*
	 * We do always set time in 24H mode.
	 */
	r->time.hour |= BD70528_MASK_RTC_HOUR_24H;
	r->day |= bin2bcd(t->tm_mday);
	r->week |= bin2bcd(t->tm_wday);
	r->month |= bin2bcd(t->tm_mon + 1);
	r->year = bin2bcd(t->tm_year - 100);
}

static inline void rtc2tm(struct bd70528_rtc_data *r, struct rtc_time *t)
{
	t->tm_sec = bcd2bin(r->time.sec & BD70528_MASK_RTC_SEC);
	t->tm_min = bcd2bin(r->time.min & BD70528_MASK_RTC_MINUTE);
	t->tm_hour = bcd2bin(r->time.hour & BD70528_MASK_RTC_HOUR);
	/*
	 * If RTC is in 12H mode, then bit BD70528_MASK_RTC_HOUR_PM
	 * is not BCD value but tells whether it is AM or PM
	 */
	if (!(r->time.hour & BD70528_MASK_RTC_HOUR_24H)) {
		t->tm_hour %= 12;
		if (r->time.hour & BD70528_MASK_RTC_HOUR_PM)
			t->tm_hour += 12;
	}
	t->tm_mday = bcd2bin(r->day & BD70528_MASK_RTC_DAY);
	t->tm_mon = bcd2bin(r->month & BD70528_MASK_RTC_MONTH) - 1;
	t->tm_year = 100 + bcd2bin(r->year & BD70528_MASK_RTC_YEAR);
	t->tm_wday = bcd2bin(r->week & BD70528_MASK_RTC_WEEK);
}

static int bd71828_set_alarm(struct device *dev, struct rtc_wkalrm *a)
{
	int ret;
	struct bd71828_rtc_alm alm;
	struct bd70528_rtc *r = dev_get_drvdata(dev);

	ret = regmap_bulk_read(r->regmap, r->bd718xx_alm_block_start, &alm,
			       sizeof(alm));
	if (ret) {

Annotation

Implementation Notes