drivers/hwmon/adm9240.c
Source file repositories/reference/linux-study-clean/drivers/hwmon/adm9240.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/hwmon/adm9240.c- Extension
.c- Size
- 19981 bytes
- Lines
- 821
- 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.
- 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/bits.hlinux/init.hlinux/module.hlinux/slab.hlinux/i2c.hlinux/hwmon-sysfs.hlinux/hwmon.hlinux/hwmon-vid.hlinux/err.hlinux/regmap.h
Detected Declarations
struct adm9240_dataenum chipsfunction SCALEfunction IN_FROM_REGfunction IN_TO_REGfunction TEMP_TO_REGfunction FAN_FROM_REGfunction AOUT_TO_REGfunction AOUT_FROM_REGfunction adm9240_write_fan_divfunction adm9240_fan_min_writefunction cpu0_vid_showfunction aout_output_showfunction aout_output_storefunction adm9240_detectfunction adm9240_init_clientfunction adm9240_chip_readfunction adm9240_intrusion_readfunction adm9240_intrusion_writefunction adm9240_in_readfunction adm9240_in_writefunction adm9240_fan_readfunction adm9240_fan_writefunction adm9240_temp_readfunction adm9240_temp_writefunction adm9240_readfunction adm9240_writefunction adm9240_is_visiblefunction adm9240_volatile_regfunction adm9240_probe
Annotated Snippet
struct adm9240_data {
struct device *dev;
struct regmap *regmap;
u8 fan_div[2]; /* rw fan1_div, read-only accessor */
u8 vrm; /* -- vrm set on startup, no accessor */
};
/* write new fan div, callers must hold data->update_lock */
static int adm9240_write_fan_div(struct adm9240_data *data, int channel, u8 fan_div)
{
unsigned int reg, old, shift = (channel + 2) * 2;
int err;
err = regmap_read(data->regmap, ADM9240_REG_VID_FAN_DIV, ®);
if (err < 0)
return err;
old = (reg >> shift) & 3;
reg &= ~(3 << shift);
reg |= (fan_div << shift);
err = regmap_write(data->regmap, ADM9240_REG_VID_FAN_DIV, reg);
if (err < 0)
return err;
dev_dbg(data->dev,
"fan%d clock divider changed from %lu to %lu\n",
channel + 1, BIT(old), BIT(fan_div));
return 0;
}
/*
* set fan speed low limit:
*
* - value is zero: disable fan speed low limit alarm
*
* - value is below fan speed measurement range: enable fan speed low
* limit alarm to be asserted while fan speed too slow to measure
*
* - otherwise: select fan clock divider to suit fan speed low limit,
* measurement code may adjust registers to ensure fan speed reading
*/
static int adm9240_fan_min_write(struct adm9240_data *data, int channel, long val)
{
u8 new_div;
u8 fan_min;
int err;
if (!val) {
fan_min = 255;
new_div = data->fan_div[channel];
dev_dbg(data->dev, "fan%u low limit set disabled\n", channel + 1);
} else if (val < 1350000 / (8 * 254)) {
new_div = 3;
fan_min = 254;
dev_dbg(data->dev, "fan%u low limit set minimum %u\n",
channel + 1, FAN_FROM_REG(254, BIT(new_div)));
} else {
unsigned int new_min = 1350000 / val;
new_div = 0;
while (new_min > 192 && new_div < 3) {
new_div++;
new_min /= 2;
}
if (!new_min) /* keep > 0 */
new_min++;
fan_min = new_min;
dev_dbg(data->dev, "fan%u low limit set fan speed %u\n",
channel + 1, FAN_FROM_REG(new_min, BIT(new_div)));
}
if (new_div != data->fan_div[channel]) {
data->fan_div[channel] = new_div;
adm9240_write_fan_div(data, channel, new_div);
}
err = regmap_write(data->regmap, ADM9240_REG_FAN_MIN(channel), fan_min);
return err;
}
static ssize_t cpu0_vid_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct adm9240_data *data = dev_get_drvdata(dev);
unsigned int regval;
int err;
Annotation
- Immediate include surface: `linux/bits.h`, `linux/init.h`, `linux/module.h`, `linux/slab.h`, `linux/i2c.h`, `linux/hwmon-sysfs.h`, `linux/hwmon.h`, `linux/hwmon-vid.h`.
- Detected declarations: `struct adm9240_data`, `enum chips`, `function SCALE`, `function IN_FROM_REG`, `function IN_TO_REG`, `function TEMP_TO_REG`, `function FAN_FROM_REG`, `function AOUT_TO_REG`, `function AOUT_FROM_REG`, `function adm9240_write_fan_div`.
- Atlas domain: Driver Families / drivers/hwmon.
- 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.