ASUS BR1100F status LED

BR1100F Laptop status LED on Linux

Status LED

The ASUS Laptop BR1100F has an LED on the top left corner of the outside cover (back) of the screen.

ASUS BR1100F status LED blinking

The ASUS FAQ: POWER & WIFI INDICATOR Introduction describes the LED as indicating three states.

State Description
On Normal operation
Slow blinking Less than 20% battery
Fast blinking Connection issue (WiFi or 4G)

To set the LED the “Asus Business Utility” is required. Linux is not supported by this software and the asus-wmi kernel module also has no entry for this LED.

Adding Linux support

Finding the LED

We get and decompile the DSDT:

sudo cp --no-preserve=mode /sys/firmware/acpi/tables/DSDT .
iasl -d DSDT

Using the resulting DSDT.dsl (BIOS 319) we find required device ID 0x0004001A for the WMI interface (using some guesswork and excluding IDs defined for the Linux kernel module in asus-wmi.h.

The relevant parts of the resulting DSDT.dsl with the ASUS_WMI_METHODID_s identified with the #defines in asus-wmi.h

DefinitionBlock ("", "DSDT", 2, "_ASUS_", "Notebook", 0x01072009)
{
    Scope (_SB.ATKD)
    {
        Method (WMNB, 3, Serialized)
        {
            P8XH (Zero, 0x11)
            CreateDWordField (Arg2, 0x04, IIA1)
            Local0 = (Arg1 & 0xFFFFFFFF)

            If ((Local0 == 0x53545344)) // ASUS_WMI_METHODID_DSTS (see asus-wmi.h)
            {
                If ((IIA0 == 0x0004001A))
                {
                    Local0 = 0x00010000
                    Local0 |= (One & ^^PC00.LPCB.H_EC.TSLN)
                    Return (Local0)
                }
            }

            If ((Local0 == 0x53564544)) // ASUS_WMI_METHODID_DEVS (see asus-wmi.h)
            {
                If ((IIA0 == 0x0004001A))
                {
                    ^^PC00.LPCB.H_EC.TSLN = IIA1 /* \_SB_.ATKD.WMNB.IIA1 */
                    Return (One)
                }
            }
        }
    }
}

Accessing the WMI Interface

Thus we can now use the asus-nb-wmi kernel debug interface to get (dsts) and set (devs) the LED.

 <platform>/    - debugfs root directory
   dev_id      - current dev_id
   ctrl_param  - current ctrl_param
   method_id   - current method_id
   devs        - call DEVS(dev_id, ctrl_param) and print result
   dsts        - call DSTS(dev_id)  and print result
   call        - call method_id(dev_id, ctrl_param) and print result

asus-wmi.c

The following values can be set:

value LED state
0 off
1 on
2 slow blinking (period: ~2s)
3 fast blinking (period: ~1s)

Limitations

Reading the value we unfortunately only get 0 for state off and 1 for on or blinking.

Furthermore if the battery is below 20% and the state is not off, the LED will blink slowly regardless of the state we have set.

This matches the description in the Manual (p. 20) where “slow blinking” can be both “Low battery (less than 20%)” and “Low battery (less than 20%) and connection issue”.

Thus the LED cannot be used for an other function. It might be possible to get better access using the embedded controller directly for TSLN (using acpi_ec or writing a kernel module).

Script cover_led.sh

The script below can be used to get:

$ sudo ./cover_led.sh
Cover LED state: enabled

and set the LED state

sudo ./cover_led.sh on
#!/usr/bin/sh

set -eu

print_usage() {
    echo "usage: $0 [-h] [off|on|slow|fast]"
    echo "Get or set the cover status LED of a ASUS BR1100F"
}

DEV_ID=0x0004001A
WMI_PATH=/sys/kernel/debug/asus-nb-wmi

set_dev_id() {
    echo "$DEV_ID" > "$WMI_PATH/dev_id" || exit 1
}

# can only check if enabled;
# 'enabled' includes both solid on and blinking
get_value() {
    set_dev_id
    if ! VALUE=$(cat "${WMI_PATH}/dsts"); then
        exit 1
    fi

    return "$(echo "$VALUE" | rev | cut -c 1)"
}

set_value() {
    set_dev_id
    echo "$1" > "${WMI_PATH}/ctrl_param"
    cat "${WMI_PATH}/devs" > /dev/null
}

if test $# -gt 1; then
    print_usage
    exit 1
fi

if test $# -eq 0; then
    echo -n "Cover LED state: "
    if get_value; then
        echo "off"
    else
        echo "enabled"
    fi
    exit 0
fi

case $1 in
    -h | --help)
        print_usage
        ;;

    off)
        set_value 0
        ;;
    on)
        set_value 1
        ;;
    slow)
        set_value 2
        ;;
    fast)
        set_value 3
        ;;
esac