drivers/power/supply/da9150-fg.c
Source file repositories/reference/linux-study-clean/drivers/power/supply/da9150-fg.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/power/supply/da9150-fg.c- Extension
.c- Size
- 14190 bytes
- Lines
- 562
- Domain
- Driver Families
- Bucket
- drivers/power
- 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.
- Touches IRQ or DMA behavior; this matters for the representative real-device path.
- 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/platform_device.hlinux/of.hlinux/slab.hlinux/interrupt.hlinux/delay.hlinux/power_supply.hlinux/list.hasm/div64.hlinux/mfd/da9150/core.hlinux/mfd/da9150/registers.hlinux/devm-helpers.h
Detected Declarations
struct da9150_fgfunction da9150_fg_read_attrfunction da9150_fg_write_attrfunction da9150_fg_read_sync_startfunction da9150_fg_read_sync_endfunction da9150_fg_read_attr_syncfunction da9150_fg_write_attr_syncfunction da9150_fg_capacityfunction da9150_fg_current_avgfunction da9150_fg_voltage_avgfunction da9150_fg_charge_fullfunction da9150_fg_tempfunction da9150_fg_get_propfunction da9150_fg_soc_changedfunction da9150_fg_workfunction da9150_fg_soc_event_configfunction da9150_fg_irqfunction da9150_fg_probefunction da9150_fg_resume
Annotated Snippet
struct da9150_fg {
struct da9150 *da9150;
struct device *dev;
struct mutex io_lock;
struct power_supply *battery;
struct delayed_work work;
u32 interval;
int warn_soc;
int crit_soc;
int soc;
};
/* Battery Properties */
static u32 da9150_fg_read_attr(struct da9150_fg *fg, u8 code, u8 size)
{
u8 buf[DA9150_QIF_LONG_SIZE];
u8 read_addr;
u32 res = 0;
int i;
/* Set QIF code (READ mode) */
read_addr = (code & DA9150_QIF_CODE_MASK) | DA9150_QIF_READ;
da9150_read_qif(fg->da9150, read_addr, size, buf);
for (i = 0; i < size; ++i)
res |= (buf[i] << (i * DA9150_QIF_BYTE_SIZE));
return res;
}
static void da9150_fg_write_attr(struct da9150_fg *fg, u8 code, u8 size,
u32 val)
{
u8 buf[DA9150_QIF_LONG_SIZE];
u8 write_addr;
int i;
/* Set QIF code (WRITE mode) */
write_addr = (code & DA9150_QIF_CODE_MASK) | DA9150_QIF_WRITE;
for (i = 0; i < size; ++i) {
buf[i] = (val >> (i * DA9150_QIF_BYTE_SIZE)) &
DA9150_QIF_BYTE_MASK;
}
da9150_write_qif(fg->da9150, write_addr, size, buf);
}
/* Trigger QIF Sync to update QIF readable data */
static void da9150_fg_read_sync_start(struct da9150_fg *fg)
{
int i = 0;
u32 res = 0;
mutex_lock(&fg->io_lock);
/* Check if QIF sync already requested, and write to sync if not */
res = da9150_fg_read_attr(fg, DA9150_QIF_SYNC,
DA9150_QIF_SYNC_SIZE);
if (res > 0)
da9150_fg_write_attr(fg, DA9150_QIF_SYNC,
DA9150_QIF_SYNC_SIZE, 0);
/* Wait for sync to complete */
res = 0;
while ((res == 0) && (i++ < DA9150_QIF_SYNC_RETRIES)) {
usleep_range(DA9150_QIF_SYNC_TIMEOUT,
DA9150_QIF_SYNC_TIMEOUT * 2);
res = da9150_fg_read_attr(fg, DA9150_QIF_SYNC,
DA9150_QIF_SYNC_SIZE);
}
/* Check if sync completed */
if (res == 0)
dev_err(fg->dev, "Failed to perform QIF read sync!\n");
}
/*
* Should always be called after QIF sync read has been performed, and all
* attributes required have been accessed.
*/
static inline void da9150_fg_read_sync_end(struct da9150_fg *fg)
{
mutex_unlock(&fg->io_lock);
}
Annotation
- Immediate include surface: `linux/kernel.h`, `linux/module.h`, `linux/platform_device.h`, `linux/of.h`, `linux/slab.h`, `linux/interrupt.h`, `linux/delay.h`, `linux/power_supply.h`.
- Detected declarations: `struct da9150_fg`, `function da9150_fg_read_attr`, `function da9150_fg_write_attr`, `function da9150_fg_read_sync_start`, `function da9150_fg_read_sync_end`, `function da9150_fg_read_attr_sync`, `function da9150_fg_write_attr_sync`, `function da9150_fg_capacity`, `function da9150_fg_current_avg`, `function da9150_fg_voltage_avg`.
- Atlas domain: Driver Families / drivers/power.
- Implementation status: source implementation candidate.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
- IRQ or DMA behavior appears here, which is relevant to the selected PCIe/NVMe device path.
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.