STRUCT POWER_SUPPLY_BATTERY_INFO(9)

๐Ÿ“ฆ version 7.3.1, in nixpkgs unstable

okay so this is struct power_supply_battery_info(9) straight out of the Kernel API Manual (section 9, kernel-dev girlies rise ๐Ÿซถ). It's a struct page, so like โ€” no flags, no exit statuses, just vibes and a lot of fields. Let's get into it โœจ


๐ŸŒธ NAME ๐ŸŒธ

struct power_supply_battery_info โ€” literally just, information about batteries ๐Ÿ’… no cap, that's the whole thing


๐ŸŽ€ SYNOPSIS ๐ŸŽ€

bestie. take a deep breath. count the fields with me. it's giving thorough ๐Ÿ‘‘

struct power_supply_battery_info {
    unsigned int technology;
    int energy_full_design_uwh;
    int charge_full_design_uah;
    int voltage_min_design_uv;
    int voltage_max_design_uv;
    int tricklecharge_current_ua;
    int precharge_current_ua;
    int precharge_voltage_max_uv;
    int charge_term_current_ua;
    int charge_restart_voltage_uv;
    int overvoltage_limit_uv;
    int constant_charge_current_max_ua;
    int constant_charge_voltage_max_uv;
    const struct power_supply_maintenance_charge_table *maintenance_charge;
    int maintenance_charge_size;
    int alert_low_temp_charge_current_ua;
    int alert_low_temp_charge_voltage_uv;
    int alert_high_temp_charge_current_ua;
    int alert_high_temp_charge_voltage_uv;
    int factory_internal_resistance_uohm;
    int factory_internal_resistance_charging_uohm;
    int ocv_temp[POWER_SUPPLY_OCV_TEMP_MAX];
    int temp_ambient_alert_min;
    int temp_ambient_alert_max;
    int temp_alert_min;
    int temp_alert_max;
    int temp_min;
    int temp_max;
    const struct power_supply_battery_ocv_table *ocv_table[POWER_SUPPLY_OCV_TEMP_MAX];
    int ocv_table_size[POWER_SUPPLY_OCV_TEMP_MAX];
    const struct power_supply_resistance_temp_table *resist_table;
    int resist_table_size;
    const struct power_supply_vbat_ri_table *vbat2ri_discharging;
    int vbat2ri_discharging_size;
    const struct power_supply_vbat_ri_table *vbat2ri_charging;
    int vbat2ri_charging_size;
    int bti_resistance_ohm;
    int bti_resistance_tolerance;
};

likeโ€ฆ look at all those _ua and _uv and _uwh suffixes. micro-units everywhere. it's giving "we take our magnitudes very seriously" ๐Ÿ˜ญ and the const pointer arrays? *ocv_table[POWER_SUPPLY_OCV_TEMP_MAX] and friends โ€” highkey iconic of them fr fr ๐ŸŒˆ

ngl the maintenance_charge field is a const struct power_supply_maintenance_charge_table * and my girl is just vibing in the middle of the ints. balance. โญ

that's the SYNOPSIS done and honestly that's already a lot of homework โ€” but there's more coming, so don't go anywhere bestie ๐Ÿ’–

โœจ Members โœจ

  • technology โ€” bestie, this one comes straight from the POWER_SUPPLY_TECHNOLOGY_* enum. It's giving "what kind of battery are we even dealing with" energy. ๐Ÿ’…
  • energy_full_design_uwh โ€” the energy content when the battery is fully charged, measured in microwatt hours. โœจ
  • charge_full_design_uah โ€” the charge content when the battery is fully charged, measured in microampere hours. ๐Ÿ”‹
  • voltage_min_design_uv โ€” the minimum voltage across the poles when the battery is at its minimum voltage level, in microvolts. If the voltage drops below this level, the battery will need precharging when using CC/CV charging. No cap, that's the vibe check. ๐Ÿ˜ญ
  • voltage_max_design_uv โ€” the voltage across the poles when the battery is fully charged, in microvolts. This is the "nominal voltage" โ€” i.e. the voltage printed on the label of the battery. Periodt. ๐Ÿท๏ธ
  • tricklecharge_current_ua โ€” the tricklecharge current used when trickle charging the battery, in microamperes. This is the charging phase when the battery is completely empty and we need to carefully trickle in some charge until we reach the precharging voltage. It's giving "gentle lil top-up" energy. ๐Ÿงš
  • precharge_current_ua โ€” the current to use in the precharge phase, in microamperes. The precharge rate is limited by limiting the current to this value. Lowkey important. ๐Ÿ’œ
  • precharge_voltage_max_uv โ€” the maximum voltage allowed when precharging, in microvolts. When we pass this voltage, we will nominally switch over to the CC (constant current) charging phase defined by constant_charge_current_ua and constant_charge_voltage_max_uv. It's a whole transition moment. ๐Ÿฆ‹
  • charge_term_current_ua โ€” when the current in the CV (constant voltage) charging phase drops below this value, in microamperes, the charging will terminate completely and not restart until the voltage over the battery poles reaches charge_restart_voltage_uv โ€” unless we use maintenance charging. So dramatic, honestly. ๐Ÿ’€
  • charge_restart_voltage_uv โ€” when the battery has been fully charged by CC/CV charging and charging has been disabled, and the voltage subsequently drops below this value in microvolts, the charging will be restarted (typically using CV charging). It's giving "comes back when you least expect it" energy. ๐Ÿ”ฅ
  • overvoltage_limit_uv โ€” okay so if the voltage exceeds the nominal voltage voltage_max_design_uv and we reach this voltage level, all charging must stop and emergency procedures take place, such as shutting down the system in some cases. This is serious bestie, not a drill. ๐Ÿšจ
  • constant_charge_current_max_ua โ€” the current in microamperes to use in the CC (constant current) charging phase. The charging rate is limited by this current. This is the main charging phase, and as the current is constant into the battery, the voltage slowly ascends to constant_charge_voltage_max_uv. Main character energy fr fr. ๐Ÿ‘‘
  • constant_charge_voltage_max_uv โ€” the voltage in microvolts signifying the end of the CC (constant current) charging phase and the beginning of the CV (constant voltage) charging phase. It's the handoff moment. ๐ŸŽ€
  • maintenance_charge โ€” an array of maintenance charging settings to be used after the main CC/CV charging phase is complete. Like a little afterparty for your battery. ๐ŸŽ‰
  • maintenance_charge_size โ€” the number of maintenance charging settings in maintenance_charge. Gotta know how many guests are at the afterparty. ๐Ÿ’ƒ
  • alert_low_temp_charge_current_ua โ€” the charging current to use if the battery enters low alert temperature, i.e. if the internal temperature is between temp_alert_min and temp_min. No matter the charging phase, this and alert_high_temp_charge_voltage_uv will be applied. (Yes, bestie, it says alert_high_temp_charge_voltage_uv โ€” we don't make the rules, we just report them.) ๐Ÿ™ˆ
  • alert_low_temp_charge_voltage_uv โ€” same as alert_low_temp_charge_current_ua, but for the charging voltage. Twin energy. ๐Ÿ‘ฏ
  • alert_high_temp_charge_current_ua โ€” the charging current to use if the battery enters high alert temperature, i.e. if the internal temperature is between temp_alert_max and temp_max. No matter the charging phase, this and alert_high_temp_charge_voltage_uv will be applied โ€” usually lowering the charging current as an evasive manouver. It's giving "backing away slowly" vibes. ๐Ÿ˜…
  • alert_high_temp_charge_voltage_uv โ€” same as alert_high_temp_charge_current_ua, but for the charging voltage. Another twin. โœŒ๏ธ
  • factory_internal_resistance_uohm โ€” the internal resistance of the battery at fabrication time, expressed in microohms. This resistance will vary depending on the lifetime and charge of the battery, so this is just a nominal ballpark figure. This internal resistance is given for the state when the battery is discharging. Lowkey a snapshot, not the whole story. ๐Ÿ“ธ
  • factory_internal_resistance_charging_uohm โ€” the internal resistance of the battery at fabrication time while charging, expressed in microohms. The charging process will affect the internal resistance of the battery, so this value provides a better resistance under these circumstances. This resistance will vary depending on the lifetime and charge of the battery, so this is just a nominal ballpark figure. Again: ballpark, bestie. โšพ
  • ocv_temp โ€” an array indicating the open circuit voltage (OCV) capacity temperature indices. This is an array of temperatures in degrees Celsius indicating which capacity table to use for a certain temperature, since the capacity โ€” for reasons of chemistry โ€” will be different at different temperatures. Determining capacity is a multivariate problem and the temperature is the first variable we determine. Science slay. ๐Ÿงช
  • temp_ambient_alert_min โ€” the battery will go outside of operating conditions when the ambient temperature goes below this temperature, in degrees Celsius. Too cold, no thank you. โ„๏ธ
  • temp_ambient_alert_max โ€” the battery will go outside of operating conditions when the ambient temperature goes above this temperature, in degrees Celsius. Too hot, also no thank you. ๐ŸŒž
  • temp_alert_min โ€” the battery should issue an alert if the internal temperature goes below this temperature, in degrees Celsius. A little warning bell. ๐Ÿ””
  • temp_alert_max โ€” the battery should issue an alert if the internal temperature goes above this temperature, in degrees Celsius. Another warning bell. ๐Ÿ””
  • temp_min โ€” the battery will go outside of operating conditions when the internal temperature goes below this temperature, in degrees Celsius. Normally this means the system should shut down. So like, actually serious. ๐Ÿ›‘
  • temp_max โ€” the battery will go outside of operating conditions when the internal temperature goes above this temperature, in degrees Celsius. Normally this means the system should shut down. Also actually serious. ๐Ÿ›‘
  • ocv_table โ€” for each entry in ocv_temp there is a corresponding entry in ocv_table and a size for each entry in ocv_table_size. These arrays determine the capacity in percent in relation to the voltage in microvolts at the indexed temperature. It's a whole lookup situation. ๐Ÿ”
  • ocv_table_size โ€” for each entry in ocv_temp this array is giving the size of each entry in the array of capacity arrays in ocv_table. Gotta know how big each table is, obviously. ๐Ÿ“
  • resist_table โ€” this is a table that correlates a battery temperature to the expected internal resistance at this temperature. The resistance is given as a percentage of factory_internal_resistance_uohm. Knowing the resistance of the battery is usually necessary for calculating the open circuit voltage (OCV) that is then used with the ocv_table to calculate the capacity of the battery. The resist_table must be ordered descending by temperature: highest temperature with lowest resistance first, lowest temperature with highest resistance last. Don't mess up the order, bestie. ๐Ÿ—‚๏ธ
  • resist_table_size โ€” the number of items in the resist_table. Count 'em. ๐Ÿ”ข
  • vbat2ri_discharging โ€” this is a table that correlates Battery voltage (VBAT) to internal resistance (Ri). The resistance is given in microohm for the corresponding voltage in microvolts. The internal resistance is used to determine the open circuit voltage so that we can determine the capacity of the battery. These voltages-to-resistance tables apply when the battery is discharging. The table must be ordered descending by voltage: highest voltage first. Order matters, fr fr. โšก
  • vbat2ri_discharging_size โ€” the number of items in the vbat2ri_discharging table. Another count. ๐Ÿงฎ
  • vbat2ri_charging โ€” same function as vbat2ri_discharging but for the state when the battery is charging. Being under charge changes the battery's internal resistance characteristics, so a separate table is needed.* The table must be ordered descending by voltage: highest voltage first. Yes, the asterisk is just there. We keep it. ๐Ÿ’ซ
  • vbat2ri_charging_size โ€” the number of items in the vbat2ri_charging table. Final count for this trio. ๐ŸŽฏ
  • bti_resistance_ohm โ€” the Battery Type Indicator (BIT) nominal resistance in ohms for this battery, if an identification resistor is mounted between a third battery terminal and ground. This scheme is used by a lot of mobile device batteries. Very "phone battery detective" energy. ๐Ÿ•ต๏ธโ€โ™€๏ธ
  • bti_resistance_tolerance โ€” the tolerance in percent of the BTI resistance. For example, 10 for +/- 10%. If the bti_resistance is set to 7000 and the tolerance is 10%, we will detect a proper battery if the BTI resistance is between 6300 and 7700 Ohm. Math bestie, but make it cute. ๐Ÿง

๐Ÿ’– DESCRIPTION ๐Ÿ’–

Okay so bestie, this is the recommended struct for managing static battery parameters, and it gets populated by power_supply_get_battery_info. Most platform drivers should use these for consistency โ€” it's giving "please keep the vibes aligned" energy. โœจ

Its field names must correspond to elements in enum power_supply_property. The default field value is -EINVAL or NULL for pointers. No cap.

โšก CC/CV CHARGING โšก

The charging parameters here assume a CC/CV charging scheme. This method is most common with Lithium Ion batteries (other methods are possible), and it looks like this:

       ^ Battery voltage |                                               ---
       overvoltage_limit_uv | |
       ...................................................  |
       .. constant_charge_voltage_max_uv |              ..  |             .  |
       .  |           .  |          .  |         .  |     ..
       precharge_voltage_max_uv |  ..  |. (trickle charging)
       +------------------------------------------------------------------>
       time
       ^ Current into the battery | |      .............
       constant_charge_current_max_ua |      .            .  |      .
       .  |      .              .  |      .               .  |      .
       ..  |      .                  ....  |      .                       .....
       |    ... precharge_current_ua       .......  charge_term_current_ua |
       .                                    .  |    .
       .  |.... tricklecharge_current_ua            .  |
       .  +----------------------------------------------------------------->
       time

These diagrams are synchronized on time, and the voltage and current follow each other. ๐Ÿซถ

With CC/CV charging, things commence over time like this for an empty battery:

  1. When the battery is completely empty, it may need to be charged with an especially small current so that electrons just "trickle in" โ€” this is the tricklecharge_current_ua.
  2. Next, a small initial pre-charge current (precharge_current_ua) is applied if the voltage is below precharge_voltage_max_uv until we reach precharge_voltage_max_uv. CAUTION: in some texts this is referred to as "trickle charging", but the use in the Linux kernel is different โ€” see below!
  3. Then the main charging current is applied, which is called the constant current (CC) phase. A current regulator is set up to allow constant_charge_current_max_ua of current to flow into the battery. The chemical reaction in the battery will make the voltage go up as charge goes into the battery. This current is applied until we reach the constant_charge_voltage_max_uv voltage.
  4. At this voltage we switch over to the constant voltage (CV) phase. This means we allow current to go into the battery, but we keep the voltage fixed. This current will continue to charge the battery while keeping the voltage the same. A chemical reaction in the battery goes on storing energy without affecting the voltage. Over time the current will slowly drop, and when we reach charge_term_current_ua we will end the constant voltage phase.

After this, the battery is fully charged, and if we do not support maintenance charging, the charging will not restart until power dissipation makes the voltage fall so that we reach charge_restart_voltage_uv โ€” at this point we restart charging at the appropriate phase, usually this will be inside the CV phase.

If we support maintenance charging, the voltage is however kept high after the CV phase with a very low current. This is meant to let the same charge go in for usage while the charger is still connected, mainly for dissipation for the power consuming entity while connected to the charger.

All charging MUST terminate if the overvoltage_limit_uv is ever reached. Overcharging Lithium Ion cells can be DANGEROUS and lead to fire or explosions. ๐Ÿ˜ญ๐Ÿ”ฅ

๐Ÿ”‹ DETERMINING BATTERY CAPACITY ๐Ÿ”‹

Several members of the struct deal with trying to determine the remaining capacity in the battery, usually as a percentage of charge. In practice many chargers use a so-called fuel gauge or coloumb counter that measures how much charge goes into the battery and how much goes out (+/- leak consumption). This does not help if we do not know how much capacity the battery has to begin with, such as when it is first used or was taken out and charged in a separate charger. Therefore many capacity algorithms use the open circuit voltage with a look-up table to determine the rough capacity of the battery. The open circuit voltage can be conceptualized with an ideal voltage source (V) in series with an internal resistance (Ri) like this:

       +-------> IBAT >----------------+ |                    ^          | [ ]
       Ri                |          | |                    | VBAT     | o
       <----------        |          | +|           ^        |         [ ]
       Rload .---.         |        |          | | V |         | OCV    |
       | |           |        |          | GND
       +-------------------------------+

If we disconnect the load (here simplified as a fixed resistance Rload) and measure VBAT with a infinite impedance voltage meter, we will get VBAT = OCV, and this assumption is sometimes made even under load, assuming Rload is insignificant. However this will be of dubious quality because the load is rarely that small and Ri is strongly nonlinear depending on temperature and how much capacity is left in the battery due to the chemistry involved.

In many practical applications we cannot just disconnect the battery from the load, so instead we often try to measure the instantaneous IBAT (the current out from the battery), estimate the Ri and thus calculate the voltage drop over Ri and compensate like this:

OCV = VBAT - (IBAT * Ri)

The tables vbat2ri_discharging and vbat2ri_charging are used to determine (by interpolation) the Ri from the VBAT under load. These curves are highly nonlinear and may need many datapoints but can be found in datasheets for some batteries. This gives the compensated open circuit voltage (OCV) for the battery even under load. Using this method will also compensate for temperature changes in the environment: this will also make the internal resistance change, and it will affect the VBAT under load, so correlating VBAT to Ri takes both remaining capacity and temperature into consideration.

Alternatively a manufacturer can specify how the capacity of the battery is dependent on the battery temperature, which is the main factor affecting Ri. As we know, all chemical reactions are faster when it is warm and slower when it is cold. You can put in 1500mAh and only get 800mAh out before the voltage drops too low, for example. This effect is also highly nonlinear, and the purpose of the table resist_table: this will take a temperature and tell us how big percentage of Ri the specified temperature correlates to. Usually we have 100% of the factory_internal_resistance_uohm at 25 degrees Celsius.

The power supply class itself doesn't use this struct as of now.


๐ŸŒˆ SEE ALSO ๐ŸŒˆ

  • Kernel file ./include/linux/power_supply.h struct power_supply_maintenance_charge_table(9)

Footer check, bestie: source/version vibes are ./include/linux, dated October 2026, and it's the struct power...battery_info(9) manual page โ€” mwah! ๐Ÿ’…๐Ÿ’–๐ŸŽ€

๐Ÿ“ฆ where this page comes from