drivers/rtc/rtc-twl.c

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

File Facts

System
Linux kernel
Corpus path
drivers/rtc/rtc-twl.c
Extension
.c
Size
18284 bytes
Lines
690
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 twl_rtc {
	struct device *dev;
	struct rtc_device *rtc;
	u8 *reg_map;
	/*
	 * Cache the value for timer/alarm interrupts register; this is
	 * only changed by callers holding rtc ops lock (or resume).
	 */
	unsigned char rtc_irq_bits;
	bool wake_enabled;
#ifdef CONFIG_PM_SLEEP
	unsigned char irqstat;
#endif
	enum twl_class class;
};

/*
 * Supports 1 byte read from TWL RTC register.
 */
static int twl_rtc_read_u8(struct twl_rtc *twl_rtc, u8 *data, u8 reg)
{
	int ret;

	ret = twl_i2c_read_u8(TWL_MODULE_RTC, data, (twl_rtc->reg_map[reg]));
	if (ret < 0)
		pr_err("Could not read TWL register %X - error %d\n", reg, ret);
	return ret;
}

/*
 * Supports 1 byte write to TWL RTC registers.
 */
static int twl_rtc_write_u8(struct twl_rtc *twl_rtc, u8 data, u8 reg)
{
	int ret;

	ret = twl_i2c_write_u8(TWL_MODULE_RTC, data, (twl_rtc->reg_map[reg]));
	if (ret < 0)
		pr_err("Could not write TWL register %X - error %d\n",
		       reg, ret);
	return ret;
}

/*
 * Enable 1/second update and/or alarm interrupts.
 */
static int set_rtc_irq_bit(struct twl_rtc *twl_rtc, unsigned char bit)
{
	unsigned char val;
	int ret;

	/* if the bit is set, return from here */
	if (twl_rtc->rtc_irq_bits & bit)
		return 0;

	val = twl_rtc->rtc_irq_bits | bit;
	val &= ~BIT_RTC_INTERRUPTS_REG_EVERY_M;
	ret = twl_rtc_write_u8(twl_rtc, val, REG_RTC_INTERRUPTS_REG);
	if (ret == 0)
		twl_rtc->rtc_irq_bits = val;

	return ret;
}

/*
 * Disable update and/or alarm interrupts.
 */
static int mask_rtc_irq_bit(struct twl_rtc *twl_rtc, unsigned char bit)
{
	unsigned char val;
	int ret;

	/* if the bit is clear, return from here */
	if (!(twl_rtc->rtc_irq_bits & bit))
		return 0;

	val = twl_rtc->rtc_irq_bits & ~bit;
	ret = twl_rtc_write_u8(twl_rtc, val, REG_RTC_INTERRUPTS_REG);
	if (ret == 0)
		twl_rtc->rtc_irq_bits = val;

	return ret;
}

static int twl_rtc_alarm_irq_enable(struct device *dev, unsigned enabled)
{
	struct platform_device *pdev = to_platform_device(dev);
	struct twl_rtc *twl_rtc = dev_get_drvdata(dev);
	int irq = platform_get_irq(pdev, 0);
	int ret;

Annotation

Implementation Notes