drivers/rtc/rtc-rv3032.c

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

File Facts

System
Linux kernel
Corpus path
drivers/rtc/rtc-rv3032.c
Extension
.c
Size
24032 bytes
Lines
1005
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 rv3032_data {
	struct regmap *regmap;
	struct rtc_device *rtc;
	bool trickle_charger_set;
#ifdef CONFIG_COMMON_CLK
	struct clk_hw clkout_hw;
#endif
};

static u16 rv3032_trickle_resistors[] = {1000, 2000, 7000, 11000};
static u16 rv3032_trickle_voltages[] = {0, 1750, 3000, 4400};

static int rv3032_exit_eerd(struct rv3032_data *rv3032, u32 eerd)
{
	if (eerd)
		return 0;

	return regmap_update_bits(rv3032->regmap, RV3032_CTRL1, RV3032_CTRL1_EERD, 0);
}

static int rv3032_enter_eerd(struct rv3032_data *rv3032, u32 *eerd)
{
	u32 ctrl1, status;
	int ret;

	ret = regmap_read(rv3032->regmap, RV3032_CTRL1, &ctrl1);
	if (ret)
		return ret;

	*eerd = ctrl1 & RV3032_CTRL1_EERD;
	if (*eerd)
		return 0;

	ret = regmap_update_bits(rv3032->regmap, RV3032_CTRL1,
				 RV3032_CTRL1_EERD, RV3032_CTRL1_EERD);
	if (ret)
		return ret;

	ret = regmap_read_poll_timeout(rv3032->regmap, RV3032_TLSB, status,
				       !(status & RV3032_TLSB_EEBUSY),
				       RV3032_EEBUSY_POLL, RV3032_EEBUSY_TIMEOUT);
	if (ret) {
		rv3032_exit_eerd(rv3032, *eerd);

		return ret;
	}

	return 0;
}

static int rv3032_update_cfg(struct rv3032_data *rv3032, unsigned int reg,
			     unsigned int mask, unsigned int val)
{
	u32 status, eerd;
	int ret;

	ret = rv3032_enter_eerd(rv3032, &eerd);
	if (ret)
		return ret;

	ret = regmap_update_bits(rv3032->regmap, reg, mask, val);
	if (ret)
		goto exit_eerd;

	ret = regmap_write(rv3032->regmap, RV3032_EEPROM_CMD, RV3032_EEPROM_CMD_UPDATE);
	if (ret)
		goto exit_eerd;

	usleep_range(46000, RV3032_EEBUSY_TIMEOUT);

	ret = regmap_read_poll_timeout(rv3032->regmap, RV3032_TLSB, status,
				       !(status & RV3032_TLSB_EEBUSY),
				       RV3032_EEBUSY_POLL, RV3032_EEBUSY_TIMEOUT);

exit_eerd:
	rv3032_exit_eerd(rv3032, eerd);

	return ret;
}

static irqreturn_t rv3032_handle_irq(int irq, void *dev_id)
{
	struct rv3032_data *rv3032 = dev_id;
	unsigned long events = 0;
	u32 status = 0, ctrl = 0;

	if (regmap_read(rv3032->regmap, RV3032_STATUS, &status) < 0 ||
	    status == 0) {
		return IRQ_NONE;
	}

Annotation

Implementation Notes