drivers/rtc/rtc-r7301.c

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

File Facts

System
Linux kernel
Corpus path
drivers/rtc/rtc-r7301.c
Extension
.c
Size
11891 bytes
Lines
481
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 rtc7301_priv {
	struct regmap *regmap;
	int irq;
	spinlock_t lock;
	u8 bank;
};

/*
 * When the device is memory-mapped, some platforms pack the registers into
 * 32-bit access using the lower 8 bits at each 4-byte stride, while others
 * expose them as simply consecutive bytes.
 */
static const struct regmap_config rtc7301_regmap_32_config = {
	.reg_bits = 32,
	.val_bits = 8,
	.reg_stride = 4,
};

static const struct regmap_config rtc7301_regmap_8_config = {
	.reg_bits = 8,
	.val_bits = 8,
	.reg_stride = 1,
};

static u8 rtc7301_read(struct rtc7301_priv *priv, unsigned int reg)
{
	int reg_stride = regmap_get_reg_stride(priv->regmap);
	unsigned int val;

	regmap_read(priv->regmap, reg_stride * reg, &val);

	return val & 0xf;
}

static void rtc7301_write(struct rtc7301_priv *priv, u8 val, unsigned int reg)
{
	int reg_stride = regmap_get_reg_stride(priv->regmap);

	regmap_write(priv->regmap, reg_stride * reg, val);
}

static void rtc7301_update_bits(struct rtc7301_priv *priv, unsigned int reg,
				u8 mask, u8 val)
{
	int reg_stride = regmap_get_reg_stride(priv->regmap);

	regmap_update_bits(priv->regmap, reg_stride * reg, mask, val);
}

static int rtc7301_wait_while_busy(struct rtc7301_priv *priv)
{
	int retries = 100;

	while (retries-- > 0) {
		u8 val;

		val = rtc7301_read(priv, RTC7301_CONTROL);
		if (!(val & RTC7301_CONTROL_BUSY))
			return 0;

		udelay(300);
	}

	return -ETIMEDOUT;
}

static void rtc7301_stop(struct rtc7301_priv *priv)
{
	rtc7301_update_bits(priv, RTC7301_CONTROL, RTC7301_CONTROL_STOP,
			    RTC7301_CONTROL_STOP);
}

static void rtc7301_start(struct rtc7301_priv *priv)
{
	rtc7301_update_bits(priv, RTC7301_CONTROL, RTC7301_CONTROL_STOP, 0);
}

static void rtc7301_select_bank(struct rtc7301_priv *priv, u8 bank)
{
	u8 val = 0;

	if (bank == priv->bank)
		return;

	if (bank & BIT(0))
		val |= RTC7301_CONTROL_BANK_SEL_0;
	if (bank & BIT(1))
		val |= RTC7301_CONTROL_BANK_SEL_1;

	rtc7301_update_bits(priv, RTC7301_CONTROL,

Annotation

Implementation Notes