drivers/rtc/rtc-ds1305.c

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

File Facts

System
Linux kernel
Corpus path
drivers/rtc/rtc-ds1305.c
Extension
.c
Size
19956 bytes
Lines
748
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 ds1305 {
	struct spi_device	*spi;
	struct rtc_device	*rtc;

	struct work_struct	work;

	unsigned long		flags;
#define FLAG_EXITING	0

	bool			hr12;
	u8			ctrl[DS1305_CONTROL_LEN];
};


/*----------------------------------------------------------------------*/

/*
 * Utilities ...  tolerate 12-hour AM/PM notation in case of non-Linux
 * software (like a bootloader) which may require it.
 */

static unsigned bcd2hour(u8 bcd)
{
	if (bcd & DS1305_HR_12) {
		unsigned	hour = 0;

		bcd &= ~DS1305_HR_12;
		if (bcd & DS1305_HR_PM) {
			hour = 12;
			bcd &= ~DS1305_HR_PM;
		}
		hour += bcd2bin(bcd);
		return hour - 1;
	}
	return bcd2bin(bcd);
}

static u8 hour2bcd(bool hr12, int hour)
{
	if (hr12) {
		hour++;
		if (hour <= 12)
			return DS1305_HR_12 | bin2bcd(hour);
		hour -= 12;
		return DS1305_HR_12 | DS1305_HR_PM | bin2bcd(hour);
	}
	return bin2bcd(hour);
}

/*----------------------------------------------------------------------*/

/*
 * Interface to RTC framework
 */

static int ds1305_alarm_irq_enable(struct device *dev, unsigned int enabled)
{
	struct ds1305	*ds1305 = dev_get_drvdata(dev);
	u8		buf[2];
	long		err = -EINVAL;

	buf[0] = DS1305_WRITE | DS1305_CONTROL;
	buf[1] = ds1305->ctrl[0];

	if (enabled) {
		if (ds1305->ctrl[0] & DS1305_AEI0)
			goto done;
		buf[1] |= DS1305_AEI0;
	} else {
		if (!(buf[1] & DS1305_AEI0))
			goto done;
		buf[1] &= ~DS1305_AEI0;
	}
	err = spi_write_then_read(ds1305->spi, buf, sizeof(buf), NULL, 0);
	if (err >= 0)
		ds1305->ctrl[0] = buf[1];
done:
	return err;

}


/*
 * Get/set of date and time is pretty normal.
 */

static int ds1305_get_time(struct device *dev, struct rtc_time *time)
{
	struct ds1305	*ds1305 = dev_get_drvdata(dev);
	u8		addr = DS1305_SEC;

Annotation

Implementation Notes