drivers/rtc/rtc-fm3130.c
Source file repositories/reference/linux-study-clean/drivers/rtc/rtc-fm3130.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/rtc/rtc-fm3130.c- Extension
.c- Size
- 15424 bytes
- Lines
- 530
- 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.
- 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.
- Allocates kernel memory; connect allocation flags and lifetime to context constraints.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/module.hlinux/i2c.hlinux/rtc.hlinux/bcd.hlinux/slab.h
Detected Declarations
struct fm3130function fm3130_rtc_modefunction fm3130_get_timefunction fm3130_set_timefunction fm3130_read_alarmfunction fm3130_set_alarmfunction fm3130_alarm_irq_enablefunction fm3130_probe
Annotated Snippet
struct fm3130 {
u8 reg_addr_time;
u8 reg_addr_alarm;
u8 regs[15];
struct i2c_msg msg[4];
struct i2c_client *client;
struct rtc_device *rtc;
int alarm_valid;
int data_valid;
};
static const struct i2c_device_id fm3130_id[] = {
{ "fm3130" },
{ }
};
MODULE_DEVICE_TABLE(i2c, fm3130_id);
#define FM3130_MODE_NORMAL 0
#define FM3130_MODE_WRITE 1
#define FM3130_MODE_READ 2
static void fm3130_rtc_mode(struct device *dev, int mode)
{
struct fm3130 *fm3130 = dev_get_drvdata(dev);
fm3130->regs[FM3130_RTC_CONTROL] =
i2c_smbus_read_byte_data(fm3130->client, FM3130_RTC_CONTROL);
switch (mode) {
case FM3130_MODE_NORMAL:
fm3130->regs[FM3130_RTC_CONTROL] &=
~(FM3130_RTC_CONTROL_BIT_WRITE |
FM3130_RTC_CONTROL_BIT_READ);
break;
case FM3130_MODE_WRITE:
fm3130->regs[FM3130_RTC_CONTROL] |= FM3130_RTC_CONTROL_BIT_WRITE;
break;
case FM3130_MODE_READ:
fm3130->regs[FM3130_RTC_CONTROL] |= FM3130_RTC_CONTROL_BIT_READ;
break;
default:
dev_dbg(dev, "invalid mode %d\n", mode);
break;
}
i2c_smbus_write_byte_data(fm3130->client,
FM3130_RTC_CONTROL, fm3130->regs[FM3130_RTC_CONTROL]);
}
static int fm3130_get_time(struct device *dev, struct rtc_time *t)
{
struct fm3130 *fm3130 = dev_get_drvdata(dev);
int tmp;
if (!fm3130->data_valid) {
/* We have invalid data in RTC, probably due
to battery faults or other problems. Return EIO
for now, it will allow us to set data later instead
of error during probing which disables device */
return -EIO;
}
fm3130_rtc_mode(dev, FM3130_MODE_READ);
/* read the RTC date and time registers all at once */
tmp = i2c_transfer(fm3130->client->adapter, fm3130->msg, 2);
if (tmp != 2) {
dev_err(dev, "%s error %d\n", "read", tmp);
return -EIO;
}
fm3130_rtc_mode(dev, FM3130_MODE_NORMAL);
dev_dbg(dev, "%s: %15ph\n", "read", fm3130->regs);
t->tm_sec = bcd2bin(fm3130->regs[FM3130_RTC_SECONDS] & 0x7f);
t->tm_min = bcd2bin(fm3130->regs[FM3130_RTC_MINUTES] & 0x7f);
tmp = fm3130->regs[FM3130_RTC_HOURS] & 0x3f;
t->tm_hour = bcd2bin(tmp);
t->tm_wday = bcd2bin(fm3130->regs[FM3130_RTC_DAY] & 0x07) - 1;
t->tm_mday = bcd2bin(fm3130->regs[FM3130_RTC_DATE] & 0x3f);
tmp = fm3130->regs[FM3130_RTC_MONTHS] & 0x1f;
t->tm_mon = bcd2bin(tmp) - 1;
/* assume 20YY not 19YY, and ignore CF bit */
t->tm_year = bcd2bin(fm3130->regs[FM3130_RTC_YEARS]) + 100;
dev_dbg(dev, "%s secs=%d, mins=%d, "
"hours=%d, mday=%d, mon=%d, year=%d, wday=%d\n",
"read", t->tm_sec, t->tm_min,
t->tm_hour, t->tm_mday,
t->tm_mon, t->tm_year, t->tm_wday);
Annotation
- Immediate include surface: `linux/module.h`, `linux/i2c.h`, `linux/rtc.h`, `linux/bcd.h`, `linux/slab.h`.
- Detected declarations: `struct fm3130`, `function fm3130_rtc_mode`, `function fm3130_get_time`, `function fm3130_set_time`, `function fm3130_read_alarm`, `function fm3130_set_alarm`, `function fm3130_alarm_irq_enable`, `function fm3130_probe`.
- Atlas domain: Driver Families / drivers/rtc.
- Implementation status: source implementation candidate.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.