You are not logged in.

#1 2019-09-16 16:05:39

ventto
Member
Registered: 2016-10-26
Posts: 5

XPS13 9370: No udev event when battery discharging

Hey,

Host: Dell XPS 13 9370
Kernel: 5.2.11
WM: Sway

These are my current udev rules:

ACTION=="change", KERNEL=="BAT0", \
SUBSYSTEM=="power_supply", \
ATTR{status}=="Discharging", \
IMPORT{program}="/usr/bin/xpub", \
RUN+="/bin/su $env{XUSER} -c 'notify-send -u critical Discharging:$attr{capacity}%'"

SUBSYSTEM=="power_supply", ACTION=="change", \
ENV{POWER_SUPPLY_ONLINE}=="0", ENV{POWER}="off", \
OPTIONS+="last_rule", \
IMPORT{program}="/usr/bin/xpub", \
RUN+="/bin/su $env{XUSER} -c 'notify-send -u low UnPlugged'"

SUBSYSTEM=="power_supply", ACTION=="change", \
ENV{POWER_SUPPLY_ONLINE}=="0", ENV{POWER}="on", \
OPTIONS+="last_rule", \
IMPORT{program}="/usr/bin/xpub", \
RUN+="/bin/su $env{XUSER} -c 'notify-send -u low Plugged'"

For monitoring the udev events, I am using the following command:

$ udevadm monitor --subsystem-match=power_supply

I test that my rules work with the following commads:

# udevadm control --reload
# udevadm trigger --subsystem-match=power_supply --action=change

Issue:

  • Nothing is reported by the udevadm monitor command when my battery level is decreasing while the power cable is unplugged-in, the first rule should be raised

  • Plug/unplug the power cable raises three udev events (plug event, unplug event, battery level event)

When I trigger manually the rules, the battery level event is raised and I get the following event information:

UDEV  [2937.947715] change   /devices/LNXSYSTM:00/LNXSYBUS:00/PNP0C0A:00/power_supply/BAT0 (power_supply)
ACTION=change
DEVPATH=/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0C0A:00/power_supply/BAT0
SUBSYSTEM=power_supply
SYNTH_UUID=0
POWER_SUPPLY_NAME=BAT0
POWER_SUPPLY_STATUS=Discharging
POWER_SUPPLY_PRESENT=1
POWER_SUPPLY_TECHNOLOGY=Li-ion
POWER_SUPPLY_CYCLE_COUNT=0
POWER_SUPPLY_VOLTAGE_MIN_DESIGN=7600000
POWER_SUPPLY_VOLTAGE_NOW=7310000
POWER_SUPPLY_CURRENT_NOW=704000
POWER_SUPPLY_CHARGE_FULL_DESIGN=6842000
POWER_SUPPLY_CHARGE_FULL=6496000
POWER_SUPPLY_CHARGE_NOW=364000
POWER_SUPPLY_CAPACITY=5
POWER_SUPPLY_CAPACITY_LEVEL=Normal
POWER_SUPPLY_MODEL_NAME=DELL H754V8C
POWER_SUPPLY_MANUFACTURER=LGC-LGC6.73
POWER_SUPPLY_SERIAL_NUMBER=201
SEQNUM=3459
USEC_INITIALIZED=965072411
TTY=tty1
XUSER=myuser
DISPLAY=:0
DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1000/bus

I came across different topics that recommend to fix the ACPI's DSDT, checking the kernel logs and so on.

This is the BAT0's device node in the DSDT:

        [...]
            Device (BAT0)
            {
                Name (_HID, EisaId ("PNP0C0A") /* Control Method Battery */)  // _HID: Hardware ID
                Name (_UID, One)  // _UID: Unique ID
                Name (_PCL, Package (0x01)  // _PCL: Power Consumer List
                {
                    _SB
                })
                Method (_STA, 0, NotSerialized)  // _STA: Status
                {
                    Local0 = ECG5 ()
                    Local0 &= 0x02
                    If (Local0)
                    {
                        Return (0x1F)
                    }

                    Return (0x0F)
                }

                Method (_BIF, 0, NotSerialized)  // _BIF: Battery Information
                {
                    Name (BIF0, Package (0x0D){})
                    ECG9 (One, BIF0)
                    Return (BIF0) /* \_SB_.BAT0._BIF.BIF0 */
                }

                Method (_BST, 0, NotSerialized)  // _BST: Battery Status
                {
                    Name (BST0, Package (0x04){})
                    ECG6 (One, BST0)
                    Return (BST0) /* \_SB_.BAT0._BST.BST0 */
                }
            }
        [...]

Curiously the AC's device node in DSDT seems to refer two batteries:

        [...]
            Device (AC)
            {
                Name (_HID, "ACPI0003" /* Power Source Device */)  // _HID: Hardware ID
                Method (_PCL, 0, NotSerialized)  // _PCL: Power Consumer List
                {
                    Return (Package (0x03)
                    {
                        _SB, 
                        BAT0, 
                        BAT1
                    })
                }
        [...]

Any lead ?

Thanks for your time.

Last edited by ventto (2019-09-16 16:14:00)

Offline

#2 2019-09-16 16:53:05

Swiggles
Member
Registered: 2014-08-02
Posts: 266

Re: XPS13 9370: No udev event when battery discharging

First of all please look whether or not the event is sent by ACPI:

acpi_listen

If it is missing the problem is the table, otherwise check if it is recognized and handled by the kernel.
Also it is always a good idea to look at the whole udev output, so remove the filter and see what you can find there.

Besides this I am not really qualified to comprehensively answer your question, this is just what my exploration steps were for another device of mine.
Make sure to share the actual DSDT file, due to their structure smaller code snippets could be misleading.

Offline

#3 2019-09-17 11:54:08

ventto
Member
Registered: 2016-10-26
Posts: 5

Re: XPS13 9370: No udev event when battery discharging

I have already tested udevadm monitor without any argument but still nothing to report.

This is the output of the acpi_listen command (which corresponds with the udev events raised) when I plug and unplug in the power cable:

ac_adapter ACPI0003:00 00000080 00000001
battery PNP0C0A:00 00000080 00000001
processor LNXCPU:00 00000081 00000000
processor LNXCPU:01 00000081 00000000
processor LNXCPU:02 00000081 00000000
processor LNXCPU:03 00000081 00000000
processor LNXCPU:04 00000081 00000000
processor LNXCPU:05 00000081 00000000
processor LNXCPU:06 00000081 00000000
processor LNXCPU:07 00000081 00000000
ac_adapter ACPI0003:00 00000080 00000000
battery PNP0C0A:00 00000080 00000001
processor LNXCPU:00 00000081 00000000
processor LNXCPU:01 00000081 00000000
processor LNXCPU:02 00000081 00000000
processor LNXCPU:03 00000081 00000000
processor LNXCPU:04 00000081 00000000
processor LNXCPU:05 00000081 00000000
processor LNXCPU:06 00000081 00000000
processor LNXCPU:07 00000081 00000000

Unfortunately, when the battery is discharging, there is no activity on the outpout.

Here is my DSDT: https://gofile.io/?c=54T8In

Thanks for your time.

Last edited by ventto (2019-09-17 11:55:11)

Offline

#4 2019-09-17 17:13:10

Swiggles
Member
Registered: 2014-08-02
Posts: 266

Re: XPS13 9370: No udev event when battery discharging

Looks like ECS5 is never called which would set the status (EC16).
Something like this might work:

Method (_PSR, 0, NotSerialized)  // _PSR: Power Source
                {
                    Local0 = ECG5 ()
                    Local0 &= One
                    If ((Local0 != PWRS))
                    {
                        PWRS = Local0
//Addition below this line
                        If ((PWRS))
                        {
                            ECS5(0x02)
                        }
                        Else
                        {
                            ECS5(0x01)
                        }
//Addition above this line
                        PNOT ()
                    }

                    Return (Local0)
                }

But this means that battery critical is never set either...
Additionally there are some ACPI errors I can't fix, because as I said before I am not too knowledgeable about this. The first line which errors doesn't look like an error to me after you remove the dangling comma.

Is it possible that there is a newer firmware for your machine? Maybe some parts are already fixed.

Offline

#5 2019-09-18 14:34:08

ventto
Member
Registered: 2016-10-26
Posts: 5

Re: XPS13 9370: No udev event when battery discharging

Regarding the output of acpi_listen (in my first post), the following Notify call seems to raise the event that I need:

Notify(BAT0, 0x80)

The only way to raise a battery-status event until now is to plug or unplug in the power cable.
So I've traced back how the Notify(BAT0, 0x80) is called and it seems that the query event 0x66 triggers it:

_Q66() -> if ECRD = One
NEVT() -> if ECG1() & 0x08
PWCH() -> if (ECG5() ^ APRE) & 0x02  AND ((ECG5() & 0x2B) & 0x02) = Zero
EV15(0x02, Zero) ->
Notify(BAT0, 0x80)

(OR)

PWCH() -> if (ECG5() ^ APRE) & 0x04  AND (ECG5() & 0x2B) & 0x02
EV15(0x03, Zero) ->
Notify(BAT0, 0x80)

 

Do you think calling the ECS5() method would raise the event (or would lead to a call to the Notify(BAT0, 0x80)) ?
If it is the case, please how does it work ?

I will read the section-10 "Power Source and Power Meter Devices" of the ACPI specifications, it should help me to understand the mechanism.

Last edited by ventto (2019-09-18 15:07:13)

Offline

#6 2019-09-18 15:06:41

Swiggles
Member
Registered: 2014-08-02
Posts: 266

Re: XPS13 9370: No udev event when battery discharging

Sorry, I can't remember, there are so many layers of functions in between. My comment was related to the state that is never changed and that's the '0x80 0x01' (where 0x01 is "charging") you see in acpi_listen. At least I think so.

But first of all you should try to get it recompiling and then you can play around with the ideas. This is imo the biggest blocking point. I am positive the other issues can be figured out in a few iterations.

Offline

#7 2019-09-18 15:11:56

ventto
Member
Registered: 2016-10-26
Posts: 5

Re: XPS13 9370: No udev event when battery discharging

Effectively, this is what you mean ?

# Plug in 
ac_adapter ACPI0003:00 00000080 00000001
battery    PNP0C0A:00  00000080 00000001       <--- 
                                                  |
# Unplug in                                       |   still 0x01, "charging" ?
ac_adapter ACPI0003:00 00000080 00000000          |
battery    PNP0C0A:00  00000080 00000001       <--- 

Generally speaking, how to read the third and the fourth columns of acpi_listen ?

I've successfully compiled the DSDT table. I've made a tiny fixed following this guide.

Last edited by ventto (2019-09-18 15:16:32)

Offline

#8 2019-09-18 15:35:46

Swiggles
Member
Registered: 2014-08-02
Posts: 266

Re: XPS13 9370: No udev event when battery discharging

I mixed them up 0x02 is charging, 0x01 discharging, 0x04 is critical: https://github.com/torvalds/linux/blob/ … tery.c#L47

Honestly I have never found proper documentation. I guess you have to look into the source code of acpid.

Let's start from the top:
The first column is the kernel driver handling the events. Or rather the name the driver reports to the kernel.

The second column is the device name given by the ACPI table

The third column is the device specific event indicator. I found 0x80 to be used for most general notify events. I think your table defined 0x81 as info etc. It looks like there is some agreement between vendors, but I have not found a reference in the ACPI spec. So I would call it the severity. The line "Notify(BAT0, 0x80)" triggers the line in your log.

The fourth column is the value of the package sent, but as far as I can tell only the first value in the collection. For battery there are 4 values in the package and the kernel driver does map them like this: https://github.com/torvalds/linux/blob/ … ery.c#L376
So basically the four values are in order: state, rate_now, capacity_now, voltage_now

But please take it with a grain of salt. This is what I think it is by exploring a previous machine of mine.

Offline

Board footer

Powered by FluxBB