使用 gpio-keys 中断唤醒 RPi3 上的屏幕

using gpio-keys interrupt to wake up screen on RPi3

我正在尝试使用 gpio-keys 中断在进入睡眠状态后唤醒屏幕。我正在使用 Raspberry Pi 3Lineage OS 14.1。我已经能够成功配置 gpio-keys,它在接收到中断时注册输入设备事件。但是,我无法让它在关闭时唤醒屏幕。我的 gpio-keys 设备的设备树覆盖文件如下:

/dts-v1/;
/plugin/;
/ {
compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709";

fragment@0 {
    // Configure the gpio pin controller
    target = <&gpio>;
    __overlay__ {
        pin_state: key_pins@0 {
            brcm,pins = <17>;       // gpio number
            brcm,function = <0>;    // 0 = input, 1 = output
            brcm,pull = <2>;        // 0 = none, 1 = pull down, 2 = pull up
        };
    };
};      

fragment@1 {    
    target-path = "/";
    __overlay__ {
        keypad: proximity@0 {
            compatible = "gpio-keys";
            #address-cells = <1>;
            #size-cells = <0>;

            key: proximity {
                label = "proximity detection";
                linux,code = <61>;          // F3 Key
                gpios = <&gpio 17 1>;       // GPIO 17
                wakeup-source;
            };
        };
    };
};
};

如您在文件中所见,我添加了 属性 wakeup-source 但我相信它可能会将系统从 CPU 睡眠中唤醒并且在屏幕休眠时不一定是屏幕本身。

如您所见,我的 gpio 键绑定到 KEY F3。如果我按键盘上的 F3,它会唤醒显示器。但是,如果我在 GPIO17 引脚上生成中断,它不会唤醒监视器,即使它注册为 KEY F3 事件。关于如何从 gpio-keys 唤醒显示器有什么建议吗?谢谢!

我认为您正在寻找接近传感器功能。 Linux 已经有 linux,keycode 此功能。

对于接近传感器,您必须在设备树中添加密钥代码 0x0b (11),例如:

 key: proximity {
                label = "proximity detection";
                linux,code = <11>; /* SW_FRONT_PROXIMITY */
            };

以类似的方式,您也可以添加其他功能的关键代码。

所以我终于明白了。我知道这不是最好的方法,我确信这不是唯一的方法,但这就是我最终让屏幕在我的 gpio 收到中断时唤醒的方法。

我使用了键码 143,也称为 KEY_WAKEUP。设备树覆盖片段如下所示:

key: proximity {
            label = "proximity-detection";
            linux,code = <143>;          // KEY_WAKEUP
            gpios = <&gpio 17 0>;       // GPIO 17
            wakeup-source;
        };

我找到了比我之前的答案更好的解决方案。我将之前的答案保留为 post,因为它是一个可行的解决方案(尽管它不是最理想的解决方案)。

无论如何,您要做的就是创建(或修改)一个按键布局文件。对于此 key layout 文件注册到某个设备,key layout 文件名必须遵循与您想要的设备的详细信息相对应的特定命名约定使用(gpio-keys 在我的例子中)。此处有更多详细信息:https://source.android.com/devices/input/key-layout-files。就我而言,我决定让我的 key layout 文件名与设备名称相匹配。在我的案例中,设备名称是 gpio-keys,您在设备树覆盖文件中定义它。如果您可以通过在命令行 cat /proc/bus/input/devices 中键入来访问 Android 本地终端,您还可以找到设备名称。我的 gpio-keys 覆盖文件的片段如下所示:

fragment@1 {    
    target-path = "/";
    __overlay__ {
        keypad: gpio-keys {
            compatible = "gpio-keys";
            #address-cells = <1>;
            #size-cells = <0>;

            key: proximity {
                label = "proximity-detection";
                linux,code = <29>;      // KEY_LEFTCTRL
                linux,input-type = <1>;     // EV_KEY
                gpios = <&gpio 17 0>;       // GPIO 17
                wakeup-source;
            };
        };
    };
};

正如您在上面 keypad: 旁边看到的,设备名称 gpio-keys 已设置。你也可以在这里写其他名字。因此,我将我的按键布局文件命名为gpio-keys.kl。我将 gpio-keys.kl 文件放在 /system/usr/keylayout/ 目录中 Android。 gpio-keys.kl文件如下图:

# Key layout used for gpio-keys

key 29   CTRL_LEFT   WAKE

因为我的 gpio-key (GPIO17) 绑定到 Linux 键码 29KEY_LEFTCTRL,我的按键布局文件关联了 Linux 键码 29(或 KEY_LEFTCTRL) 到相应的 Android 键码 CTRL_LEFT。然后我在同一行上添加术语 WAKE,如上所示。 Linux 键码及其匹配的 Android 键码可在此处找到:https://source.android.com/devices/input/keyboard-devices

这允许我的屏幕在 GPIO17 收到中断时根据需要唤醒。这是一个比 WAKEUP 仅使用 Linux 键码更好的解决方案,因为您可能想编写一个 Android 应用程序,其中有几个不同的 gpio-keys 你想区别对待。如果每个 gpio-key 绑定到不同的键码,您将能够将它们彼此区分开来。如果它们都有相同的键码,我认为区分这些不同的键会更加困难。