drivers/hwmon/ltc2945.c
Source file repositories/reference/linux-study-clean/drivers/hwmon/ltc2945.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/hwmon/ltc2945.c- Extension
.c- Size
- 15597 bytes
- Lines
- 531
- 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/kernel.hlinux/module.hlinux/err.hlinux/slab.hlinux/i2c.hlinux/hwmon.hlinux/hwmon-sysfs.hlinux/jiffies.hlinux/regmap.h
Detected Declarations
struct ltc2945_datafunction is_power_regfunction ltc2945_reg_to_valfunction ltc2945_val_to_regfunction ltc2945_value_showfunction ltc2945_value_storefunction ltc2945_history_storefunction ltc2945_bool_showfunction ltc2945_probe
Annotated Snippet
struct ltc2945_data {
struct regmap *regmap;
u32 shunt_resistor;
};
static inline bool is_power_reg(u8 reg)
{
return reg < LTC2945_SENSE_H;
}
/* Return the value from the given register in uW, mV, or mA */
static long long ltc2945_reg_to_val(struct device *dev, u8 reg)
{
struct ltc2945_data *data = dev_get_drvdata(dev);
struct regmap *regmap = data->regmap;
u32 shunt_resistor = data->shunt_resistor;
unsigned int control;
u8 buf[3];
long long val;
int ret;
ret = regmap_bulk_read(regmap, reg, buf,
is_power_reg(reg) ? 3 : 2);
if (ret < 0)
return ret;
if (is_power_reg(reg)) {
/* 24-bit power */
val = (buf[0] << 16) + (buf[1] << 8) + buf[2];
} else {
/* 12-bit current, voltage */
val = (buf[0] << 4) + (buf[1] >> 4);
}
switch (reg) {
case LTC2945_POWER_H:
case LTC2945_MAX_POWER_H:
case LTC2945_MIN_POWER_H:
case LTC2945_MAX_POWER_THRES_H:
case LTC2945_MIN_POWER_THRES_H:
/*
* Convert to uW
* Control register bit 0 selects if voltage at SENSE+/VDD
* or voltage at ADIN is used to measure power.
*/
ret = regmap_read(regmap, LTC2945_CONTROL, &control);
if (ret < 0)
return ret;
if (control & CONTROL_MULT_SELECT) {
/* 25 mV * 25 uV = 0.625 uV resolution. */
val *= 625LL;
} else {
/* 0.5 mV * 25 uV = 0.0125 uV resolution. */
val = (val * 25LL) >> 1;
}
val *= 1000;
/* Overflow check: Assuming max 24-bit power, val is at most 53 bits right now. */
val = DIV_ROUND_CLOSEST_ULL(val, shunt_resistor);
/*
* Overflow check: After division, depending on shunt resistor,
* val can still be > 32 bits so returning long long makes sense
*/
break;
case LTC2945_VIN_H:
case LTC2945_MAX_VIN_H:
case LTC2945_MIN_VIN_H:
case LTC2945_MAX_VIN_THRES_H:
case LTC2945_MIN_VIN_THRES_H:
/* 25 mV resolution. Convert to mV. */
val *= 25;
break;
case LTC2945_ADIN_H:
case LTC2945_MAX_ADIN_H:
case LTC2945_MIN_ADIN_THRES_H:
case LTC2945_MAX_ADIN_THRES_H:
case LTC2945_MIN_ADIN_H:
/* 0.5mV resolution. Convert to mV. */
val = val >> 1;
break;
case LTC2945_SENSE_H:
case LTC2945_MAX_SENSE_H:
case LTC2945_MIN_SENSE_H:
case LTC2945_MAX_SENSE_THRES_H:
case LTC2945_MIN_SENSE_THRES_H:
/* 25 uV resolution. Convert to mA. */
val *= 25 * 1000;
/* Overflow check: Assuming max 12-bit sense, val is at most 27 bits right now */
val = DIV_ROUND_CLOSEST_ULL(val, shunt_resistor);
/* Overflow check: After division, <= 27 bits */
Annotation
- Immediate include surface: `linux/kernel.h`, `linux/module.h`, `linux/err.h`, `linux/slab.h`, `linux/i2c.h`, `linux/hwmon.h`, `linux/hwmon-sysfs.h`, `linux/jiffies.h`.
- Detected declarations: `struct ltc2945_data`, `function is_power_reg`, `function ltc2945_reg_to_val`, `function ltc2945_val_to_reg`, `function ltc2945_value_show`, `function ltc2945_value_store`, `function ltc2945_history_store`, `function ltc2945_bool_show`, `function ltc2945_probe`.
- 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.