drivers/power/supply/macsmc-power.c
Source file repositories/reference/linux-study-clean/drivers/power/supply/macsmc-power.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/power/supply/macsmc-power.c- Extension
.c- Size
- 25950 bytes
- Lines
- 856
- 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.
- 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/ctype.hlinux/delay.hlinux/devm-helpers.hlinux/limits.hlinux/module.hlinux/mfd/macsmc.hlinux/notifier.hlinux/of.hlinux/platform_device.hlinux/power_supply.hlinux/reboot.hlinux/workqueue.h
Detected Declarations
struct macsmc_powerfunction macsmc_battery_get_statusfunction macsmc_battery_get_charge_behaviourfunction macsmc_battery_set_charge_behaviourfunction macsmc_battery_get_datefunction macsmc_battery_get_capacity_levelfunction macsmc_battery_get_propertyfunction macsmc_battery_set_propertyfunction macsmc_battery_property_is_writeablefunction macsmc_ac_get_propertyfunction macsmc_power_critical_workfunction apple_smc_read_u16function macsmc_power_eventfunction eventsfunction macsmc_power_probefunction macsmc_power_remove
Annotated Snippet
struct macsmc_power {
struct device *dev;
struct apple_smc *smc;
struct power_supply_desc ac_desc;
struct power_supply_desc batt_desc;
struct power_supply *batt;
struct power_supply *ac;
char model_name[MAX_STRING_LENGTH];
char serial_number[MAX_STRING_LENGTH];
char mfg_date[MAX_STRING_LENGTH];
/* Supported feature flags based on SMC key presence */
bool has_chwa; /* Charge limit (Modern firmware) */
bool has_chls; /* Charge limit (Older firmware) */
bool has_ch0i; /* Force discharge (Older firmware) */
bool has_ch0c; /* Inhibit charge (Older firmware) */
bool has_chte; /* Inhibit charge (Modern firmware) */
u8 num_cells;
int nominal_voltage_mv;
struct notifier_block nb;
struct work_struct critical_work;
bool emergency_shutdown_triggered;
bool orderly_shutdown_triggered;
};
static int macsmc_battery_get_status(struct macsmc_power *power)
{
u64 nocharge_flags;
u32 nopower_flags;
u16 ac_current;
int charge_limit = 0;
bool limited = false;
bool flag;
int ret;
/*
* B0AV (Voltage) is fundamental. If we can't read it, we assume the
* battery is gone. CHCE (Hardware charger present) / CHCC (Hardware
* charger capable) are fundamental status flags.
* BSFC (System full charge) / CHSC (System charging) are fundamental
* status flags.
*/
/* Check if power input is inhibited (e.g. BMS balancing cycle) */
ret = apple_smc_read_u32(power->smc, SMC_KEY(CH0R), &nopower_flags);
if (!ret && (nopower_flags & CH0R_LOWER_FLAGS & ~CH0R_BMS_BUSY))
return POWER_SUPPLY_STATUS_DISCHARGING;
/* Check if charger is present */
ret = apple_smc_read_flag(power->smc, SMC_KEY(CHCE), &flag);
if (ret < 0)
return ret;
if (!flag)
return POWER_SUPPLY_STATUS_DISCHARGING;
/* Check if AC is charge capable */
ret = apple_smc_read_flag(power->smc, SMC_KEY(CHCC), &flag);
if (ret < 0)
return ret;
if (!flag)
return POWER_SUPPLY_STATUS_DISCHARGING;
/* Check if AC input limit is too low */
ret = apple_smc_read_u16(power->smc, SMC_KEY(AC-i), &ac_current);
if (!ret && ac_current < 100)
return POWER_SUPPLY_STATUS_DISCHARGING;
/* Check if battery is full */
ret = apple_smc_read_flag(power->smc, SMC_KEY(BSFC), &flag);
if (ret < 0)
return ret;
if (flag)
return POWER_SUPPLY_STATUS_FULL;
/* Check for user-defined charge limits */
if (power->has_chls) {
u16 vu16;
ret = apple_smc_read_u16(power->smc, SMC_KEY(CHLS), &vu16);
if (ret == 0 && (vu16 & 0xff) >= CHLS_MIN_END_THRESHOLD)
charge_limit = (vu16 & 0xff) - CHWA_CHLS_FIXED_START_OFFSET;
} else if (power->has_chwa) {
ret = apple_smc_read_flag(power->smc, SMC_KEY(CHWA), &flag);
if (ret == 0 && flag)
charge_limit = CHWA_FIXED_END_THRESHOLD - CHWA_CHLS_FIXED_START_OFFSET;
Annotation
- Immediate include surface: `linux/ctype.h`, `linux/delay.h`, `linux/devm-helpers.h`, `linux/limits.h`, `linux/module.h`, `linux/mfd/macsmc.h`, `linux/notifier.h`, `linux/of.h`.
- Detected declarations: `struct macsmc_power`, `function macsmc_battery_get_status`, `function macsmc_battery_get_charge_behaviour`, `function macsmc_battery_set_charge_behaviour`, `function macsmc_battery_get_date`, `function macsmc_battery_get_capacity_level`, `function macsmc_battery_get_property`, `function macsmc_battery_set_property`, `function macsmc_battery_property_is_writeable`, `function macsmc_ac_get_property`.
- Atlas domain: Driver Families / drivers/power.
- 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.