drivers/hwmon/lm80.c
Source file repositories/reference/linux-study-clean/drivers/hwmon/lm80.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/hwmon/lm80.c- Extension
.c- Size
- 18710 bytes
- Lines
- 648
- Domain
- Driver Families
- Bucket
- drivers/hwmon
- 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.
- 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/module.hlinux/init.hlinux/slab.hlinux/jiffies.hlinux/i2c.hlinux/hwmon.hlinux/hwmon-sysfs.hlinux/err.hlinux/mutex.h
Detected Declarations
struct lm80_dataenum temp_indexenum in_indexenum fan_indexfunction FAN_TO_REGfunction lm80_read_valuefunction lm80_write_valuefunction lm80_init_clientfunction in_showfunction in_storefunction fan_showfunction fan_div_showfunction fan_storefunction fan_div_storefunction temp_showfunction temp_storefunction alarms_showfunction alarm_showfunction lm80_detectfunction lm80_probe
Annotated Snippet
struct lm80_data {
struct i2c_client *client;
struct mutex update_lock;
char error; /* !=0 if error occurred during last update */
bool valid; /* true if following fields are valid */
unsigned long last_updated; /* In jiffies */
u8 in[i_num_in][7]; /* Register value, 1st index is enum in_index */
u8 fan[f_num_fan][2]; /* Register value, 1st index enum fan_index */
u8 fan_div[2]; /* Register encoding, shifted right */
s16 temp[t_num_temp]; /* Register values, normalized to 16 bit */
u16 alarms; /* Register encoding, combined */
};
static int lm80_read_value(struct i2c_client *client, u8 reg)
{
return i2c_smbus_read_byte_data(client, reg);
}
static int lm80_write_value(struct i2c_client *client, u8 reg, u8 value)
{
return i2c_smbus_write_byte_data(client, reg, value);
}
/* Called when we have found a new LM80 and after read errors */
static void lm80_init_client(struct i2c_client *client)
{
/*
* Reset all except Watchdog values and last conversion values
* This sets fan-divs to 2, among others. This makes most other
* initializations unnecessary
*/
lm80_write_value(client, LM80_REG_CONFIG, 0x80);
/* Set 11-bit temperature resolution */
lm80_write_value(client, LM80_REG_RES, 0x08);
/* Start monitoring */
lm80_write_value(client, LM80_REG_CONFIG, 0x01);
}
static struct lm80_data *lm80_update_device(struct device *dev)
{
struct lm80_data *data = dev_get_drvdata(dev);
struct i2c_client *client = data->client;
int i;
int rv;
int prev_rv;
struct lm80_data *ret = data;
mutex_lock(&data->update_lock);
if (data->error)
lm80_init_client(client);
if (time_after(jiffies, data->last_updated + 2 * HZ) || !data->valid) {
dev_dbg(dev, "Starting lm80 update\n");
for (i = 0; i <= 6; i++) {
rv = lm80_read_value(client, LM80_REG_IN(i));
if (rv < 0)
goto abort;
data->in[i_input][i] = rv;
rv = lm80_read_value(client, LM80_REG_IN_MIN(i));
if (rv < 0)
goto abort;
data->in[i_min][i] = rv;
rv = lm80_read_value(client, LM80_REG_IN_MAX(i));
if (rv < 0)
goto abort;
data->in[i_max][i] = rv;
}
rv = lm80_read_value(client, LM80_REG_FAN1);
if (rv < 0)
goto abort;
data->fan[f_input][0] = rv;
rv = lm80_read_value(client, LM80_REG_FAN_MIN(1));
if (rv < 0)
goto abort;
data->fan[f_min][0] = rv;
rv = lm80_read_value(client, LM80_REG_FAN2);
if (rv < 0)
goto abort;
data->fan[f_input][1] = rv;
rv = lm80_read_value(client, LM80_REG_FAN_MIN(2));
if (rv < 0)
Annotation
- Immediate include surface: `linux/module.h`, `linux/init.h`, `linux/slab.h`, `linux/jiffies.h`, `linux/i2c.h`, `linux/hwmon.h`, `linux/hwmon-sysfs.h`, `linux/err.h`.
- Detected declarations: `struct lm80_data`, `enum temp_index`, `enum in_index`, `enum fan_index`, `function FAN_TO_REG`, `function lm80_read_value`, `function lm80_write_value`, `function lm80_init_client`, `function in_show`, `function in_store`.
- Atlas domain: Driver Families / drivers/hwmon.
- Implementation status: source 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.