5

On my Dell latitude e6540, the WMI hotkeys Fn+Up and Fn+Down are not working. I have all necesary modules compiled in my kernel:

CONFIG_DELL_LAPTOP=m
CONFIG_DELL_WMI=m
CONFIG_DELL_WMI_AIO=m

On the predecessor model (Latitude e6520), all worked fine, without any need for additional setup. I am using the same (custom build) kernel 3.16.6 on both laptops. On e6520 wmi works, on e6540 it doesn't.

I can still change the brightness with echo:

echo 35 > /sys/class/backlight/acpi_video0/brightness

but only as root, obviously.

Pressing Fn+Up and Fn+Down does not change the walue in /sys/class/backlight/acpi_video0/brightness. On the previous model, it does change the value.

One thing I noticed, on the older model, the max value is 15. On the new model it is 95. Looks like something might have changed inside this mechanism.

Thus my question: How can I make WMI hotkeys work on my new laptop?

I am using Debian wheezy with custom kernel 3.16.6. I have also tried distribution kernel 3.16 (linux-image-3.16-0.bpo.2-amd64 from Wheezy-backports) and the wmi keys don't work either.

UPDATE:

I have just noticed that the WMI hotkeys work fine when I am in BIOS !!! That is quite surprising that they don't work when I boot into linux.

following is output of dmesg. The mention of dell_wmi: Received unknown WMI event looks relevant to my problem, but I get the same messages on the old laptop, where wmi hotkeys are working. So this alone does not seeem the be the issue.

dmesg | egrep -i '(dell|wmi)'
[Tue Apr 15 22:04:30 2014] DMI: Dell Inc. Latitude E6540/05V0V4, BIOS A05 09/03/2013
[Tue Apr 15 22:04:30 2014] ACPI: RSDP 00000000000eee60 00024 (v02 DELL  )
[Tue Apr 15 22:04:30 2014] ACPI: XSDT 00000000d8fe0080 0007C (v01 DELL    CBX3    01072009 AMI  00010013)
[Tue Apr 15 22:04:30 2014] ACPI: FACP 00000000d8fed7e8 0010C (v05 DELL    CBX3    01072009 AMI  00010013)
[Tue Apr 15 22:04:30 2014] ACPI: DSDT 00000000d8fe0188 0D659 (v02 DELL    CBX3    00000014 INTL 20091112)
[Tue Apr 15 22:04:30 2014] ACPI: APIC 00000000d8fed8f8 00072 (v03 DELL    CBX3    01072009 AMI  00010013)
[Tue Apr 15 22:04:30 2014] ACPI: FPDT 00000000d8fed970 00044 (v01 DELL    CBX3    01072009 AMI  00010013)
[Tue Apr 15 22:04:30 2014] ACPI: HPET 00000000d8feed38 00038 (v01 DELL    CBX3    01072009 AMI. 00000005)
[Tue Apr 15 22:04:30 2014] ACPI: MCFG 00000000d8fef148 0003C (v01 DELL    CBX3    01072009 MSFT 00000097)
[Tue Apr 15 22:04:38 2014] dcdbas dcdbas: Dell Systems Management Base Driver (version 5.6.0-3.2)
[Tue Apr 15 22:04:39 2014] wmi: Mapper loaded
[Tue Apr 15 22:04:39 2014] input: Dell WMI hotkeys as /devices/virtual/input/input10
[Wed Apr 16 18:30:04 2014] dell_wmi: Received unknown WMI event (0x0)
[Fri Apr 18 17:09:41 2014] dell_wmi: Received unknown WMI event (0x0)
[Fri Apr 18 17:09:41 2014] dell_wmi: Received unknown WMI event (0x0)
[Fri Apr 18 17:09:49 2014] dell_wmi: Received unknown WMI event (0x0)

UPDATE2

after patching the WMI module, I get following messages for Fn+Up and Fn+Down

2014-04-18 19:00:49  kernel: [  120.731480] dell_wmi: WMBU = 0002 0010 0048
2014-04-18 19:00:49  kernel: [  120.731496] wmi: DEBUG Event GUID: 9DBB5994-A997-11DA-B012-B622A1EF5492

2014-04-18 19:00:53  kernel: [  123.935400] dell_wmi: WMBU = 0002 0010 0050
2014-04-18 19:00:53  kernel: [  123.935415] wmi: DEBUG Event GUID: 9DBB5994-A997-11DA-B012-B622A1EF5492

UPDATE3

Also interesting is, that the laptop came with pre-installed Ubuntu 12.04, and the wmi keys are working in Ubuntu.

8
  • Martin, could you post the output of sudo acpidump > acpidump.txt on gist.github.com? It shouldn't be a big suprise that WMI hotkeys work in BIOS but not in Linux, there are several variables that control this behavior.
    – Lekensteyn
    Apr 18, 2014 at 13:08
  • @Lekensteyn - on my system, the output of acpidump is binary. I have to extract the tables first with acpixtract -a acpidump.out and then I can convert the tables with iasl -d. Which table contains the relevant information ? I have these: APIC.dat ASF!.dat DSDT.dat FACP.dat FACS.dat FPDT.dat HPET.dat MCFG.dat RSDP.dat SSDT1.dat SSDT2.dat SSDT3.dat SSDT4.dat SSDT5.dat XSDT.dat Apr 18, 2014 at 13:51
  • acpidump.txt should contain hexdumps that can be extracted with acpixtract. The DSDT and SSDT tables are relevant, but it is easier to check if you can post the acpidump completely (or post the DSDT and SSDT* dat (or dsl) files to gist.github.com such that it can be cloned).
    – Lekensteyn
    Apr 18, 2014 at 14:03
  • @Lekensteyn - OK, here it is: https://gist.github.com/anonymous/11046257 Apr 18, 2014 at 14:13
  • Can you also post a dmesg containing logs from the boot, and when you press hotkeys? Perhaps it gives me some hints that speed up debugging
    – Lekensteyn
    Apr 18, 2014 at 15:05

2 Answers 2

6
+125

This post describes how I approach WMI debugging based on the DSDT from your acpidump (SSDT does not contain relevant details here).

\_SB.AMW0 is the WMI device in your Dell ACPI firmware. The \EV4 method calls \WMNF which is the only method that calls on the \_SB.AMW0 device (function SWEV = Set? WMI Event). \EV4 is the method that is called by the embedded/keyboard controller.

Now, SWEV is Set WMI Event, CMEV is likely Clear WMI Event. Upon calling SWEV, the bits in the WMEV variable ("WMI Event"?) are set. WMI checks for event codes by calling the _WED method and checking its return value. In this _WED method, it is indeed visible that WMEV is checked and CMEV gets called:

Method (_WED, 1, NotSerialized)  // _Wxx: Wake Event
{
    WVSP ()
    If (LNotEqual (Arg0, 0xD0))
    {
        WVCU ()
        Return (WMBU) /* \_SB_.AMW0.WMBU */
    }

    If (LEqual (ECD0, Zero))
    {
        WVCU ()
        Return (WMBU) /* \_SB_.AMW0.WMBU */
    }

    If (And (WMEV, 0x0200))
    {
        CWEV (0x0200)
        // WMBU = { 0x0002, 0x0000, 0xE045 }
        WVPT (0x02)
        WVPT (Zero)
        WVPT (0xE045)
    }
    Else
    {
        If (And (WMEV, 0x0100))
        {
            CWEV (0x0100)
            If (ECG4 ())
            {
                WVPT (0x02)
                WVPT (Zero)
                WVPT (0xE043)
            }
            Else
            {
                WVPT (0x02)
                WVPT (Zero)
                WVPT (0xE044)
            }
        }
        Else
        {
            If (And (WMEV, 0x0800))
            {
                Store (EC0A (WMBU), WMBU) /* \_SB_.AMW0.WMBU */
                CWEV (0x0800)
            }
        }
    }

    WVCU ()
    Return (WMBU) /* \_SB_.AMW0.WMBU */
}

Note, however, there are two conditions that may prevent an event code from being returned (not applicable here though):

  • If Arg0 (the notification ID) is not 0xD0. This is not the case as can be seen in this interpretation of the WMI description:

    9DBB5994-A997-11DA-B012-B622A1EF5492:
        object_id: � [D0 00]
        notify_id: D0
        reserved: 00
        instance_count: 1
        flags: 0x8 ACPI_WMI_EVENT 
    
  • If \_SB.AMW0.ECD0 is equal to 0. As the Dell WMI code listens for WMI events, the WED0 (WMI Event D0) got called with a non-zero argument and this also doesn't hold.

So, let's continue with the interpretation of _WED. The return value now depends on the value of WMEV. WVPT sets the 16-bit word in the returned buffer WMBU (and advanced the pointer for the next WVPT call). We can build the following table:

WMEV                returned WMBU   guessed key (see dell-wmi)
0200                0002 0000 E045  KEY_PROG1 or NumLock
0100 (ECG4())       0002 0000 E043  ??
0100 (not ECG4())   0002 0000 E044  ??
0800                ?? (value depends on EC registers)

Now, the dell-wmi code expects the second word to be 0x0010, not 0x0000. In order to further debug this, you should enable the debug_event option for the WMI module

# remove all dependencies of WMI and WMI itself:
modprobe -vr dell-wmi
modprobe wmi debug_event
modprobe dell-wmi

Now press hot keys and watch your kernel logs. You need to find out what the exact format is of WMBU, I guess that you get most interesting keys for WMEV 0x0800, you need to take a closer look on that. Perhaps add this to dell_wmi_notify (after u16 *buffer_entry = (u16 *)obj->buffer.pointer;) for debugging:

pr_info("WMBU = %04x %04x %04x\n", buffer_entry[0], buffer_entry[1], buffer_entry[2]);
8
  • I have enabled debug_event and watching the kernel logs I see the following message when I press wmi hotkey: 2014-04-18 18:28:20 kernel: [246284.273164] wmi: DEBUG Event GUID: 9DBB5994-A997-11DA-B012-B622A1EF5492 Apr 18, 2014 at 16:33
  • Yeah, I was already afraid that you only get those messages. Are you able to patch the WMI module as I said? You do not need to rebuild the whole kernel, it is sufficient to build with make -C /lib/modules/$(uname -r)/build M=drivers/platform/x86/ modules and insmod drivers/platform/x86/dell-wmi.ko after patching.
    – Lekensteyn
    Apr 18, 2014 at 16:39
  • please see my update2 Apr 18, 2014 at 17:05
  • Can you edit dell_wmi_prepare_new_keymap and add the following at the end of the loop body: pr_info("%i %08x %04x\n", keymap[i].type, keymap[i].code, keymap[i].keycode);.
    – Lekensteyn
    Apr 18, 2014 at 17:16
  • done, but I don't see any difference Apr 18, 2014 at 17:40
3

You could install xbacklight, a utility for managing your brightness using RandR. Then, to activate it, use a simple script along these lines—bound to your two keys:

#!/usr/bin/env bash
up() {
    xbacklight -inc 10
}

down() {
    xbacklight -dec 10
}

notify() {
    bright=$(</sys/class/backlight/acpi_video0/actual_brightness)
    if [[ "$bright" -eq 95 ]]; then
        score="100%"
    else score="$(( $bright * 100 / 95 ))"
    fi
    printf '%s\n' "Backlight set to ${score}%" | dzen2 -p 3
}

if [[ $1 = up ]]; then
    up && notify
elif [[ $1 = down ]]; then
    down && notify
fi

Swap out your notification method for whatever you use as part of your normal setup, eg., notify-send.

6
  • using xbacklight has several problems: first it only works in X, but I am also working in console and I would like to be able to adjust the brightness. Second, when running xbacklight in X, it takes several seconds (3 - 5) to complete and in the meanwhile my mouse cursor moves very slowly/discontinuously. Apr 15, 2014 at 19:14
  • @MartinVegter your question explicitly references xev: it is reasonable to assume that you are referring to X unless otherwise stated: I am not clairvoyant. The lag/mouse thing is also atypical and may or not be related.
    – jasonwryan
    Apr 15, 2014 at 20:47
  • I have removed the reference to xev from my question. Sorry if it was confusing. Apr 15, 2014 at 21:11
  • 1
    @MartinVegter You could try adding one of the kernel lines to your bootloader, like acpi_osi=Linux acpi_backlight=vendor - google your model to see if there is a more specific one.
    – jasonwryan
    Apr 15, 2014 at 22:37
  • when I boot my kernel with acpi_backlight=vendor, the WMI hotkeys do not work and /sys/class/backlight/acpi_video0/ disappears completely from /sys/. Apr 18, 2014 at 13:04

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .