我正在为 Linux 中的 Samsung Galaxybook 开发一个新平台驱动程序的雏形,你可以看到这里。我已经成功地调试了 Windows 中的内核,并且能够大致拼凑出 Windows 驱动程序“三星系统事件控制器”在几种情况下的工作方式,而我开始的第一个是键盘背光控制。
Windows 中的驱动程序获取一个 ACPI 设备,然后该设备内有一个通用的“设置”ACPI 方法 (CSFI),驱动程序将各种不同的有效负载发送到该设备,以控制某些事物(kbd 背光、“性能模式”,打开盖子时自动启动等)。
该键盘背光有 3 种不同的亮度级别,发送到 ACPI 方法的有效负载有一个特定的字节,直接给出为 0、1、2 或 3。我现在已经为键盘背光复制了这个,如果我执行以下操作,它就可以在我的笔记本电脑上成功运行:
echo 3 | sudo tee /sys/class/leds/samsung-galaxybook::kbd_backlight/brightness
brightnessctl
它也被其他类似的实用程序正确接收,所以这是一个相当成功的成功!
sudo brightnessctl --device='samsung-galaxybook::kbd_backlight' set 3
Updated device 'samsung-galaxybook::kbd_backlight':
Device 'samsung-galaxybook::kbd_backlight' of class 'leds':
Current brightness: 3 (100%)
Max brightness: 3
现在进入问题的实质:
键盘上有一个键 (fn+F9),在 Windows 中,当您重复按下它时,它会在一个圆圈中循环显示不同级别(0、1、2、3、0、1、2 等) 。
当你在 Linux 中按下这个键时,它似乎是通过普通的键盘设备来的,但不是映射的键,并且实际上会抛出一个错误,你可以看到dmesg
这样的错误:
kernel: atkbd serio0: Unknown key pressed (translated set 2, code 0xac on isa0060/serio0).
kernel: atkbd serio0: Use 'setkeycodes e02c <keycode>' to make it known.
我尝试使用 hwdb 进行一些操作,例如为其创建一个映射,例如
KEYBOARD_KEY_ac=kbdillumtoggle
,它实际上确实控制了背光,但只会在最大 (3) 时“打开”背光,并通过重复按下将其关闭 (0) - 无法达到级别 1 和 2,并且KEYBOARD_KEY_ac=kbdillumup
,这“有点”起作用,因为第一次从 0 开始,你可以逐步通过 1、2,然后是 3。但是一旦你到达顶部,它只会停留在顶部的 3,并且你无法关掉灯。
我想我现在正处于十字路口,因为我不知道“正确”的解决方案是什么。实际尝试映射此键以便我可以按照我想要的方式控制这个新的 kbd 背光的最佳方法是什么?是否有可能以某种方式将其构建到平台驱动程序中,它实际上会捕获密钥,然后我可以编写代码来控制这种“循环”行为?
我研究了一些稀疏键盘映射支持,但据我了解,这更多的是如果您的按键是 ACPI 设备的一部分(当您按下它时,它会抛出 ACPI 事件,而不是从键盘设备按下“正常”键盘??)这里的情况并非如此——我的钥匙实际上确实是通过键盘输入的,但我想以某种方式“覆盖”它的行为,理想情况下以“标准化”方式提供良好的开箱即用功能经验与新平台驱动程序相结合。
我的选择是什么?“最佳”/“正确”的选择是什么?