drivers/hwmon/lochnagar-hwmon.c
Source file repositories/reference/linux-study-clean/drivers/hwmon/lochnagar-hwmon.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/hwmon/lochnagar-hwmon.c- Extension
.c- Size
- 10046 bytes
- Lines
- 399
- 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/delay.hlinux/hwmon.hlinux/math64.hlinux/mfd/lochnagar.hlinux/mfd/lochnagar2_regs.hlinux/module.hlinux/of.hlinux/platform_device.hlinux/regmap.h
Detected Declarations
struct lochnagar_hwmonenum lochnagar_measure_modefunction float_to_longfunction do_measurementfunction request_datafunction read_sensorfunction read_powerfunction lochnagar_is_visiblefunction lochnagar_readfunction lochnagar_read_stringfunction lochnagar_writefunction lochnagar_hwmon_probe
Annotated Snippet
struct lochnagar_hwmon {
struct regmap *regmap;
long power_nsamples[ARRAY_SIZE(lochnagar_chan_names)];
};
enum lochnagar_measure_mode {
LN2_CURR = 0,
LN2_VOLT,
LN2_TEMP,
};
/**
* float_to_long - Convert ieee754 reading from hardware to an integer
*
* @data: Value read from the hardware
* @precision: Units to multiply up to eg. 1000 = milli, 1000000 = micro
*
* Return: Converted integer reading
*
* Depending on the measurement type the hardware returns an ieee754
* floating point value in either volts, amps or celsius. This function
* will convert that into an integer in a smaller unit such as micro-amps
* or milli-celsius. The hardware does not return NaN, so consideration of
* that is not required.
*/
static long float_to_long(u32 data, u32 precision)
{
u64 man = data & 0x007FFFFF;
int exp = ((data & 0x7F800000) >> 23) - 127 - 23;
bool negative = data & 0x80000000;
long result;
man = (man + (1 << 23)) * precision;
if (fls64(man) + exp > (int)sizeof(long) * 8 - 1)
result = LONG_MAX;
else if (exp < 0)
result = (man + (1ull << (-exp - 1))) >> -exp;
else
result = man << exp;
return negative ? -result : result;
}
static int do_measurement(struct regmap *regmap, int chan,
enum lochnagar_measure_mode mode, int nsamples)
{
unsigned int val;
int ret;
chan = 1 << (chan + LOCHNAGAR2_IMON_MEASURED_CHANNELS_SHIFT);
ret = regmap_write(regmap, LOCHNAGAR2_IMON_CTRL1,
LOCHNAGAR2_IMON_ENA_MASK | chan | mode);
if (ret < 0)
return ret;
ret = regmap_write(regmap, LOCHNAGAR2_IMON_CTRL2, nsamples);
if (ret < 0)
return ret;
ret = regmap_write(regmap, LOCHNAGAR2_IMON_CTRL3,
LOCHNAGAR2_IMON_CONFIGURE_MASK);
if (ret < 0)
return ret;
ret = regmap_read_poll_timeout(regmap, LOCHNAGAR2_IMON_CTRL3, val,
val & LOCHNAGAR2_IMON_DONE_MASK,
1000, 10000);
if (ret < 0)
return ret;
ret = regmap_write(regmap, LOCHNAGAR2_IMON_CTRL3,
LOCHNAGAR2_IMON_MEASURE_MASK);
if (ret < 0)
return ret;
/*
* Actual measurement time is ~1.67mS per sample, approximate this
* with a 1.5mS per sample msleep and then poll for success up to
* ~0.17mS * 1023 (LN2_MAX_NSAMPLES). Normally for smaller values
* of nsamples the poll will complete on the first loop due to
* other latency in the system.
*/
msleep((nsamples * 3) / 2);
ret = regmap_read_poll_timeout(regmap, LOCHNAGAR2_IMON_CTRL3, val,
val & LOCHNAGAR2_IMON_DONE_MASK,
5000, 200000);
Annotation
- Immediate include surface: `linux/delay.h`, `linux/hwmon.h`, `linux/math64.h`, `linux/mfd/lochnagar.h`, `linux/mfd/lochnagar2_regs.h`, `linux/module.h`, `linux/of.h`, `linux/platform_device.h`.
- Detected declarations: `struct lochnagar_hwmon`, `enum lochnagar_measure_mode`, `function float_to_long`, `function do_measurement`, `function request_data`, `function read_sensor`, `function read_power`, `function lochnagar_is_visible`, `function lochnagar_read`, `function lochnagar_read_string`.
- 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.