drivers/hwmon/ina3221.c
Source file repositories/reference/linux-study-clean/drivers/hwmon/ina3221.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/hwmon/ina3221.c- Extension
.c- Size
- 27284 bytes
- Lines
- 1025
- 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/debugfs.hlinux/hwmon.hlinux/hwmon-sysfs.hlinux/i2c.hlinux/module.hlinux/of.hlinux/pm_runtime.hlinux/regmap.hlinux/util_macros.h
Detected Declarations
struct ina3221_inputstruct ina3221_dataenum ina3221_fieldsenum ina3221_channelsfunction ina3221_is_enabledfunction ina3221_summation_shunt_resistorfunction ina3221_interval_ms_to_conv_timefunction ina3221_reg_to_interval_usfunction ina3221_wait_for_datafunction ina3221_read_valuefunction ina3221_read_chipfunction ina3221_read_infunction ina3221_read_currfunction ina3221_write_chipfunction ina3221_write_currfunction ina3221_write_enablefunction ina3221_readfunction ina3221_writefunction ina3221_read_stringfunction ina3221_is_visiblefunction ina3221_shunt_showfunction ina3221_shunt_storefunction ina3221_probe_child_from_dtfunction ina3221_probe_from_dtfunction for_each_child_of_node_scopedfunction ina3221_probefunction ina3221_removefunction ina3221_suspendfunction ina3221_resume
Annotated Snippet
struct ina3221_input {
const char *label;
int shunt_resistor;
bool disconnected;
bool summation_disable;
};
/**
* struct ina3221_data - device specific information
* @pm_dev: Device pointer for pm runtime
* @regmap: Register map of the device
* @fields: Register fields of the device
* @inputs: Array of channel input source specific structures
* @reg_config: Register value of INA3221_CONFIG
* @summation_shunt_resistor: equivalent shunt resistor value for summation
* @summation_channel_control: Value written to SCC field in INA3221_MASK_ENABLE
* @single_shot: running in single-shot operating mode
*/
struct ina3221_data {
struct device *pm_dev;
struct regmap *regmap;
struct regmap_field *fields[F_MAX_FIELDS];
struct ina3221_input inputs[INA3221_NUM_CHANNELS];
u32 reg_config;
int summation_shunt_resistor;
u32 summation_channel_control;
bool single_shot;
};
static inline bool ina3221_is_enabled(struct ina3221_data *ina, int channel)
{
/* Summation channel checks shunt resistor values */
if (channel > INA3221_CHANNEL3)
return ina->summation_shunt_resistor != 0;
return pm_runtime_active(ina->pm_dev) &&
(ina->reg_config & INA3221_CONFIG_CHx_EN(channel));
}
/*
* Helper function to return the resistor value for current summation.
*
* There is a condition to calculate current summation -- all the shunt
* resistor values should be the same, so as to simply fit the formula:
* current summation = shunt voltage summation / shunt resistor
*
* Returns the equivalent shunt resistor value on success or 0 on failure
*/
static inline int ina3221_summation_shunt_resistor(struct ina3221_data *ina)
{
struct ina3221_input *input = ina->inputs;
int i, shunt_resistor = 0;
for (i = 0; i < INA3221_NUM_CHANNELS; i++) {
if (input[i].disconnected || !input[i].shunt_resistor ||
input[i].summation_disable)
continue;
if (!shunt_resistor) {
/* Found the reference shunt resistor value */
shunt_resistor = input[i].shunt_resistor;
} else {
/* No summation if resistor values are different */
if (shunt_resistor != input[i].shunt_resistor)
return 0;
}
}
return shunt_resistor;
}
/* Lookup table for Bus and Shunt conversion times in usec */
static const u16 ina3221_conv_time[] = {
140, 204, 332, 588, 1100, 2116, 4156, 8244,
};
/* Lookup table for number of samples using in averaging mode */
static const int ina3221_avg_samples[] = {
1, 4, 16, 64, 128, 256, 512, 1024,
};
/* Converting update_interval in msec to conversion time in usec */
static inline u32 ina3221_interval_ms_to_conv_time(u16 config, int interval)
{
u32 channels = hweight16(config & INA3221_CONFIG_CHs_EN_MASK);
u32 samples_idx = INA3221_CONFIG_AVG(config);
u32 samples = ina3221_avg_samples[samples_idx];
/* Bisect the result to Bus and Shunt conversion times */
return DIV_ROUND_CLOSEST(interval * 1000 / 2, channels * samples);
Annotation
- Immediate include surface: `linux/debugfs.h`, `linux/hwmon.h`, `linux/hwmon-sysfs.h`, `linux/i2c.h`, `linux/module.h`, `linux/of.h`, `linux/pm_runtime.h`, `linux/regmap.h`.
- Detected declarations: `struct ina3221_input`, `struct ina3221_data`, `enum ina3221_fields`, `enum ina3221_channels`, `function ina3221_is_enabled`, `function ina3221_summation_shunt_resistor`, `function ina3221_interval_ms_to_conv_time`, `function ina3221_reg_to_interval_us`, `function ina3221_wait_for_data`, `function ina3221_read_value`.
- 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.