drivers/hwmon/pmbus/adm1266.c
Source file repositories/reference/linux-study-clean/drivers/hwmon/pmbus/adm1266.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/hwmon/pmbus/adm1266.c- Extension
.c- Size
- 17820 bytes
- Lines
- 674
- Domain
- Driver Families
- Bucket
- drivers/hwmon
- Inferred role
- Driver Families: operation-table or driver-model contract
- Status
- pattern 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.
- Defines an operation table; this is where Linux turns generic core objects into subsystem-specific behavior.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- 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/bitfield.hlinux/crc8.hlinux/debugfs.hlinux/gpio/driver.hlinux/i2c.hlinux/i2c-smbus.hlinux/init.hlinux/kernel.hlinux/module.hlinux/nvmem-consumer.hlinux/nvmem-provider.hpmbus.hlinux/slab.hlinux/timekeeping.h
Detected Declarations
struct adm1266_datafunction adm1266_pmbus_block_xferfunction adm1266_gpio_getfunction adm1266_gpio_get_multiplefunction for_each_set_bit_fromfunction adm1266_gpio_dbg_showfunction adm1266_config_gpiofunction adm1266_state_readfunction IC_DEVICE_REVfunction POWERUP_COUNTERfunction adm1266_clear_blackbox_writefunction agentfunction adm1266_rtc_setfunction adm1266_init_debugfsfunction adm1266_nvmem_read_blackboxfunction adm1266_nvmem_readfunction adm1266_config_nvmemfunction adm1266_probe
Annotated Snippet
static const struct file_operations adm1266_clear_blackbox_fops = {
.owner = THIS_MODULE,
.open = simple_open,
.write = adm1266_clear_blackbox_write,
.llseek = noop_llseek,
};
/*
* SET_RTC (0xDF) is a 6-byte block (datasheet Rev. D, Table 84):
* bytes [1:0] - fractional seconds (1/65536 s, written as zero)
* bytes [5:2] - seconds since 1970-01-01 UTC, little-endian
*
* The driver seeds it once at probe via adm1266_rtc_set(). Over a
* long uptime the chip's counter drifts away from host wall-clock,
* so expose it via debugfs:
*
* read -- returns the chip's current seconds counter, which lets
* userspace observe host-vs-chip drift.
* write -- the kernel re-reads ktime_get_real_seconds() and writes
* it to SET_RTC. The write payload is ignored; userspace
* does not get to supply its own timestamp value, so
* there is no way to push a wrong time into the chip.
*
* A small userspace agent (chrony hook, systemd-timesyncd script,
* or a periodic cron job) can write to this file to keep the
* timestamp embedded in each blackbox record aligned with
* wall-clock across long uptimes.
*/
static int adm1266_rtc_get(void *data, u64 *val)
{
struct i2c_client *client = data;
u8 buf[I2C_SMBUS_BLOCK_MAX];
u32 seconds = 0;
int ret, i;
guard(pmbus_lock)(client);
ret = i2c_smbus_read_block_data(client, ADM1266_SET_RTC, buf);
if (ret < 0)
return ret;
if (ret < 6)
return -EIO;
for (i = 0; i < 4; i++)
seconds |= (u32)buf[2 + i] << (i * 8);
*val = seconds;
return 0;
}
static int adm1266_rtc_set(void *data, u64 val)
{
struct i2c_client *client = data;
time64_t kt = ktime_get_real_seconds();
u8 write_buf[6] = { 0 };
int i;
/* User-supplied @val is ignored on purpose; the kernel owns the
* time source so userspace cannot push a wrong value into the chip.
*/
for (i = 0; i < 4; i++)
write_buf[2 + i] = (kt >> (i * 8)) & 0xFF;
guard(pmbus_lock)(client);
return i2c_smbus_write_block_data(client, ADM1266_SET_RTC,
sizeof(write_buf), write_buf);
}
DEFINE_DEBUGFS_ATTRIBUTE(adm1266_rtc_fops,
adm1266_rtc_get, adm1266_rtc_set, "%llu\n");
static void adm1266_init_debugfs(struct adm1266_data *data)
{
struct dentry *root;
root = pmbus_get_debugfs_dir(data->client);
if (!root)
return;
data->debugfs_dir = debugfs_create_dir(data->client->name, root);
debugfs_create_devm_seqfile(&data->client->dev, "sequencer_state", data->debugfs_dir,
adm1266_state_read);
debugfs_create_devm_seqfile(&data->client->dev, "firmware_revision", data->debugfs_dir,
adm1266_firmware_revision_read);
debugfs_create_devm_seqfile(&data->client->dev, "powerup_counter", data->debugfs_dir,
adm1266_powerup_counter_read);
debugfs_create_file("clear_blackbox", 0200, data->debugfs_dir, data->client,
&adm1266_clear_blackbox_fops);
debugfs_create_file("rtc", 0600, data->debugfs_dir, data->client,
&adm1266_rtc_fops);
Annotation
- Immediate include surface: `linux/bitfield.h`, `linux/crc8.h`, `linux/debugfs.h`, `linux/gpio/driver.h`, `linux/i2c.h`, `linux/i2c-smbus.h`, `linux/init.h`, `linux/kernel.h`.
- Detected declarations: `struct adm1266_data`, `function adm1266_pmbus_block_xfer`, `function adm1266_gpio_get`, `function adm1266_gpio_get_multiple`, `function for_each_set_bit_from`, `function adm1266_gpio_dbg_show`, `function adm1266_config_gpio`, `function adm1266_state_read`, `function IC_DEVICE_REV`, `function POWERUP_COUNTER`.
- Atlas domain: Driver Families / drivers/hwmon.
- Implementation status: pattern implementation candidate.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
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.