web-dev-qa-db-ja.com

WMIベースのホットキーが機能しない

私のDell latitude e6540では、WMIホットキー Fn+Up そして Fn+Down 動作していません。必要なすべてのモジュールをカーネルにコンパイルしました。

CONFIG_Dell_LAPTOP=m
CONFIG_Dell_WMI=m
CONFIG_Dell_WMI_AIO=m

以前のモデル(Latitude e6520)では、追加のセットアップを必要とせずに、すべて正常に動作しました。両方のラップトップで同じ(カスタムビルド)カーネル3.16.6を使用しています。 e6520ではwmiが機能しますが、e6540では機能しません。

echoで明るさを変更できます:

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

しかし、明らかにrootとしてのみです。

押す Fn+Up そして Fn+Down/sys/class/backlight/acpi_video0/brightnessの値を変更しません。以前のモデルでは、値が変更されます。

古いモデルでは、最大値は15です。新しいモデルでは、95です。このメカニズムの内部で何かが変更された可能性があります。

したがって、私の質問:新しいラップトップでWMIホットキーを機能させるにはどうすればよいですか?

カスタムカーネル3.16.6でDebianwheezyを使用しています。ディストリビューションカーネル3.16(Wheezy-backportsのlinux-image-3.16-0.bpo.2-AMD64)も試しましたが、wmiキーも機能しません。

更新:

BIOSでWMIホットキーが正常に機能することに気づきました!!!私がLinuxを起動したときにそれらが機能しないことは、かなり驚くべきことです。

以下はdmesgの出力です。 Dell_wmi: Received unknown WMI eventについての言及は私の問題に関連しているようですが、古いラップトップでも同じメッセージが表示され、wmiホットキーが機能しています。したがって、これだけでは問題とは見なされません。

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

wMIモジュールにパッチを適用した後、次のメッセージが表示されます。 Fn+Up そして 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

また、ラップトップにはUbuntu 12.04がプリインストールされており、wmiキーはUbuntuで機能していることも興味深い点です。

5
Martin Vegter

RandR を使用して明るさを管理するユーティリティ xbacklight をインストールできます。次に、それをアクティブにするには、2つのキーにバインドされたこれらの行に沿って単純なスクリプトを使用します。

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

通知方法を、通常の設定の一部として使用するものと交換します。例:notify-send

3
jasonwryan

この投稿では、acpidumpからのDSDTに基づいてWMIデバッグにアプローチする方法について説明します(SSDTには関連する詳細はここには含まれていません)。

_\_SB.AMW0_は、Dell ACPIファームウェアのWMIデバイスです。 _\EV4_メソッドは_\WMNF_を呼び出します。これは、_\_SB.AMW0_デバイスを呼び出す唯一のメソッドです(関数SWEV = Set?WMIイベント)。 _\EV4_は、組み込み/キーボードコントローラーによって呼び出されるメソッドです。

現在、SWEVはSetWMIイベントであり、CMEVはClearWMIイベントである可能性があります。 SWEVを呼び出すと、WMEV変数のビット(「WMIイベント」?)が設定されます。 WMIは、__WED_メソッドを呼び出してその戻り値を確認することにより、イベントコードを確認します。この__WED_メソッドでは、確かにWMEVがチェックされ、CMEVが呼び出されることがわかります。

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

ただし、イベントコードが返されない場合がある2つの条件があります(ただし、ここでは適用されません)。

  • Arg0(通知ID)が0xD0でない場合。これは、WMIの説明のこの解釈に見られるように当てはまりません。

    _9DBB5994-A997-11DA-B012-B622A1EF5492:
        object_id: � [D0 00]
        notify_id: D0
        reserved: 00
        instance_count: 1
        flags: 0x8 ACPI_WMI_EVENT 
    _
  • _\_SB.AMW0.ECD0_が_0_と等しい場合。 Dell WMIコードがWMIイベントをリッスンするときに、_WED0_(WMIイベント_D0_)がゼロ以外の引数で呼び出されましたが、これも当てはまりません。

それでは、__WED_の解釈を続けましょう。戻り値は、WMEVの値に依存するようになりました。 WVPTは、返されたバッファWMBUに16ビットワードを設定します(そして、次のWVPT呼び出しのポインタを進めます)。次のテーブルを作成できます。

_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)
_

現在、Dell-wmiコードは、2番目の単語が_0x0010_ではなく_0x0000_であることを想定しています。これをさらにデバッグするには、WMIモジュールの_debug_event_オプションを有効にする必要があります

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

ホットキーを押して、カーネルログを確認します。 WMBUの正確な形式を確認する必要があります。これは、WMEV 0x0800の最も興味深いキーを取得していると思いますが、それを詳しく調べる必要があります。おそらくこれを_Dell_wmi_notify_(u16 *buffer_entry = (u16 *)obj->buffer.pointer;の後)に追加してデバッグします。

_pr_info("WMBU = %04x %04x %04x\n", buffer_entry[0], buffer_entry[1], buffer_entry[2]);
_
5
Lekensteyn