Teclas de atalho baseadas em WMI ao não funcionar

5

No meu Dell latitude e6540 , as teclas de atalho do WMI Fn + Acima e Fn + Abaixo não estão funcionando . Eu tenho todos os módulos necessários compilados no meu kernel:

CONFIG_DELL_LAPTOP=m
CONFIG_DELL_WMI=m
CONFIG_DELL_WMI_AIO=m

No modelo predecessor (Latitude e6520), tudo funcionou bem, sem necessidade de configuração adicional. Eu estou usando o mesmo (custom build) kernel 3.16.6 em ambos os laptops. Em e6520 wmi funciona, em e6540 isso não acontece.

Ainda posso alterar o brilho com echo :

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

mas apenas como root , obviamente.

Pressionar Fn + Acima e Fn + Abaixo não altera o resultado em /sys/class/backlight/acpi_video0/brightness . No modelo anterior, ele altera o valor.

Uma coisa que notei, no modelo mais antigo, o valor máximo é 15 . No novo modelo, é 95 . Parece que algo pode ter mudado dentro desse mecanismo.

Assim, minha pergunta: Como posso fazer as teclas de atalho do WMI funcionarem no meu novo laptop?

Estou usando o wheezy do Debian com o kernel personalizado 3.16.6. Eu também tentei o kernel de distribuição 3.16 (linux-image-3.16-0.bpo.2-amd64 do Wheezy-backports) e as chaves wmi também não funcionam.

UPDATE:

Acabei de notar que as teclas de atalho do WMI funcionam bem quando estou na BIOS !!! Isso é surpreendente que eles não funcionem quando eu inicializo no linux.

a seguir é a saída do dmesg. A menção de dell_wmi: Received unknown WMI event parece relevante para o meu problema, mas recebo as mesmas mensagens no laptop antigo, onde as teclas de atalho wmi estão funcionando. Então, isso sozinho não parece ser o problema.

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

após o patch do módulo WMI, recebo as seguintes mensagens para Fn + Acima e Fn + Abaixo

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

Também é interessante que o laptop veio com o Ubuntu 12.04 pré-instalado e as chaves wmi estão funcionando no Ubuntu.

    
por Martin Vegter 15.04.2014 / 20:07

2 respostas

3

Você pode instalar o xbacklight , um utilitário para gerenciar o brilho usando RandR . Então, para ativá-lo, use um script simples ao longo destas linhas - ligado às suas duas chaves:

#!/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

Troque seu método de notificação por qualquer coisa que você use como parte de sua configuração normal, por exemplo, notify-send .

    
por 15.04.2014 / 20:23
5

Esta postagem descreve como abordo a depuração da WMI com base no DSDT do seu acpidump (o SSDT não contém detalhes relevantes aqui).

\_SB.AMW0 é o dispositivo WMI no firmware do ACPI da Dell. O método \EV4 chama \WMNF , que é o único método que chama o dispositivo \_SB.AMW0 (função SWEV = Set? Evento WMI). \EV4 é o método que é chamado pelo controlador incorporado / teclado.

Agora, SWEV é Definir Evento WMI, CMEV é provável Limpar Evento WMI. Ao chamar SWEV , os bits na variável WMEV ("Evento WMI"?) São definidos. O WMI verifica os códigos de evento chamando o método _WED e verificando seu valor de retorno. Neste método _WED , é realmente visível que WMEV está marcado e CMEV é chamado:

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 */
}

Observe, no entanto, que há duas condições que podem impedir que um código de evento seja retornado (não aplicável aqui):

  • Se Arg0 (o ID de notificação) não for 0xD0. Este não é o caso, como pode ser visto nesta interpretação da descrição do WMI:

    9DBB5994-A997-11DA-B012-B622A1EF5492:
        object_id: � [D0 00]
        notify_id: D0
        reserved: 00
        instance_count: 1
        flags: 0x8 ACPI_WMI_EVENT 
    
  • Se \_SB.AMW0.ECD0 for igual a 0 . Como o código do Dell WMI escuta eventos WMI, o WED0 (evento% WMID0) foi chamado com um argumento diferente de zero e isso também não é válido.

Então, vamos continuar com a interpretação de _WED . O valor de retorno agora depende do valor de WMEV . WVPT define a palavra de 16 bits no buffer retornado WMBU (e avança o ponteiro para a próxima chamada WVPT ). Podemos construir a seguinte tabela:

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)

Agora, o código dell-wmi espera que a segunda palavra seja 0x0010 , não 0x0000 . Para depurar ainda mais isso, você deve ativar a opção debug_event para o módulo WMI

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

Agora pressione as teclas de atalho e observe seus registros do kernel. Você precisa descobrir qual é o formato exato de WMBU , eu acho que você obtém as chaves mais interessantes para o WMEV 0x0800, você precisa dar uma olhada nisso. Talvez adicione isso a dell_wmi_notify (após u16 *buffer_entry = (u16 *)obj->buffer.pointer; ) para depuração:

pr_info("WMBU = %04x %04x %04x\n", buffer_entry[0], buffer_entry[1], buffer_entry[2]);
    
por 18.04.2014 / 18:14