Bug 218343

Summary: discharge rate not reported
Product: ACPI Reporter: Marc Dietrich (marvin24)
Component: Power-BatteryAssignee: acpi_power-battery
Status: RESOLVED INVALID    
Severity: normal    
Priority: P3    
Hardware: All   
OS: Linux   
Kernel Version: Subsystem:
Regression: No Bisected commit-id:
Attachments: dsdt.dsl

Description Marc Dietrich 2024-01-04 15:55:28 UTC
Hi,

I noticed a strange phenomenon while trying to find out the power consumption of my notebook (HP Elitebook 850). While AC plugged in, the charging current is shown in /sys/class/power_class/BAT0/current_now, but when I unplug it, the current rate is unavailable:
/sys/class/power_supply/BAT0# while /bin/true; do cat current_now; sleep 1; done
--- with AC ---
254000
253000
253000
253000
--- unplug AC ---
0
cat: current_now: No such device
cat: current_now: No such device
cat: current_now: No such device
cat: current_now: No such device
cat: current_now: No such device
--- plug AC ---
0
0
0
0
242000
290000
286000
285000
^C

I already "debugged" that in battery.c that for unplugged state the rate returned is indeed "-1", so the output above makes sense. I just wonder if it could report also the (more interesting) discharge current instead of the charging current. Is there some way to better debug this, eg. by manually reading the ACPI tables?
Comment 1 Marc Dietrich 2024-01-05 11:50:40 UTC
Created attachment 305679 [details]
dsdt.dsl
Comment 2 Marc Dietrich 2024-01-05 11:54:02 UTC
I checked the _BST method with acpidbg (not going further) and it seems that it really returns -1:
- Evaluate _SB_.BAT0._BST
Evaluating \_SB_.BAT0._BST
Evaluation of \_SB_.BAT0._BST returned object 0000000035df6af1, external buffer length 78
 [Package] Contains 4 Elements:
  [Integer] = 0000000000000001
  [Integer] = 00000000FFFFFFFF
  [Integer] = 0000000000000DD9
  [Integer] = 0000000000003056

so I guess it's a firmware bug or a feature. The diagnosis of the UEFI Bios however is able to get the current within a few seconds. Maybe there is some proprietary way to get battery current. Closing.
Comment 3 Marc Dietrich 2024-01-05 15:34:39 UTC
I guess this one here is the FW bug (from \_SB_.PCI0.LPCB.EC0_.BTST)

              DerefOf (NBST [Arg0]) [Zero] = Local0 // Battery state
                If ((Local0 & One))   // discharging ?
                {
                    // yes -> range check of current rate (local3)
                    If (((Local3 < 0x0190) || (Local3 > 0x1964)))
                    {
                        // out of range? use old rate
                        Local5 = DerefOf (DerefOf (NBST [Arg0]) [One])
                        // also out of range?
                        If (((Local5 < 0x0190) || (Local5 > 0x1964)))
                        {
                            Local3 = 0x0D7A  // 3450
                        }
                        Else
                        {
                            Local3 = Local5 // old rate
                        }
                    }

                    // ups, now always overwrite current rate with -1 !
                    Local3 = 0xFFFFFFFF  
                }
                ElseIf (((Local0 & 0x02) == Zero))   // not charging?
                {
                    Local3 = Zero
                }

So, I guess clearly a FW bug, a direct call to \_SB_.PCI0.LPCB.EC0_.BPR_ gives the correct current while discharging and charging.