drivers/rtc/rtc-rx4581.c

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

File Facts

System
Linux kernel
Corpus path
drivers/rtc/rtc-rx4581.c
Extension
.c
Size
7821 bytes
Lines
293
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

if (data & RX4581_FLAG_UF) {
			err = rx4581_set_reg(dev,
				RX4581_REG_FLAG, (data & ~RX4581_FLAG_UF));
			if (err != 0) {
				dev_err(dev, "Unable to write device "
					"flags\n");
				return -EIO;
			}
		}

		/* Now read time and date */
		date[0] = 0x80;
		err = spi_write_then_read(spi, date, 1, date, 7);
		if (err < 0) {
			dev_err(dev, "Unable to read date\n");
			return -EIO;
		}

		/* Check flag register */
		err = rx4581_get_reg(dev, RX4581_REG_FLAG, &data);
		if (err != 0) {
			dev_err(dev, "Unable to read device flags\n");
			return -EIO;
		}
	} while (data & RX4581_FLAG_UF);

	if (data & RX4581_FLAG_VLF)
		dev_info(dev,
			"low voltage detected, date/time is not reliable.\n");

	dev_dbg(dev,
		"%s: raw data is sec=%02x, min=%02x, hr=%02x, "
		"wday=%02x, mday=%02x, mon=%02x, year=%02x\n",
		__func__,
		date[0], date[1], date[2], date[3], date[4], date[5], date[6]);

	tm->tm_sec = bcd2bin(date[RX4581_REG_SC] & 0x7F);
	tm->tm_min = bcd2bin(date[RX4581_REG_MN] & 0x7F);
	tm->tm_hour = bcd2bin(date[RX4581_REG_HR] & 0x3F); /* rtc hr 0-23 */
	tm->tm_wday = ilog2(date[RX4581_REG_DW] & 0x7F);
	tm->tm_mday = bcd2bin(date[RX4581_REG_DM] & 0x3F);
	tm->tm_mon = bcd2bin(date[RX4581_REG_MO] & 0x1F) - 1; /* rtc mn 1-12 */
	tm->tm_year = bcd2bin(date[RX4581_REG_YR]);
	if (tm->tm_year < 70)
		tm->tm_year += 100;	/* assume we are in 1970...2069 */


	dev_dbg(dev, "%s: tm is secs=%d, mins=%d, hours=%d, "
		"mday=%d, mon=%d, year=%d, wday=%d\n",
		__func__,
		tm->tm_sec, tm->tm_min, tm->tm_hour,
		tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday);

	return 0;
}

static int rx4581_set_datetime(struct device *dev, struct rtc_time *tm)
{
	struct spi_device *spi = to_spi_device(dev);
	int err;
	unsigned char buf[8], data;

	dev_dbg(dev, "%s: secs=%d, mins=%d, hours=%d, "
		"mday=%d, mon=%d, year=%d, wday=%d\n",
		__func__,
		tm->tm_sec, tm->tm_min, tm->tm_hour,
		tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday);

	buf[0] = 0x00;
	/* hours, minutes and seconds */
	buf[RX4581_REG_SC+1] = bin2bcd(tm->tm_sec);
	buf[RX4581_REG_MN+1] = bin2bcd(tm->tm_min);
	buf[RX4581_REG_HR+1] = bin2bcd(tm->tm_hour);

	buf[RX4581_REG_DM+1] = bin2bcd(tm->tm_mday);

	/* month, 1 - 12 */
	buf[RX4581_REG_MO+1] = bin2bcd(tm->tm_mon + 1);

	/* year and century */
	buf[RX4581_REG_YR+1] = bin2bcd(tm->tm_year % 100);
	buf[RX4581_REG_DW+1] = (0x1 << tm->tm_wday);

	/* Stop the clock */
	err = rx4581_get_reg(dev, RX4581_REG_CTRL, &data);
	if (err != 0) {
		dev_err(dev, "Unable to read control register\n");
		return -EIO;
	}

Annotation

Implementation Notes