Monday, June 4, 2012

Introduction to ACPI Control Method Battery (2)


Control Method Battery Interface



Figure 1 - An ASL Battery Device
To present a control method battery to an OS, BIOS needs to declare an object in DSDT/SSDT table, and it must be with an _HID "PNP0C0A", as shown in Figure 1.

If more than a battery are needed, each battery can be distinguished by an unique _UID.

In addition to _HID and _UID, a number of ASL objects are also mandatory as below.

_STA: Battery Presence

Figure 3 - _STA Object for a Battery Device
_STA object is used to show the state of a device in a system; however, ACPI battery is special in the sense of device presence.

In ACPI, it is specially noted "Unlike most other devices, when a battery is inserted or removed from the system, the device itself (the battery bay) is still considered to be present in the system." The battery presence is therefore determine as Figure 2, and _STA for a control method battery should be written as the sample in Figure 3.
Figure 2 - _STA Bitmap

_PCL: Power Consumer List

Figure 4 - Sample _PCL Object
_PCL object defines what components are powered by this power source (i.e. this battery). It is not certain who uses this information and how it affects system behaviors, but it may be used to manage more complex systems with multiple power sources and allows runtime replacement. In most of cases, a battery powers every components, and it can be written as Figure 4.

_BIF or _BIX: Battery Information

_BIF passes "static" battery information from a battery pack to an operating system, such as design capacity and last full charged capacity previously discussed (as shown in Figure 5). Please refer to ACPI specification for more details.

Figure 5 - _BIF Data Structure

_BIX is a replacement for _BIF since ACPI 4.0. It includes all data in _BIF plus some additions. However, it would be better to include both _BIF and _BIX in BIOS because many all operating systems support _BIX. Please refer to ACPI Spec 4.0/5.0 for details.

Battery Information Update

BIOS notifies OSPM that battery information changes by issuing Notify (Battery, 0x81). This mostly happens when a battery is inserted or removed. However, this is not 100% sufficient according to my experiences - I think Notify (Battery, 0x81) should be issued whenever any field in _BIF/_BIX change.

If we take a clear look at _BIF and _BIF, it is obvious that most of fiends are very much static, i.e. Power Unit, Design Capacity, Model Name and so on; however, some fields can change without changing a battery, such as Last Full Charge Capacity and Cycle Count. EC should also geneate a SCI to BIOS to Notify (Battery, 0x81) in such scenario. This will keep operating system updated with latest information and prevent some bugs from happening. (Do you know what bugs can happen?)

Getting Battery Information in Linux (Ubuntu 12.04)

To get battery information in Ubuntu 12.04 is very easy and it can be done by two approaches.
  • /proc/acpi/battery/[Battery]/info
On my laptop PC, a simple cat /proc/acpi/battery/BAT0/info returns:
present:                 yes
design capacity:         4313 mAh
last full capacity:      4313 mAh
battery technology:      non-rechargeable
design voltage:          12416 mV
design capacity warning: 432 mAh
design capacity low:     216 mAh
cycle count:   0
capacity granularity 1:  100 mAh
capacity granularity 2:  100 mAh
model number:          
serial number:        
battery type:            LiOn
OEM info:                HP

It should noted that Linux kernel assumed the format of _BIX and it returns 0 for unsupported field if only _BIF is present (i.e. cycle count = 0).
    • /sys/class/power_supply/[Battery]/uevent
    On my laptop PC, a simple cat /sys/class/power_supply/BAT0/uevent returns:
    POWER_SUPPLY_NAME=BAT0
    POWER_SUPPLY_STATUS=Full
    POWER_SUPPLY_PRESENT=1
    POWER_SUPPLY_TECHNOLOGY=Li-ion
    POWER_SUPPLY_CYCLE_COUNT=0
    POWER_SUPPLY_VOLTAGE_MIN_DESIGN=12416000
    POWER_SUPPLY_CHARGE_FULL_DESIGN=4313000
    POWER_SUPPLY_CHARGE_FULL=4313000
    POWER_SUPPLY_CHARGE_NOW=4313000
    POWER_SUPPLY_MODEL_NAME=
    POWER_SUPPLY_MANUFACTURER=HP
    POWER_SUPPLY_SERIAL_NUMBER=

    _BST: Battery State

    _BST passes "dynamic battery information from a battery pack to an operating system, including:
    • Battery State - state of charging/discharging and critical low
    • Battery Present Rate - power or current being supplied or accepted through the battery’s  terminals.
    • Battery Remaining Capacity - the estimated remaining battery capacity
    • Battery Present Voltage - the voltage across the battery’s terminals.

    Battery State Update

    BIOS notifies OSPM that battery information changes by issuing Notify (Battery, 0x80). This can happen during run-time when battery is presented in battery bay. Especially, ACPI defines two scenario that this notification should happen: 1. When battery state of battery changes, and 2. When remaining capacity reaches critical low. Failing to do will not introduce critical bugs (reasonable below) but will decrease responsiveness of battery information to users in some use-cases.

    Operating systems like Windows or Linux periodically poll battery states and there is no need for BIOS/EC to issue Notify (Battery, 0x80) periodically; for example, it is known that Windows 7 polls battery state every 15 seconds. This often surprises BIOS or EC engineers (and I wonder why). Issuing extra Notify (Battery, 0x80) will not prevent any bugs but only waste of CPU cycle (and therefore slightly battery life penalty!).

    Getting Battery State in Linux (Ubuntu 12.04)


    Similarly to Battery Information, two approaches can be applied to get battery state in Linux.
    • /proc/acpi/battery/[Battery]/state
    On my laptop PC, cat /proc/acpi/battery/BAT0/state returns:
    present:                 yes
    capacity state:          ok
    charging state:          charged
    present rate:            unknown
    remaining capacity:      4313 mAh
    present voltage:         unknown
    • /sys/class/power_supply/[Battery]/*
    This is a little different. Each field in _BST is declared as a node (file), and getting battery state is done by cat state_node. I will leave details to you.

    Extra Information

    This article focus on BIOS-OS interfaces and explains little on each field. To understand more on how to get information from a battery pack, extra reading on Smart Battery System Specification is highly recommended; however, this is out-of-scope from BIOS or OS perspectives.

    1 comment:

    1. Hi,

      I have a requirement of interfacing a battery fuel gauge and battery controller via I2C to SoC. i.e there are no embedded controller in between( no smart battery). So ,as per my current understanding, I will have to use ACPI "Control Method Battery Interface" for the same. i.e edit the ACPI table DSDT to add battery related methods. Is this flow correct? Will chaging the ASL code and adding battery related control methods pass all the required information to cmbatt.sys(miniport driver). Do I need to write a mini port driver for this ? Kindly help me out as I am a beginner with windows development. Please do suggest if any alternative solutions are available.

      Regards,
      Parvathi

      ReplyDelete