* Support for X1 tablet keyboard (was Re: [PATCH] platform/x86: thinkpad_acpi: handle HKEY 0x4012, 0x4013 events) [not found] ` <38cb8265-1e30-d547-9e12-b4ae290be737@a-kobel.de> @ 2021-02-08 10:17 ` Hans de Goede 2021-02-09 15:16 ` Alexander Kobel 0 siblings, 1 reply; 9+ messages in thread From: Hans de Goede @ 2021-02-08 10:17 UTC (permalink / raw) To: Alexander Kobel, platform-driver-x86, Mark Pearson, Nitin Joshi1 Cc: linux-input Hi, On 2/7/21 6:55 PM, Alexander Kobel wrote: > Hi, > > On 2/7/21 6:10 PM, Hans de Goede wrote: >> Hi, >> >> On 2/7/21 5:34 PM, Alexander Kobel wrote: >>> Those events occur when a keyboard cover is attached to a ThinkPad >>> Tablet device. Typically, they are used to switch from normal to tablet >>> mode in userspace; e.g., to offer touch keyboard choices when focus goes >>> to a text box and no keyboard is attached, or to enable autorotation of >>> the display according to the builtin orientation sensor. >> >> Thank you for your patch. > > Thank you for your swift response. You're welcome. >>> No attempt is taken to emit an EV_SW event for SW_TABLET_MODE; this is >>> left to userspace. >> >> I don't understand this part, in order for userspace to respond to these >> events the thinkpad_acpi driver needs to emit events for this; and emitting >> SW_TABLET_MODE seems like it is the right thing to do. >> >> Why are you not doing this ? > > Quite frankly, because I did not know how to, reliably. (First ever > patch attempt to the kernel here, so I'd rather err on the safe side.) > > There are a number of events (e.g., TP_HKEY_EV_HOTPLUG_DOCK) that do not > propagate to userspace, but only report a specific message. I figured > it's better to have a meaningful entry in the log rather than just the > warning about an unknown event. > But on second thought: pretending to react, but not actually doing > something, isn't too valuable. > > I'll go off and try to improve. So Nitin has been kind enough to provide us with some docs for this, please see me reply to Nitin's email and lets continue this part of this mail thread there. <snip> > Finally, I mentioned some open ends already on a post to ibm-acpi-devel > at https://sourceforge.net/p/ibm-acpi/mailman/message/37200082/; this > very question is among them. > I will start tackling the SW_TABLET_MODE event issue first, but if Mark > and Nitin can already hint about the keyboard shortcuts, it'd be highly > appreciated. I think I might be able to help there, a couple of months ago I bought a second-hand thinkpad-10 tablet which also has a USB attached keyboard. In hindsight I guess I could have asked Mark and Nitin for some more info, but I went on autopilot and just ran hexdump -C on the /dev/hidraw node to see which events all the keys send. And I fired up an usb-sniffer under Windows to figure out the audio-leds, since I'm used to just figure these things out without help from the vendor :) See the recent commits here for my work on this: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/log/drivers/hid/hid-lenovo.c So on the ibm-acpi list message you said that the kbd sends the following: type 4 (EV_MSC), code 4 (MSC_SCAN), value c0001 type 1 (EV_KEY), code 240 (KEY_UNKNOWN), value 1 For the Fn-keys, does it send the same MSC_SCAN code for *all* the non-working Fn-keys ? If so then it seems that this is very much like the thinkpad 10 kbd dock which also does this, see the lenovo_input_mapping_tp10_ultrabook_kbd() function in drivers/hid/hid-lenovo.c . If I have that right, then I think we should be able to get the Fn keys to work without too much trouble. You could try hacking up drivers/hid/hid-lenovo.c a bit: 1. Add an entry to the lenovo_devices array like this: /* * Note bind to the HID_GROUP_GENERIC group, so that we only bind to the keyboard part, * while letting hid-multitouch.c handle the touchpad and trackpoint. */ { HID_DEVICE(BUS_USB, HID_GROUP_GENERIC, USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_X1_TAB), 2. Add the following entry to the switch-case in lenovo_input_mapping() : case USB_DEVICE_ID_LENOVO_X1_TAB: return lenovo_input_mapping_tp10_ultrabook_kbd(hdev, hi, field, usage, bit, max); And then build hid-lenovo.c and modprobe it. After the modprobe to: ls -l /sys/bus/hid/devices/0003:17EF:60A3.*/driver This should show 2 devices (I guess) with one being bound to hid-lenovo and 1 being bound to hid-multitouch. If this works some of your Fn + F# keys will now hopefully start doing something, you can play around with modifying lenovo_input_mapping_tp10_ultrabook_kbd to make it do the right thing for your kbd. ### About LED support, just enabling the LED support bits for the USB_DEVICE_ID_LENOVO_TP10UBKBD handling for now might work fine, but there is a tiny chance that sending the wrong command somehow puts the kbd in firmware update mode, I had that happen once with a Logitech kbd which did not seem to have any kind of handshake / passcode to avoid accidental fw updates (*). If you can give me a dump of the hid-descriptors for your keyboard, then I can check if that the LEDs might work the same way too (or not). The easiest way to get a dump is to run the following command as root: cat /sys/kernel/debug/hid/0003:17EF:60A3.*/rdesc > rdesc And then attach rdesc to your next email. Regards, Hans *) Luckily it at least had a separate firmware-bootlader mode in which it was stuck now, so with some cmdline magic to force an upgrade the Windows fw installer could still fix it. ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Support for X1 tablet keyboard (was Re: [PATCH] platform/x86: thinkpad_acpi: handle HKEY 0x4012, 0x4013 events) 2021-02-08 10:17 ` Support for X1 tablet keyboard (was Re: [PATCH] platform/x86: thinkpad_acpi: handle HKEY 0x4012, 0x4013 events) Hans de Goede @ 2021-02-09 15:16 ` Alexander Kobel 2021-02-11 23:42 ` Hans de Goede 0 siblings, 1 reply; 9+ messages in thread From: Alexander Kobel @ 2021-02-09 15:16 UTC (permalink / raw) To: Hans de Goede, platform-driver-x86, Mark Pearson, Nitin Joshi1 Cc: linux-input [-- Attachment #1.1: Type: text/plain, Size: 4874 bytes --] Hi, On 2/8/21 11:17 AM, Hans de Goede wrote: > On 2/7/21 6:55 PM, Alexander Kobel wrote: >> <snip> >> I'll go off and try to improve. > > So Nitin has been kind enough to provide us with some docs for this, > please see me reply to Nitin's email and lets continue this part of this mail > thread there. Right. I have the other patch ready, thanks to your great help. I'm waiting for Nitin's okay whether / how much info I can copy from the reference sheet to source code comments. Once I have that confirmation, I will post the revised patch. > <snip> > >> Finally, I mentioned some open ends already on a post to ibm-acpi-devel >> at https://sourceforge.net/p/ibm-acpi/mailman/message/37200082/; this >> very question is among them. >> I will start tackling the SW_TABLET_MODE event issue first, but if Mark >> and Nitin can already hint about the keyboard shortcuts, it'd be highly >> appreciated. > > I think I might be able to help there, a couple of months ago I bought > a second-hand thinkpad-10 tablet which also has a USB attached keyboard. > > In hindsight I guess I could have asked Mark and Nitin for some more info, > but I went on autopilot and just ran hexdump -C on the /dev/hidraw node > to see which events all the keys send. > > And I fired up an usb-sniffer under Windows to figure out the audio-leds, > since I'm used to just figure these things out without help from the vendor :) Yeah, why take the boring route if you know how to do all the work on your own... ;-) > See the recent commits here for my work on this: > > https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/log/drivers/hid/hid-lenovo.c Thanks, very helpful. > So on the ibm-acpi list message you said that the kbd sends the following: > > type 4 (EV_MSC), code 4 (MSC_SCAN), value c0001 > type 1 (EV_KEY), code 240 (KEY_UNKNOWN), value 1 > > For the Fn-keys, does it send the same MSC_SCAN code for *all* the > non-working Fn-keys ? Correct. And I can confirm that /dev/hidraw1 lets me distinguish between the keys. > If so then it seems that this is very much like the thinkpad 10 kbd dock > which also does this, see the lenovo_input_mapping_tp10_ultrabook_kbd() > function in drivers/hid/hid-lenovo.c . > > If I have that right, then I think we should be able to get the > Fn keys to work without too much trouble. You could try hacking up > drivers/hid/hid-lenovo.c a bit: (Not yet there, but will investigate.) > 1. Add an entry to the lenovo_devices array like this: > > /* > * Note bind to the HID_GROUP_GENERIC group, so that we only bind to the keyboard part, > * while letting hid-multitouch.c handle the touchpad and trackpoint. > */ > { HID_DEVICE(BUS_USB, HID_GROUP_GENERIC, > USB_VENDOR_ID_LENOVO, > USB_DEVICE_ID_LENOVO_X1_TAB), > > 2. Add the following entry to the switch-case in lenovo_input_mapping() : > > case USB_DEVICE_ID_LENOVO_X1_TAB: > return lenovo_input_mapping_tp10_ultrabook_kbd(hdev, hi, field, > usage, bit, max); > > And then build hid-lenovo.c and modprobe it. > > After the modprobe to: > > ls -l /sys/bus/hid/devices/0003:17EF:60A3.*/driver > > This should show 2 devices (I guess) with one being bound to hid-lenovo > and 1 being bound to hid-multitouch. So far (without patching hid-lenovo), 2 bound to hid-generic and 1 to hid-multitouch. > If this works some of your Fn + F# keys will now hopefully start doing > something, you can play around with modifying lenovo_input_mapping_tp10_ultrabook_kbd > to make it do the right thing for your kbd. > > ### > > About LED support, just enabling the LED support bits for the > USB_DEVICE_ID_LENOVO_TP10UBKBD handling for now might work fine, > but there is a tiny chance that sending the wrong command somehow puts > the kbd in firmware update mode, I had that happen once with a Logitech > kbd which did not seem to have any kind of handshake / passcode to avoid > accidental fw updates (*). > > If you can give me a dump of the hid-descriptors for your keyboard, > then I can check if that the LEDs might work the same way too (or not). > > The easiest way to get a dump is to run the following command as root: > > cat /sys/kernel/debug/hid/0003:17EF:60A3.*/rdesc > rdesc > > And then attach rdesc to your next email. Please find this one attached already now. In case it helps, the * expands to 0057 0058 0059 on my system. Thanks, Alex > Regards, > > Hans > > > > > > *) Luckily it at least had a separate firmware-bootlader mode in which it > was stuck now, so with some cmdline magic to force an upgrade the Windows > fw installer could still fix it. > [-- Attachment #1.2: rdesc --] [-- Type: text/plain, Size: 51585 bytes --] 05 01 09 06 a1 01 05 07 19 e0 29 e7 15 00 25 01 75 01 95 08 81 02 95 01 75 08 81 01 95 05 75 01 05 08 19 01 29 05 91 02 95 01 75 03 91 01 95 06 75 08 15 00 26 ff 00 05 07 19 00 2a ff 00 81 00 05 0c 09 00 15 80 25 7f 95 40 75 08 b1 02 c0 INPUT[INPUT] Field(0) Application(GenericDesktop.Keyboard) Usage(8) Keyboard.00e0 Keyboard.00e1 Keyboard.00e2 Keyboard.00e3 Keyboard.00e4 Keyboard.00e5 Keyboard.00e6 Keyboard.00e7 Logical Minimum(0) Logical Maximum(1) Report Size(1) Report Count(8) Report Offset(0) Flags( Variable Absolute ) Field(1) Application(GenericDesktop.Keyboard) Usage(256) Keyboard.0000 Keyboard.0001 Keyboard.0002 Keyboard.0003 Keyboard.0004 Keyboard.0005 Keyboard.0006 Keyboard.0007 Keyboard.0008 Keyboard.0009 Keyboard.000a Keyboard.000b Keyboard.000c Keyboard.000d Keyboard.000e Keyboard.000f Keyboard.0010 Keyboard.0011 Keyboard.0012 Keyboard.0013 Keyboard.0014 Keyboard.0015 Keyboard.0016 Keyboard.0017 Keyboard.0018 Keyboard.0019 Keyboard.001a Keyboard.001b Keyboard.001c Keyboard.001d Keyboard.001e Keyboard.001f Keyboard.0020 Keyboard.0021 Keyboard.0022 Keyboard.0023 Keyboard.0024 Keyboard.0025 Keyboard.0026 Keyboard.0027 Keyboard.0028 Keyboard.0029 Keyboard.002a Keyboard.002b Keyboard.002c Keyboard.002d Keyboard.002e Keyboard.002f Keyboard.0030 Keyboard.0031 Keyboard.0032 Keyboard.0033 Keyboard.0034 Keyboard.0035 Keyboard.0036 Keyboard.0037 Keyboard.0038 Keyboard.0039 Keyboard.003a Keyboard.003b Keyboard.003c Keyboard.003d Keyboard.003e Keyboard.003f Keyboard.0040 Keyboard.0041 Keyboard.0042 Keyboard.0043 Keyboard.0044 Keyboard.0045 Keyboard.0046 Keyboard.0047 Keyboard.0048 Keyboard.0049 Keyboard.004a Keyboard.004b Keyboard.004c Keyboard.004d Keyboard.004e Keyboard.004f Keyboard.0050 Keyboard.0051 Keyboard.0052 Keyboard.0053 Keyboard.0054 Keyboard.0055 Keyboard.0056 Keyboard.0057 Keyboard.0058 Keyboard.0059 Keyboard.005a Keyboard.005b Keyboard.005c Keyboard.005d Keyboard.005e Keyboard.005f Keyboard.0060 Keyboard.0061 Keyboard.0062 Keyboard.0063 Keyboard.0064 Keyboard.0065 Keyboard.0066 Keyboard.0067 Keyboard.0068 Keyboard.0069 Keyboard.006a Keyboard.006b Keyboard.006c Keyboard.006d Keyboard.006e Keyboard.006f Keyboard.0070 Keyboard.0071 Keyboard.0072 Keyboard.0073 Keyboard.0074 Keyboard.0075 Keyboard.0076 Keyboard.0077 Keyboard.0078 Keyboard.0079 Keyboard.007a Keyboard.007b Keyboard.007c Keyboard.007d Keyboard.007e Keyboard.007f Keyboard.0080 Keyboard.0081 Keyboard.0082 Keyboard.0083 Keyboard.0084 Keyboard.0085 Keyboard.0086 Keyboard.0087 Keyboard.0088 Keyboard.0089 Keyboard.008a Keyboard.008b Keyboard.008c Keyboard.008d Keyboard.008e Keyboard.008f Keyboard.0090 Keyboard.0091 Keyboard.0092 Keyboard.0093 Keyboard.0094 Keyboard.0095 Keyboard.0096 Keyboard.0097 Keyboard.0098 Keyboard.0099 Keyboard.009a Keyboard.009b Keyboard.009c Keyboard.009d Keyboard.009e Keyboard.009f Keyboard.00a0 Keyboard.00a1 Keyboard.00a2 Keyboard.00a3 Keyboard.00a4 Keyboard.00a5 Keyboard.00a6 Keyboard.00a7 Keyboard.00a8 Keyboard.00a9 Keyboard.00aa Keyboard.00ab Keyboard.00ac Keyboard.00ad Keyboard.00ae Keyboard.00af Keyboard.00b0 Keyboard.00b1 Keyboard.00b2 Keyboard.00b3 Keyboard.00b4 Keyboard.00b5 Keyboard.00b6 Keyboard.00b7 Keyboard.00b8 Keyboard.00b9 Keyboard.00ba Keyboard.00bb Keyboard.00bc Keyboard.00bd Keyboard.00be Keyboard.00bf Keyboard.00c0 Keyboard.00c1 Keyboard.00c2 Keyboard.00c3 Keyboard.00c4 Keyboard.00c5 Keyboard.00c6 Keyboard.00c7 Keyboard.00c8 Keyboard.00c9 Keyboard.00ca Keyboard.00cb Keyboard.00cc Keyboard.00cd Keyboard.00ce Keyboard.00cf Keyboard.00d0 Keyboard.00d1 Keyboard.00d2 Keyboard.00d3 Keyboard.00d4 Keyboard.00d5 Keyboard.00d6 Keyboard.00d7 Keyboard.00d8 Keyboard.00d9 Keyboard.00da Keyboard.00db Keyboard.00dc Keyboard.00dd Keyboard.00de Keyboard.00df Keyboard.00e0 Keyboard.00e1 Keyboard.00e2 Keyboard.00e3 Keyboard.00e4 Keyboard.00e5 Keyboard.00e6 Keyboard.00e7 Keyboard.00e8 Keyboard.00e9 Keyboard.00ea Keyboard.00eb Keyboard.00ec Keyboard.00ed Keyboard.00ee Keyboard.00ef Keyboard.00f0 Keyboard.00f1 Keyboard.00f2 Keyboard.00f3 Keyboard.00f4 Keyboard.00f5 Keyboard.00f6 Keyboard.00f7 Keyboard.00f8 Keyboard.00f9 Keyboard.00fa Keyboard.00fb Keyboard.00fc Keyboard.00fd Keyboard.00fe Keyboard.00ff Logical Minimum(0) Logical Maximum(255) Report Size(8) Report Count(6) Report Offset(16) Flags( Array Absolute ) OUTPUT[OUTPUT] Field(0) Application(GenericDesktop.Keyboard) Usage(5) LED.NumLock LED.CapsLock LED.ScrollLock LED.Compose LED.Kana Logical Minimum(0) Logical Maximum(1) Report Size(1) Report Count(5) Report Offset(0) Flags( Variable Absolute ) FEATURE[FEATURE] Field(0) Application(GenericDesktop.Keyboard) Usage(64) Consumer.0000 Consumer.0000 Consumer.0000 Consumer.0000 Consumer.0000 Consumer.0000 Consumer.0000 Consumer.0000 Consumer.0000 Consumer.0000 Consumer.0000 Consumer.0000 Consumer.0000 Consumer.0000 Consumer.0000 Consumer.0000 Consumer.0000 Consumer.0000 Consumer.0000 Consumer.0000 Consumer.0000 Consumer.0000 Consumer.0000 Consumer.0000 Consumer.0000 Consumer.0000 Consumer.0000 Consumer.0000 Consumer.0000 Consumer.0000 Consumer.0000 Consumer.0000 Consumer.0000 Consumer.0000 Consumer.0000 Consumer.0000 Consumer.0000 Consumer.0000 Consumer.0000 Consumer.0000 Consumer.0000 Consumer.0000 Consumer.0000 Consumer.0000 Consumer.0000 Consumer.0000 Consumer.0000 Consumer.0000 Consumer.0000 Consumer.0000 Consumer.0000 Consumer.0000 Consumer.0000 Consumer.0000 Consumer.0000 Consumer.0000 Consumer.0000 Consumer.0000 Consumer.0000 Consumer.0000 Consumer.0000 Consumer.0000 Consumer.0000 Consumer.0000 Logical Minimum(-128) Logical Maximum(127) Report Size(8) Report Count(64) Report Offset(0) Flags( Variable Absolute ) Keyboard.00e0 ---> Key.LeftControl Keyboard.00e1 ---> Key.LeftShift Keyboard.00e2 ---> Key.LeftAlt Keyboard.00e3 ---> Key.LeftMeta Keyboard.00e4 ---> Key.RightCtrl Keyboard.00e5 ---> Key.RightShift Keyboard.00e6 ---> Key.RightAlt Keyboard.00e7 ---> Key.RightMeta Keyboard.0000 ---> Sync.Report Keyboard.0001 ---> Sync.Report Keyboard.0002 ---> Sync.Report Keyboard.0003 ---> Sync.Report Keyboard.0004 ---> Key.A Keyboard.0005 ---> Key.B Keyboard.0006 ---> Key.C Keyboard.0007 ---> Key.D Keyboard.0008 ---> Key.E Keyboard.0009 ---> Key.F Keyboard.000a ---> Key.G Keyboard.000b ---> Key.H Keyboard.000c ---> Key.I Keyboard.000d ---> Key.J Keyboard.000e ---> Key.K Keyboard.000f ---> Key.L Keyboard.0010 ---> Key.M Keyboard.0011 ---> Key.N Keyboard.0012 ---> Key.O Keyboard.0013 ---> Key.P Keyboard.0014 ---> Key.Q Keyboard.0015 ---> Key.R Keyboard.0016 ---> Key.S Keyboard.0017 ---> Key.T Keyboard.0018 ---> Key.U Keyboard.0019 ---> Key.V Keyboard.001a ---> Key.W Keyboard.001b ---> Key.X Keyboard.001c ---> Key.Y Keyboard.001d ---> Key.Z Keyboard.001e ---> Key.1 Keyboard.001f ---> Key.2 Keyboard.0020 ---> Key.3 Keyboard.0021 ---> Key.4 Keyboard.0022 ---> Key.5 Keyboard.0023 ---> Key.6 Keyboard.0024 ---> Key.7 Keyboard.0025 ---> Key.8 Keyboard.0026 ---> Key.9 Keyboard.0027 ---> Key.0 Keyboard.0028 ---> Key.Enter Keyboard.0029 ---> Key.Esc Keyboard.002a ---> Key.Backspace Keyboard.002b ---> Key.Tab Keyboard.002c ---> Key.Space Keyboard.002d ---> Key.Minus Keyboard.002e ---> Key.Equal Keyboard.002f ---> Key.LeftBrace Keyboard.0030 ---> Key.RightBrace Keyboard.0031 ---> Key.BackSlash Keyboard.0032 ---> Key.BackSlash Keyboard.0033 ---> Key.Semicolon Keyboard.0034 ---> Key.Apostrophe Keyboard.0035 ---> Key.Grave Keyboard.0036 ---> Key.Comma Keyboard.0037 ---> Key.Dot Keyboard.0038 ---> Key.Slash Keyboard.0039 ---> Key.CapsLock Keyboard.003a ---> Key.F1 Keyboard.003b ---> Key.F2 Keyboard.003c ---> Key.F3 Keyboard.003d ---> Key.F4 Keyboard.003e ---> Key.F5 Keyboard.003f ---> Key.F6 Keyboard.0040 ---> Key.F7 Keyboard.0041 ---> Key.F8 Keyboard.0042 ---> Key.F9 Keyboard.0043 ---> Key.F10 Keyboard.0044 ---> Key.F11 Keyboard.0045 ---> Key.F12 Keyboard.0046 ---> Key.SysRq Keyboard.0047 ---> Key.ScrollLock Keyboard.0048 ---> Key.Pause Keyboard.0049 ---> Key.Insert Keyboard.004a ---> Key.Home Keyboard.004b ---> Key.PageUp Keyboard.004c ---> Key.Delete Keyboard.004d ---> Key.End Keyboard.004e ---> Key.PageDown Keyboard.004f ---> Key.Right Keyboard.0050 ---> Key.Left Keyboard.0051 ---> Key.Down Keyboard.0052 ---> Key.Up Keyboard.0053 ---> Key.NumLock Keyboard.0054 ---> Key.KPSlash Keyboard.0055 ---> Key.KPAsterisk Keyboard.0056 ---> Key.KPMinus Keyboard.0057 ---> Key.KPPlus Keyboard.0058 ---> Key.KPEnter Keyboard.0059 ---> Key.KP1 Keyboard.005a ---> Key.KP2 Keyboard.005b ---> Key.KP3 Keyboard.005c ---> Key.KP4 Keyboard.005d ---> Key.KP5 Keyboard.005e ---> Key.KP6 Keyboard.005f ---> Key.KP7 Keyboard.0060 ---> Key.KP8 Keyboard.0061 ---> Key.KP9 Keyboard.0062 ---> Key.KP0 Keyboard.0063 ---> Key.KPDot Keyboard.0064 ---> Key.102nd Keyboard.0065 ---> Key.Compose Keyboard.0066 ---> Key.Power Keyboard.0067 ---> Key.KPEqual Keyboard.0068 ---> Key.F13 Keyboard.0069 ---> Key.F14 Keyboard.006a ---> Key.F15 Keyboard.006b ---> Key.F16 Keyboard.006c ---> Key.F17 Keyboard.006d ---> Key.F18 Keyboard.006e ---> Key.F19 Keyboard.006f ---> Key.F20 Keyboard.0070 ---> Key.F21 Keyboard.0071 ---> Key.F22 Keyboard.0072 ---> Key.F23 Keyboard.0073 ---> Key.F24 Keyboard.0074 ---> Key.Open Keyboard.0075 ---> Key.Help Keyboard.0076 ---> Key.Props Keyboard.0077 ---> Key.Front Keyboard.0078 ---> Key.Stop Keyboard.0079 ---> Key.Again Keyboard.007a ---> Key.Undo Keyboard.007b ---> Key.Cut Keyboard.007c ---> Key.Copy Keyboard.007d ---> Key.Paste Keyboard.007e ---> Key.Find Keyboard.007f ---> Key.Mute Keyboard.0080 ---> Key.VolumeUp Keyboard.0081 ---> Key.VolumeDown Keyboard.0082 ---> Key.Unknown Keyboard.0083 ---> Key.Unknown Keyboard.0084 ---> Key.Unknown Keyboard.0085 ---> Key.KPComma Keyboard.0086 ---> Key.Unknown Keyboard.0087 ---> Key.RO Keyboard.0088 ---> Key.Katakana/Hiragana Keyboard.0089 ---> Key.Yen Keyboard.008a ---> Key.Henkan Keyboard.008b ---> Key.Muhenkan Keyboard.008c ---> Key.KPJpComma Keyboard.008d ---> Key.Unknown Keyboard.008e ---> Key.Unknown Keyboard.008f ---> Key.Unknown Keyboard.0090 ---> Key.Hangeul Keyboard.0091 ---> Key.Hanja Keyboard.0092 ---> Key.Katakana Keyboard.0093 ---> Key.HIRAGANA Keyboard.0094 ---> Key.Zenkaku/Hankaku Keyboard.0095 ---> Key.Unknown Keyboard.0096 ---> Key.Unknown Keyboard.0097 ---> Key.Unknown Keyboard.0098 ---> Key.Unknown Keyboard.0099 ---> Key.Unknown Keyboard.009a ---> Key.Unknown Keyboard.009b ---> Key.Unknown Keyboard.009c ---> Key.Delete Keyboard.009d ---> Key.Unknown Keyboard.009e ---> Key.Unknown Keyboard.009f ---> Key.Unknown Keyboard.00a0 ---> Key.Unknown Keyboard.00a1 ---> Key.Unknown Keyboard.00a2 ---> Key.Unknown Keyboard.00a3 ---> Key.Unknown Keyboard.00a4 ---> Key.Unknown Keyboard.00a5 ---> Key.Unknown Keyboard.00a6 ---> Key.Unknown Keyboard.00a7 ---> Key.Unknown Keyboard.00a8 ---> Key.Unknown Keyboard.00a9 ---> Key.Unknown Keyboard.00aa ---> Key.Unknown Keyboard.00ab ---> Key.Unknown Keyboard.00ac ---> Key.Unknown Keyboard.00ad ---> Key.Unknown Keyboard.00ae ---> Key.Unknown Keyboard.00af ---> Key.Unknown Keyboard.00b0 ---> Key.Unknown Keyboard.00b1 ---> Key.Unknown Keyboard.00b2 ---> Key.Unknown Keyboard.00b3 ---> Key.Unknown Keyboard.00b4 ---> Key.Unknown Keyboard.00b5 ---> Key.Unknown Keyboard.00b6 ---> Key.KPLeftParenthesis Keyboard.00b7 ---> Key.KPRightParenthesis Keyboard.00b8 ---> Key.Unknown Keyboard.00b9 ---> Key.Unknown Keyboard.00ba ---> Key.Unknown Keyboard.00bb ---> Key.Unknown Keyboard.00bc ---> Key.Unknown Keyboard.00bd ---> Key.Unknown Keyboard.00be ---> Key.Unknown Keyboard.00bf ---> Key.Unknown Keyboard.00c0 ---> Key.Unknown Keyboard.00c1 ---> Key.Unknown Keyboard.00c2 ---> Key.Unknown Keyboard.00c3 ---> Key.Unknown Keyboard.00c4 ---> Key.Unknown Keyboard.00c5 ---> Key.Unknown Keyboard.00c6 ---> Key.Unknown Keyboard.00c7 ---> Key.Unknown Keyboard.00c8 ---> Key.Unknown Keyboard.00c9 ---> Key.Unknown Keyboard.00ca ---> Key.Unknown Keyboard.00cb ---> Key.Unknown Keyboard.00cc ---> Key.Unknown Keyboard.00cd ---> Key.Unknown Keyboard.00ce ---> Key.Unknown Keyboard.00cf ---> Key.Unknown Keyboard.00d0 ---> Key.Unknown Keyboard.00d1 ---> Key.Unknown Keyboard.00d2 ---> Key.Unknown Keyboard.00d3 ---> Key.Unknown Keyboard.00d4 ---> Key.Unknown Keyboard.00d5 ---> Key.Unknown Keyboard.00d6 ---> Key.Unknown Keyboard.00d7 ---> Key.Unknown Keyboard.00d8 ---> Key.Delete Keyboard.00d9 ---> Key.Unknown Keyboard.00da ---> Key.Unknown Keyboard.00db ---> Key.Unknown Keyboard.00dc ---> Key.Unknown Keyboard.00dd ---> Key.Unknown Keyboard.00de ---> Key.Unknown Keyboard.00df ---> Key.Unknown Keyboard.00e0 ---> Key.LeftControl Keyboard.00e1 ---> Key.LeftShift Keyboard.00e2 ---> Key.LeftAlt Keyboard.00e3 ---> Key.LeftMeta Keyboard.00e4 ---> Key.RightCtrl Keyboard.00e5 ---> Key.RightShift Keyboard.00e6 ---> Key.RightAlt Keyboard.00e7 ---> Key.RightMeta Keyboard.00e8 ---> Key.PlayPause Keyboard.00e9 ---> Key.StopCD Keyboard.00ea ---> Key.PreviousSong Keyboard.00eb ---> Key.NextSong Keyboard.00ec ---> Key.EjectCD Keyboard.00ed ---> Key.VolumeUp Keyboard.00ee ---> Key.VolumeDown Keyboard.00ef ---> Key.Mute Keyboard.00f0 ---> Key.WWW Keyboard.00f1 ---> Key.Back Keyboard.00f2 ---> Key.Forward Keyboard.00f3 ---> Key.Stop Keyboard.00f4 ---> Key.Find Keyboard.00f5 ---> Key.ScrollUp Keyboard.00f6 ---> Key.ScrollDown Keyboard.00f7 ---> Key.Edit Keyboard.00f8 ---> Key.Sleep Keyboard.00f9 ---> Key.Coffee Keyboard.00fa ---> Key.Refresh Keyboard.00fb ---> Key.Calc Keyboard.00fc ---> Key.Unknown Keyboard.00fd ---> Key.Unknown Keyboard.00fe ---> Key.Unknown Keyboard.00ff ---> Key.Unknown LED.NumLock ---> LED.NumLock LED.CapsLock ---> LED.CapsLock LED.ScrollLock ---> LED.ScrollLock LED.Compose ---> LED.Compose LED.Kana ---> LED.Kana 05 01 09 80 a1 01 85 02 05 01 19 81 29 83 15 00 25 01 95 03 75 01 81 02 95 01 75 05 81 01 c0 05 0c 09 01 a1 01 85 03 15 00 25 01 09 01 09 01 09 01 09 01 09 01 09 e2 09 01 09 01 09 01 09 01 09 01 09 b7 09 01 09 01 09 01 09 01 09 01 09 01 09 01 09 6f 09 ea 09 e9 09 70 09 01 75 01 95 18 81 02 c0 06 a0 ff 09 01 a1 01 85 09 15 00 25 ff 09 04 75 08 95 02 91 02 06 a1 ff 09 01 85 54 15 00 25 7f 0a 11 00 75 08 95 01 b1 02 06 a2 ff 09 01 85 64 15 00 25 01 0a 12 00 75 08 95 01 b1 02 06 a3 ff 09 01 85 74 15 00 25 01 0a 13 00 75 08 95 01 b1 02 06 a4 ff 09 01 85 90 09 08 b1 02 85 84 09 09 b1 02 85 20 09 0a b1 02 06 a5 ff 09 01 85 a2 09 0b 95 06 b1 02 85 a3 09 0c 95 03 b1 02 c0 09 22 a1 00 85 04 09 57 09 58 75 01 95 02 25 01 b1 02 95 06 b1 03 c0 INPUT(2)[INPUT] Field(0) Application(GenericDesktop.SystemControl) Usage(3) GenericDesktop.SystemPowerDown GenericDesktop.SystemSleep GenericDesktop.SystemWakeUp Logical Minimum(0) Logical Maximum(1) Report Size(1) Report Count(3) Report Offset(0) Flags( Variable Absolute ) INPUT(3)[INPUT] Field(0) Application(Consumer.0001) Usage(24) Consumer.0001 Consumer.0001 Consumer.0001 Consumer.0001 Consumer.0001 Consumer.00e2 Consumer.0001 Consumer.0001 Consumer.0001 Consumer.0001 Consumer.0001 Consumer.00b7 Consumer.0001 Consumer.0001 Consumer.0001 Consumer.0001 Consumer.0001 Consumer.0001 Consumer.0001 Consumer.006f Consumer.00ea Consumer.00e9 Consumer.0070 Consumer.0001 Logical Minimum(0) Logical Maximum(1) Report Size(1) Report Count(24) Report Offset(0) Flags( Variable Absolute ) OUTPUT(9)[OUTPUT] Field(0) Application(ffa0.0001) Usage(2) ffa0.0004 ffa0.0004 Logical Minimum(0) Logical Maximum(255) Report Size(8) Report Count(2) Report Offset(0) Flags( Variable Absolute ) FEATURE(84)[FEATURE] Field(0) Application(ffa0.0001) Usage(2) ffa1.0001 ffa1.0011 Logical Minimum(0) Logical Maximum(127) Report Size(8) Report Count(1) Report Offset(0) Flags( Variable Absolute ) FEATURE(100)[FEATURE] Field(0) Application(ffa0.0001) Usage(2) ffa2.0001 ffa2.0012 Logical Minimum(0) Logical Maximum(1) Report Size(8) Report Count(1) Report Offset(0) Flags( Variable Absolute ) FEATURE(116)[FEATURE] Field(0) Application(ffa0.0001) Usage(2) ffa3.0001 ffa3.0013 Logical Minimum(0) Logical Maximum(1) Report Size(8) Report Count(1) Report Offset(0) Flags( Variable Absolute ) FEATURE(144)[FEATURE] Field(0) Application(ffa0.0001) Usage(2) ffa4.0001 ffa4.0008 Logical Minimum(0) Logical Maximum(1) Report Size(8) Report Count(1) Report Offset(0) Flags( Variable Absolute ) FEATURE(132)[FEATURE] Field(0) Application(ffa0.0001) Usage(1) ffa4.0009 Logical Minimum(0) Logical Maximum(1) Report Size(8) Report Count(1) Report Offset(0) Flags( Variable Absolute ) FEATURE(32)[FEATURE] Field(0) Application(ffa0.0001) Usage(1) ffa4.000a Logical Minimum(0) Logical Maximum(1) Report Size(8) Report Count(1) Report Offset(0) Flags( Variable Absolute ) FEATURE(162)[FEATURE] Field(0) Application(ffa0.0001) Usage(6) ffa5.0001 ffa5.000b ffa5.000b ffa5.000b ffa5.000b ffa5.000b Logical Minimum(0) Logical Maximum(1) Report Size(8) Report Count(6) Report Offset(0) Flags( Variable Absolute ) FEATURE(163)[FEATURE] Field(0) Application(ffa0.0001) Usage(3) ffa5.000c ffa5.000c ffa5.000c Logical Minimum(0) Logical Maximum(1) Report Size(8) Report Count(3) Report Offset(0) Flags( Variable Absolute ) FEATURE(4)[FEATURE] Field(0) Physical(ffa5.0022) Usage(2) ffa5.0057 ffa5.0058 Logical Minimum(0) Logical Maximum(1) Report Size(1) Report Count(2) Report Offset(0) Flags( Variable Absolute ) GenericDesktop.SystemPowerDown ---> Key.Power GenericDesktop.SystemSleep ---> Key.Sleep GenericDesktop.SystemWakeUp ---> Key.WakeUp Consumer.0001 ---> Key.Unknown Consumer.0001 ---> Key.Unknown Consumer.0001 ---> Key.Unknown Consumer.0001 ---> Key.Unknown Consumer.0001 ---> Key.Unknown Consumer.00e2 ---> Key.Mute Consumer.0001 ---> Key.Unknown Consumer.0001 ---> Key.Unknown Consumer.0001 ---> Key.Unknown Consumer.0001 ---> Key.Unknown Consumer.0001 ---> Key.Unknown Consumer.00b7 ---> Key.StopCD Consumer.0001 ---> Key.Unknown Consumer.0001 ---> Key.Unknown Consumer.0001 ---> Key.Unknown Consumer.0001 ---> Key.Unknown Consumer.0001 ---> Key.Unknown Consumer.0001 ---> Key.Unknown Consumer.0001 ---> Key.Unknown Consumer.006f ---> Key.BrightnessUp Consumer.00ea ---> Key.VolumeDown Consumer.00e9 ---> Key.VolumeUp Consumer.0070 ---> Key.BrightnessDown Consumer.0001 ---> Key.Unknown ffa0.0004 ---> Sync.Report ffa0.0004 ---> Sync.Report 05 01 09 02 a1 01 85 02 09 01 a1 00 05 09 19 01 29 02 15 00 25 01 75 01 95 02 81 02 95 06 81 01 05 01 09 30 09 31 15 81 25 7f 75 08 95 02 81 06 c0 c0 05 01 09 02 a1 01 85 10 09 01 a1 00 05 09 19 01 29 03 15 00 25 01 75 01 95 03 81 02 95 05 81 01 05 01 09 30 09 31 15 81 25 7f 75 08 95 02 81 06 c0 c0 05 0d 09 05 a1 01 85 03 05 0d 09 22 a1 02 15 00 25 01 09 47 09 42 95 02 75 01 81 02 95 01 75 03 25 05 09 51 81 02 75 01 95 03 81 03 05 01 15 00 26 16 04 75 10 55 0e 65 11 09 30 35 00 46 67 03 95 01 81 02 46 d0 01 26 2d 02 09 31 81 02 c0 05 0d 09 22 a1 02 15 00 25 01 09 47 09 42 95 02 75 01 81 02 95 01 75 03 25 05 09 51 81 02 75 01 95 03 81 03 05 01 15 00 26 16 04 75 10 55 0e 65 11 09 30 35 00 46 67 03 95 01 81 02 46 d0 01 26 2d 02 09 31 81 02 c0 05 0d 09 22 a1 02 15 00 25 01 09 47 09 42 95 02 75 01 81 02 95 01 75 03 25 05 09 51 81 02 75 01 95 03 81 03 05 01 15 00 26 16 04 75 10 55 0e 65 11 09 30 35 00 46 67 03 95 01 81 02 46 d0 01 26 2d 02 09 31 81 02 c0 05 0d 09 22 a1 02 15 00 25 01 09 47 09 42 95 02 75 01 81 02 95 01 75 03 25 05 09 51 81 02 75 01 95 03 81 03 05 01 15 00 26 16 04 75 10 55 0e 65 11 09 30 35 00 46 67 03 95 01 81 02 46 d0 01 26 2d 02 09 31 81 02 c0 05 0d 09 22 a1 02 15 00 25 01 09 47 09 42 95 02 75 01 81 02 95 01 75 03 25 05 09 51 81 02 75 01 95 03 81 03 05 01 15 00 26 16 04 75 10 55 0e 65 11 09 30 35 00 46 67 03 95 01 81 02 46 d0 01 26 2d 02 09 31 81 02 c0 05 0d 55 0c 66 01 10 47 ff ff 00 00 27 ff ff 00 00 75 10 95 01 09 56 81 02 09 54 25 7f 95 01 75 08 81 02 05 09 09 01 25 01 75 01 95 01 81 02 95 07 81 03 05 0d 85 08 09 55 09 59 75 04 95 02 25 0f b1 02 85 0d 09 60 75 01 95 01 15 00 25 01 b1 02 95 07 b1 03 85 07 06 00 ff 09 c5 15 00 26 ff 00 75 08 96 00 01 b1 02 c0 05 0d 09 0e a1 01 85 04 09 22 a1 02 09 52 15 00 25 0a 75 08 95 01 b1 02 c0 09 22 a1 00 85 06 09 57 09 58 75 01 95 02 25 01 b1 02 95 06 b1 03 c0 c0 06 00 ff 09 01 a1 01 85 09 09 02 15 00 26 ff 00 75 08 95 14 91 02 85 0a 09 03 15 00 26 ff 00 75 08 95 14 91 02 85 0b 09 04 15 00 26 ff 00 75 08 95 3d 81 02 85 0c 09 05 15 00 26 ff 00 75 08 95 3d 81 02 85 0f 09 06 15 00 26 ff 00 75 08 95 03 b1 02 85 0e 09 07 15 00 26 ff 00 75 08 95 01 b1 02 c0 INPUT(2)[INPUT] Field(0) Physical(GenericDesktop.Pointer) Application(GenericDesktop.Mouse) Usage(2) Button.0001 Button.0002 Logical Minimum(0) Logical Maximum(1) Report Size(1) Report Count(2) Report Offset(0) Flags( Variable Absolute ) Field(1) Physical(GenericDesktop.Pointer) Application(GenericDesktop.Mouse) Usage(2) GenericDesktop.X GenericDesktop.Y Logical Minimum(-127) Logical Maximum(127) Report Size(8) Report Count(2) Report Offset(8) Flags( Variable Relative ) INPUT(16)[INPUT] Field(0) Physical(GenericDesktop.Pointer) Application(GenericDesktop.Mouse) Usage(3) Button.0001 Button.0002 Button.0003 Logical Minimum(0) Logical Maximum(1) Report Size(1) Report Count(3) Report Offset(0) Flags( Variable Absolute ) Field(1) Physical(GenericDesktop.Pointer) Application(GenericDesktop.Mouse) Usage(2) GenericDesktop.X GenericDesktop.Y Logical Minimum(-127) Logical Maximum(127) Report Size(8) Report Count(2) Report Offset(8) Flags( Variable Relative ) INPUT(3)[INPUT] Field(0) Logical(Digitizers.Finger) Application(Digitizers.TouchPad) Usage(2) Digitizers.Confidence Digitizers.TipSwitch Logical Minimum(0) Logical Maximum(1) Report Size(1) Report Count(2) Report Offset(0) Flags( Variable Absolute ) Field(1) Logical(Digitizers.Finger) Application(Digitizers.TouchPad) Usage(1) Digitizers.ContactID Logical Minimum(0) Logical Maximum(5) Report Size(3) Report Count(1) Report Offset(2) Flags( Variable Absolute ) Field(2) Logical(Digitizers.Finger) Application(Digitizers.TouchPad) Usage(1) GenericDesktop.X Logical Minimum(0) Logical Maximum(1046) Physical Minimum(0) Physical Maximum(871) Unit Exponent(-2) Unit(SI Linear : Centimeter) Report Size(16) Report Count(1) Report Offset(8) Flags( Variable Absolute ) Field(3) Logical(Digitizers.Finger) Application(Digitizers.TouchPad) Usage(1) GenericDesktop.Y Logical Minimum(0) Logical Maximum(557) Physical Minimum(0) Physical Maximum(464) Unit Exponent(-2) Unit(SI Linear : Centimeter) Report Size(16) Report Count(1) Report Offset(24) Flags( Variable Absolute ) Field(4) Logical(Digitizers.Finger) Application(Digitizers.TouchPad) Usage(2) Digitizers.Confidence Digitizers.TipSwitch Logical Minimum(0) Logical Maximum(1) Physical Minimum(0) Physical Maximum(464) Unit Exponent(-2) Unit(SI Linear : Centimeter) Report Size(1) Report Count(2) Report Offset(40) Flags( Variable Absolute ) Field(5) Logical(Digitizers.Finger) Application(Digitizers.TouchPad) Usage(1) Digitizers.ContactID Logical Minimum(0) Logical Maximum(5) Physical Minimum(0) Physical Maximum(464) Unit Exponent(-2) Unit(SI Linear : Centimeter) Report Size(3) Report Count(1) Report Offset(42) Flags( Variable Absolute ) Field(6) Logical(Digitizers.Finger) Application(Digitizers.TouchPad) Usage(1) GenericDesktop.X Logical Minimum(0) Logical Maximum(1046) Physical Minimum(0) Physical Maximum(871) Unit Exponent(-2) Unit(SI Linear : Centimeter) Report Size(16) Report Count(1) Report Offset(48) Flags( Variable Absolute ) Field(7) Logical(Digitizers.Finger) Application(Digitizers.TouchPad) Usage(1) GenericDesktop.Y Logical Minimum(0) Logical Maximum(557) Physical Minimum(0) Physical Maximum(464) Unit Exponent(-2) Unit(SI Linear : Centimeter) Report Size(16) Report Count(1) Report Offset(64) Flags( Variable Absolute ) Field(8) Logical(Digitizers.Finger) Application(Digitizers.TouchPad) Usage(2) Digitizers.Confidence Digitizers.TipSwitch Logical Minimum(0) Logical Maximum(1) Physical Minimum(0) Physical Maximum(464) Unit Exponent(-2) Unit(SI Linear : Centimeter) Report Size(1) Report Count(2) Report Offset(80) Flags( Variable Absolute ) Field(9) Logical(Digitizers.Finger) Application(Digitizers.TouchPad) Usage(1) Digitizers.ContactID Logical Minimum(0) Logical Maximum(5) Physical Minimum(0) Physical Maximum(464) Unit Exponent(-2) Unit(SI Linear : Centimeter) Report Size(3) Report Count(1) Report Offset(82) Flags( Variable Absolute ) Field(10) Logical(Digitizers.Finger) Application(Digitizers.TouchPad) Usage(1) GenericDesktop.X Logical Minimum(0) Logical Maximum(1046) Physical Minimum(0) Physical Maximum(871) Unit Exponent(-2) Unit(SI Linear : Centimeter) Report Size(16) Report Count(1) Report Offset(88) Flags( Variable Absolute ) Field(11) Logical(Digitizers.Finger) Application(Digitizers.TouchPad) Usage(1) GenericDesktop.Y Logical Minimum(0) Logical Maximum(557) Physical Minimum(0) Physical Maximum(464) Unit Exponent(-2) Unit(SI Linear : Centimeter) Report Size(16) Report Count(1) Report Offset(104) Flags( Variable Absolute ) Field(12) Logical(Digitizers.Finger) Application(Digitizers.TouchPad) Usage(2) Digitizers.Confidence Digitizers.TipSwitch Logical Minimum(0) Logical Maximum(1) Physical Minimum(0) Physical Maximum(464) Unit Exponent(-2) Unit(SI Linear : Centimeter) Report Size(1) Report Count(2) Report Offset(120) Flags( Variable Absolute ) Field(13) Logical(Digitizers.Finger) Application(Digitizers.TouchPad) Usage(1) Digitizers.ContactID Logical Minimum(0) Logical Maximum(5) Physical Minimum(0) Physical Maximum(464) Unit Exponent(-2) Unit(SI Linear : Centimeter) Report Size(3) Report Count(1) Report Offset(122) Flags( Variable Absolute ) Field(14) Logical(Digitizers.Finger) Application(Digitizers.TouchPad) Usage(1) GenericDesktop.X Logical Minimum(0) Logical Maximum(1046) Physical Minimum(0) Physical Maximum(871) Unit Exponent(-2) Unit(SI Linear : Centimeter) Report Size(16) Report Count(1) Report Offset(128) Flags( Variable Absolute ) Field(15) Logical(Digitizers.Finger) Application(Digitizers.TouchPad) Usage(1) GenericDesktop.Y Logical Minimum(0) Logical Maximum(557) Physical Minimum(0) Physical Maximum(464) Unit Exponent(-2) Unit(SI Linear : Centimeter) Report Size(16) Report Count(1) Report Offset(144) Flags( Variable Absolute ) Field(16) Logical(Digitizers.Finger) Application(Digitizers.TouchPad) Usage(2) Digitizers.Confidence Digitizers.TipSwitch Logical Minimum(0) Logical Maximum(1) Physical Minimum(0) Physical Maximum(464) Unit Exponent(-2) Unit(SI Linear : Centimeter) Report Size(1) Report Count(2) Report Offset(160) Flags( Variable Absolute ) Field(17) Logical(Digitizers.Finger) Application(Digitizers.TouchPad) Usage(1) Digitizers.ContactID Logical Minimum(0) Logical Maximum(5) Physical Minimum(0) Physical Maximum(464) Unit Exponent(-2) Unit(SI Linear : Centimeter) Report Size(3) Report Count(1) Report Offset(162) Flags( Variable Absolute ) Field(18) Logical(Digitizers.Finger) Application(Digitizers.TouchPad) Usage(1) GenericDesktop.X Logical Minimum(0) Logical Maximum(1046) Physical Minimum(0) Physical Maximum(871) Unit Exponent(-2) Unit(SI Linear : Centimeter) Report Size(16) Report Count(1) Report Offset(168) Flags( Variable Absolute ) Field(19) Logical(Digitizers.Finger) Application(Digitizers.TouchPad) Usage(1) GenericDesktop.Y Logical Minimum(0) Logical Maximum(557) Physical Minimum(0) Physical Maximum(464) Unit Exponent(-2) Unit(SI Linear : Centimeter) Report Size(16) Report Count(1) Report Offset(184) Flags( Variable Absolute ) Field(20) Application(Digitizers.TouchPad) Usage(1) Digitizers.0056 Logical Minimum(0) Logical Maximum(65535) Physical Minimum(0) Physical Maximum(65535) Unit Exponent(-4) Unit(SI Linear : Seconds) Report Size(16) Report Count(1) Report Offset(200) Flags( Variable Absolute ) Field(21) Application(Digitizers.TouchPad) Usage(1) Digitizers.ContactCount Logical Minimum(0) Logical Maximum(127) Physical Minimum(0) Physical Maximum(65535) Unit Exponent(-4) Unit(SI Linear : Seconds) Report Size(8) Report Count(1) Report Offset(216) Flags( Variable Absolute ) Field(22) Application(Digitizers.TouchPad) Usage(1) Button.0001 Logical Minimum(0) Logical Maximum(1) Physical Minimum(0) Physical Maximum(65535) Unit Exponent(-4) Unit(SI Linear : Seconds) Report Size(1) Report Count(1) Report Offset(224) Flags( Variable Absolute ) INPUT(11)[INPUT] Field(0) Application(ff00.0001) Usage(61) ff00.0004 ff00.0004 ff00.0004 ff00.0004 ff00.0004 ff00.0004 ff00.0004 ff00.0004 ff00.0004 ff00.0004 ff00.0004 ff00.0004 ff00.0004 ff00.0004 ff00.0004 ff00.0004 ff00.0004 ff00.0004 ff00.0004 ff00.0004 ff00.0004 ff00.0004 ff00.0004 ff00.0004 ff00.0004 ff00.0004 ff00.0004 ff00.0004 ff00.0004 ff00.0004 ff00.0004 ff00.0004 ff00.0004 ff00.0004 ff00.0004 ff00.0004 ff00.0004 ff00.0004 ff00.0004 ff00.0004 ff00.0004 ff00.0004 ff00.0004 ff00.0004 ff00.0004 ff00.0004 ff00.0004 ff00.0004 ff00.0004 ff00.0004 ff00.0004 ff00.0004 ff00.0004 ff00.0004 ff00.0004 ff00.0004 ff00.0004 ff00.0004 ff00.0004 ff00.0004 ff00.0004 Logical Minimum(0) Logical Maximum(255) Physical Minimum(0) Physical Maximum(65535) Unit Exponent(-4) Unit(SI Linear : Seconds) Report Size(8) Report Count(61) Report Offset(0) Flags( Variable Absolute ) INPUT(12)[INPUT] Field(0) Application(ff00.0001) Usage(61) ff00.0005 ff00.0005 ff00.0005 ff00.0005 ff00.0005 ff00.0005 ff00.0005 ff00.0005 ff00.0005 ff00.0005 ff00.0005 ff00.0005 ff00.0005 ff00.0005 ff00.0005 ff00.0005 ff00.0005 ff00.0005 ff00.0005 ff00.0005 ff00.0005 ff00.0005 ff00.0005 ff00.0005 ff00.0005 ff00.0005 ff00.0005 ff00.0005 ff00.0005 ff00.0005 ff00.0005 ff00.0005 ff00.0005 ff00.0005 ff00.0005 ff00.0005 ff00.0005 ff00.0005 ff00.0005 ff00.0005 ff00.0005 ff00.0005 ff00.0005 ff00.0005 ff00.0005 ff00.0005 ff00.0005 ff00.0005 ff00.0005 ff00.0005 ff00.0005 ff00.0005 ff00.0005 ff00.0005 ff00.0005 ff00.0005 ff00.0005 ff00.0005 ff00.0005 ff00.0005 ff00.0005 Logical Minimum(0) Logical Maximum(255) Physical Minimum(0) Physical Maximum(65535) Unit Exponent(-4) Unit(SI Linear : Seconds) Report Size(8) Report Count(61) Report Offset(0) Flags( Variable Absolute ) OUTPUT(9)[OUTPUT] Field(0) Application(ff00.0001) Usage(20) ff00.0002 ff00.0002 ff00.0002 ff00.0002 ff00.0002 ff00.0002 ff00.0002 ff00.0002 ff00.0002 ff00.0002 ff00.0002 ff00.0002 ff00.0002 ff00.0002 ff00.0002 ff00.0002 ff00.0002 ff00.0002 ff00.0002 ff00.0002 Logical Minimum(0) Logical Maximum(255) Physical Minimum(0) Physical Maximum(65535) Unit Exponent(-4) Unit(SI Linear : Seconds) Report Size(8) Report Count(20) Report Offset(0) Flags( Variable Absolute ) OUTPUT(10)[OUTPUT] Field(0) Application(ff00.0001) Usage(20) ff00.0003 ff00.0003 ff00.0003 ff00.0003 ff00.0003 ff00.0003 ff00.0003 ff00.0003 ff00.0003 ff00.0003 ff00.0003 ff00.0003 ff00.0003 ff00.0003 ff00.0003 ff00.0003 ff00.0003 ff00.0003 ff00.0003 ff00.0003 Logical Minimum(0) Logical Maximum(255) Physical Minimum(0) Physical Maximum(65535) Unit Exponent(-4) Unit(SI Linear : Seconds) Report Size(8) Report Count(20) Report Offset(0) Flags( Variable Absolute ) FEATURE(8)[FEATURE] Field(0) Application(Digitizers.TouchPad) Usage(2) Digitizers.ContactMaximumNumber Digitizers.ButtonType Logical Minimum(0) Logical Maximum(15) Physical Minimum(0) Physical Maximum(65535) Unit Exponent(-4) Unit(SI Linear : Seconds) Report Size(4) Report Count(2) Report Offset(0) Flags( Variable Absolute ) FEATURE(13)[FEATURE] Field(0) Application(Digitizers.TouchPad) Usage(1) Digitizers.0060 Logical Minimum(0) Logical Maximum(1) Physical Minimum(0) Physical Maximum(65535) Unit Exponent(-4) Unit(SI Linear : Seconds) Report Size(1) Report Count(1) Report Offset(0) Flags( Variable Absolute ) FEATURE(7)[FEATURE] Field(0) Application(Digitizers.TouchPad) Usage(256) ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 ff00.00c5 Logical Minimum(0) Logical Maximum(255) Physical Minimum(0) Physical Maximum(65535) Unit Exponent(-4) Unit(SI Linear : Seconds) Report Size(8) Report Count(256) Report Offset(0) Flags( Variable Absolute ) FEATURE(4)[FEATURE] Field(0) Logical(Digitizers.Finger) Application(Digitizers.DeviceConfiguration) Usage(1) Digitizers.InputMode Logical Minimum(0) Logical Maximum(10) Physical Minimum(0) Physical Maximum(65535) Unit Exponent(-4) Unit(SI Linear : Seconds) Report Size(8) Report Count(1) Report Offset(0) Flags( Variable Absolute ) FEATURE(6)[FEATURE] Field(0) Physical(Digitizers.Finger) Application(Digitizers.DeviceConfiguration) Usage(2) Digitizers.0057 Digitizers.0058 Logical Minimum(0) Logical Maximum(1) Physical Minimum(0) Physical Maximum(65535) Unit Exponent(-4) Unit(SI Linear : Seconds) Report Size(1) Report Count(2) Report Offset(0) Flags( Variable Absolute ) FEATURE(15)[FEATURE] Field(0) Application(ff00.0001) Usage(3) ff00.0006 ff00.0006 ff00.0006 Logical Minimum(0) Logical Maximum(255) Physical Minimum(0) Physical Maximum(65535) Unit Exponent(-4) Unit(SI Linear : Seconds) Report Size(8) Report Count(3) Report Offset(0) Flags( Variable Absolute ) FEATURE(14)[FEATURE] Field(0) Application(ff00.0001) Usage(1) ff00.0007 Logical Minimum(0) Logical Maximum(255) Physical Minimum(0) Physical Maximum(65535) Unit Exponent(-4) Unit(SI Linear : Seconds) Report Size(8) Report Count(1) Report Offset(0) Flags( Variable Absolute ) Button.0001 ---> Key.LeftBtn Button.0002 ---> Key.RightBtn GenericDesktop.X ---> Relative.X GenericDesktop.Y ---> Relative.Y Button.0001 ---> Key.LeftBtn Button.0002 ---> Key.RightBtn Button.0003 ---> Key.MiddleBtn GenericDesktop.X ---> Relative.X GenericDesktop.Y ---> Relative.Y Digitizers.Confidence ---> Sync.Report Digitizers.TipSwitch ---> Sync.Report Digitizers.ContactID ---> Sync.Report GenericDesktop.X ---> Sync.Report GenericDesktop.Y ---> Sync.Report Digitizers.Confidence ---> Sync.Report Digitizers.TipSwitch ---> Sync.Report Digitizers.ContactID ---> Sync.Report GenericDesktop.X ---> Sync.Report GenericDesktop.Y ---> Sync.Report Digitizers.Confidence ---> Sync.Report Digitizers.TipSwitch ---> Sync.Report Digitizers.ContactID ---> Sync.Report GenericDesktop.X ---> Sync.Report GenericDesktop.Y ---> Sync.Report Digitizers.Confidence ---> Sync.Report Digitizers.TipSwitch ---> Sync.Report Digitizers.ContactID ---> Sync.Report GenericDesktop.X ---> Sync.Report GenericDesktop.Y ---> Sync.Report Digitizers.Confidence ---> Sync.Report Digitizers.TipSwitch ---> Sync.Report Digitizers.ContactID ---> Sync.Report GenericDesktop.X ---> Sync.Report GenericDesktop.Y ---> Sync.Report Digitizers.0056 ---> Sync.Report Digitizers.ContactCount ---> Sync.Report Button.0001 ---> Key.LeftBtn ff00.0004 ---> Sync.Report ff00.0004 ---> Sync.Report ff00.0004 ---> Sync.Report ff00.0004 ---> Sync.Report ff00.0004 ---> Sync.Report ff00.0004 ---> Sync.Report ff00.0004 ---> Sync.Report ff00.0004 ---> Sync.Report ff00.0004 ---> Sync.Report ff00.0004 ---> Sync.Report ff00.0004 ---> Sync.Report ff00.0004 ---> Sync.Report ff00.0004 ---> Sync.Report ff00.0004 ---> Sync.Report ff00.0004 ---> Sync.Report ff00.0004 ---> Sync.Report ff00.0004 ---> Sync.Report ff00.0004 ---> Sync.Report ff00.0004 ---> Sync.Report ff00.0004 ---> Sync.Report ff00.0004 ---> Sync.Report ff00.0004 ---> Sync.Report ff00.0004 ---> Sync.Report ff00.0004 ---> Sync.Report ff00.0004 ---> Sync.Report ff00.0004 ---> Sync.Report ff00.0004 ---> Sync.Report ff00.0004 ---> Sync.Report ff00.0004 ---> Sync.Report ff00.0004 ---> Sync.Report ff00.0004 ---> Sync.Report ff00.0004 ---> Sync.Report ff00.0004 ---> Sync.Report ff00.0004 ---> Sync.Report ff00.0004 ---> Sync.Report ff00.0004 ---> Sync.Report ff00.0004 ---> Sync.Report ff00.0004 ---> Sync.Report ff00.0004 ---> Sync.Report ff00.0004 ---> Sync.Report ff00.0004 ---> Sync.Report ff00.0004 ---> Sync.Report ff00.0004 ---> Sync.Report ff00.0004 ---> Sync.Report ff00.0004 ---> Sync.Report ff00.0004 ---> Sync.Report ff00.0004 ---> Sync.Report ff00.0004 ---> Sync.Report ff00.0004 ---> Sync.Report ff00.0004 ---> Sync.Report ff00.0004 ---> Sync.Report ff00.0004 ---> Sync.Report ff00.0004 ---> Sync.Report ff00.0004 ---> Sync.Report ff00.0004 ---> Sync.Report ff00.0004 ---> Sync.Report ff00.0004 ---> Sync.Report ff00.0004 ---> Sync.Report ff00.0004 ---> Sync.Report ff00.0004 ---> Sync.Report ff00.0004 ---> Sync.Report ff00.0005 ---> Sync.Report ff00.0005 ---> Sync.Report ff00.0005 ---> Sync.Report ff00.0005 ---> Sync.Report ff00.0005 ---> Sync.Report ff00.0005 ---> Sync.Report ff00.0005 ---> Sync.Report ff00.0005 ---> Sync.Report ff00.0005 ---> Sync.Report ff00.0005 ---> Sync.Report ff00.0005 ---> Sync.Report ff00.0005 ---> Sync.Report ff00.0005 ---> Sync.Report ff00.0005 ---> Sync.Report ff00.0005 ---> Sync.Report ff00.0005 ---> Sync.Report ff00.0005 ---> Sync.Report ff00.0005 ---> Sync.Report ff00.0005 ---> Sync.Report ff00.0005 ---> Sync.Report ff00.0005 ---> Sync.Report ff00.0005 ---> Sync.Report ff00.0005 ---> Sync.Report ff00.0005 ---> Sync.Report ff00.0005 ---> Sync.Report ff00.0005 ---> Sync.Report ff00.0005 ---> Sync.Report ff00.0005 ---> Sync.Report ff00.0005 ---> Sync.Report ff00.0005 ---> Sync.Report ff00.0005 ---> Sync.Report ff00.0005 ---> Sync.Report ff00.0005 ---> Sync.Report ff00.0005 ---> Sync.Report ff00.0005 ---> Sync.Report ff00.0005 ---> Sync.Report ff00.0005 ---> Sync.Report ff00.0005 ---> Sync.Report ff00.0005 ---> Sync.Report ff00.0005 ---> Sync.Report ff00.0005 ---> Sync.Report ff00.0005 ---> Sync.Report ff00.0005 ---> Sync.Report ff00.0005 ---> Sync.Report ff00.0005 ---> Sync.Report ff00.0005 ---> Sync.Report ff00.0005 ---> Sync.Report ff00.0005 ---> Sync.Report ff00.0005 ---> Sync.Report ff00.0005 ---> Sync.Report ff00.0005 ---> Sync.Report ff00.0005 ---> Sync.Report ff00.0005 ---> Sync.Report ff00.0005 ---> Sync.Report ff00.0005 ---> Sync.Report ff00.0005 ---> Sync.Report ff00.0005 ---> Sync.Report ff00.0005 ---> Sync.Report ff00.0005 ---> Sync.Report ff00.0005 ---> Sync.Report ff00.0005 ---> Sync.Report ff00.0002 ---> Sync.Report ff00.0002 ---> Sync.Report ff00.0002 ---> Sync.Report ff00.0002 ---> Sync.Report ff00.0002 ---> Sync.Report ff00.0002 ---> Sync.Report ff00.0002 ---> Sync.Report ff00.0002 ---> Sync.Report ff00.0002 ---> Sync.Report ff00.0002 ---> Sync.Report ff00.0002 ---> Sync.Report ff00.0002 ---> Sync.Report ff00.0002 ---> Sync.Report ff00.0002 ---> Sync.Report ff00.0002 ---> Sync.Report ff00.0002 ---> Sync.Report ff00.0002 ---> Sync.Report ff00.0002 ---> Sync.Report ff00.0002 ---> Sync.Report ff00.0002 ---> Sync.Report ff00.0003 ---> Sync.Report ff00.0003 ---> Sync.Report ff00.0003 ---> Sync.Report ff00.0003 ---> Sync.Report ff00.0003 ---> Sync.Report ff00.0003 ---> Sync.Report ff00.0003 ---> Sync.Report ff00.0003 ---> Sync.Report ff00.0003 ---> Sync.Report ff00.0003 ---> Sync.Report ff00.0003 ---> Sync.Report ff00.0003 ---> Sync.Report ff00.0003 ---> Sync.Report ff00.0003 ---> Sync.Report ff00.0003 ---> Sync.Report ff00.0003 ---> Sync.Report ff00.0003 ---> Sync.Report ff00.0003 ---> Sync.Report ff00.0003 ---> Sync.Report ff00.0003 ---> Sync.Report [-- Attachment #2: S/MIME Cryptographic Signature --] [-- Type: application/pkcs7-signature, Size: 5916 bytes --] ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Support for X1 tablet keyboard (was Re: [PATCH] platform/x86: thinkpad_acpi: handle HKEY 0x4012, 0x4013 events) 2021-02-09 15:16 ` Alexander Kobel @ 2021-02-11 23:42 ` Hans de Goede 2021-02-21 13:17 ` Alexander Kobel 0 siblings, 1 reply; 9+ messages in thread From: Hans de Goede @ 2021-02-11 23:42 UTC (permalink / raw) To: Alexander Kobel, platform-driver-x86, Mark Pearson, Nitin Joshi1 Cc: linux-input [-- Attachment #1: Type: text/plain, Size: 7161 bytes --] Hi, On 2/9/21 4:16 PM, Alexander Kobel wrote: > Hi, > > On 2/8/21 11:17 AM, Hans de Goede wrote: >> On 2/7/21 6:55 PM, Alexander Kobel wrote: >>> <snip> >>> I'll go off and try to improve. >> >> So Nitin has been kind enough to provide us with some docs for this, >> please see me reply to Nitin's email and lets continue this part of this mail >> thread there. > > Right. I have the other patch ready, thanks to your great help. I'm > waiting for Nitin's okay whether / how much info I can copy from the > reference sheet to source code comments. Once I have that confirmation, > I will post the revised patch. > >> <snip> >> >>> Finally, I mentioned some open ends already on a post to ibm-acpi-devel >>> at https://sourceforge.net/p/ibm-acpi/mailman/message/37200082/; this >>> very question is among them. >>> I will start tackling the SW_TABLET_MODE event issue first, but if Mark >>> and Nitin can already hint about the keyboard shortcuts, it'd be highly >>> appreciated. >> >> I think I might be able to help there, a couple of months ago I bought >> a second-hand thinkpad-10 tablet which also has a USB attached keyboard. >> >> In hindsight I guess I could have asked Mark and Nitin for some more info, >> but I went on autopilot and just ran hexdump -C on the /dev/hidraw node >> to see which events all the keys send. >> >> And I fired up an usb-sniffer under Windows to figure out the audio-leds, >> since I'm used to just figure these things out without help from the vendor :) > > Yeah, why take the boring route if you know how to do all the work on > your own... ;-) > >> See the recent commits here for my work on this: >> >> https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/log/drivers/hid/hid-lenovo.c > > Thanks, very helpful. > >> So on the ibm-acpi list message you said that the kbd sends the following: >> >> type 4 (EV_MSC), code 4 (MSC_SCAN), value c0001 >> type 1 (EV_KEY), code 240 (KEY_UNKNOWN), value 1 >> >> For the Fn-keys, does it send the same MSC_SCAN code for *all* the >> non-working Fn-keys ? > > Correct. And I can confirm that /dev/hidraw1 lets me distinguish between > the keys. > >> If so then it seems that this is very much like the thinkpad 10 kbd dock >> which also does this, see the lenovo_input_mapping_tp10_ultrabook_kbd() >> function in drivers/hid/hid-lenovo.c . >> >> If I have that right, then I think we should be able to get the >> Fn keys to work without too much trouble. You could try hacking up >> drivers/hid/hid-lenovo.c a bit: > > (Not yet there, but will investigate.) > >> 1. Add an entry to the lenovo_devices array like this: >> >> /* >> * Note bind to the HID_GROUP_GENERIC group, so that we only bind to the keyboard part, >> * while letting hid-multitouch.c handle the touchpad and trackpoint. >> */ >> { HID_DEVICE(BUS_USB, HID_GROUP_GENERIC, >> USB_VENDOR_ID_LENOVO, >> USB_DEVICE_ID_LENOVO_X1_TAB), >> >> 2. Add the following entry to the switch-case in lenovo_input_mapping() : >> >> case USB_DEVICE_ID_LENOVO_X1_TAB: >> return lenovo_input_mapping_tp10_ultrabook_kbd(hdev, hi, field, >> usage, bit, max); >> >> And then build hid-lenovo.c and modprobe it. >> >> After the modprobe to: >> >> ls -l /sys/bus/hid/devices/0003:17EF:60A3.*/driver >> >> This should show 2 devices (I guess) with one being bound to hid-lenovo >> and 1 being bound to hid-multitouch. > > So far (without patching hid-lenovo), 2 bound to hid-generic and 1 to > hid-multitouch. Ok, so it seems that they kept the thinkpad 10 kbd bits (mostly) with 1 keyboard interface using the usb boot kbd interface (so that it will also work inside the BIOS) and a second interface for multimedia-keys + the mouse emulation of the thinkpad 10 touchpad, those are interfaces 1 and 2, except that they removed the mouse emulation as they added a new proper multi-touch capable touchpad as interface 3; and that one also handles the pointing stick I believe. So yes 2 bound to hid-generic, 1 bound to hid-multitouch seems to be correct. >> If this works some of your Fn + F# keys will now hopefully start doing >> something, you can play around with modifying lenovo_input_mapping_tp10_ultrabook_kbd >> to make it do the right thing for your kbd. >>z >> ### >> >> About LED support, just enabling the LED support bits for the >> USB_DEVICE_ID_LENOVO_TP10UBKBD handling for now might work fine, >> but there is a tiny chance that sending the wrong command somehow puts >> the kbd in firmware update mode, I had that happen once with a Logitech >> kbd which did not seem to have any kind of handshake / passcode to avoid >> accidental fw updates (*). >> >> If you can give me a dump of the hid-descriptors for your keyboard, >> then I can check if that the LEDs might work the same way too (or not). >> >> The easiest way to get a dump is to run the following command as root: >> >> cat /sys/kernel/debug/hid/0003:17EF:60A3.*/rdesc > rdesc >> >> And then attach rdesc to your next email. > > Please find this one attached already now. > In case it helps, the * expands to 0057 0058 0059 on my system. Ok, so there still is an output-report number 9 on the second interface, which probably still controls the LEDS but its descriptors are subtly different. Although different in a good way I guess because the thinkpad 10 dock descriptor describes the 2 bytes in the output report as being in the range of 0-1 which is not how they are actually used. So I think that the code for the Thinkpad 10 ultrabook keyboard as Lenovo calls it, should also work on the X1 tablet thin keyboard. I've prepared a set of patches which enable the tp10ubkbd code on the X1 tablet thin keyboard. But beware as mentioned before there is a tiny chance that sending the wrong command somehow puts the kbd in firmware update mode. I believe that trying the tp10ubkbd code is safe, esp. since this is using a 2 byte large output report and using that for fw-updating would be a bit weird. Still there is a small risk (there always is when poking hw) so I will leave it up to you if you are willing to try this. Here is how I test this (note you will need to adjust the paths a bit) : Toggle the 2 mute LEDs: [root@localhost ~]# echo 1 > /sys/class/leds/0003:17EF:6062.000E:amber:micmute/brightness [root@localhost ~]# echo 0 > /sys/class/leds/0003:17EF:6062.000E:amber:micmute/brightness [root@localhost ~]# echo 1 > /sys/class/leds/0003:17EF:6062.000E:amber:mute/brightness [root@localhost ~]# echo 0 > /sys/class/leds/0003:17EF:6062.000E:amber:mute/brightness Check Fnlock LED state (toggle on kbd by pressing Fn + Esc) : [root@localhost ~]# cat /sys/bus/hid/devices/0003:17EF:6062.000E/fn_lock 1 [root@localhost ~]# cat /sys/bus/hid/devices/0003:17EF:6062.000E/fn_lock 0 Change Fnlock state from within Linux: [root@localhost ~]# echo 1 > /sys/bus/hid/devices/0003:17EF:6062.000E/fn_lock [root@localhost ~]# echo 0 > /sys/bus/hid/devices/0003:17EF:6062.000E/fn_lock (The Led on the kbd should update; and the F## key behavior should change) Regards, Hans [-- Attachment #2: 0001-HID-lenovo-Fix-false-positive-errors-on-setting-tp10.patch --] [-- Type: text/x-patch, Size: 1228 bytes --] From 44311c907697180046648736dc82b34e8ab5beaf Mon Sep 17 00:00:00 2001 From: Hans de Goede <hdegoede@redhat.com> Date: Thu, 11 Feb 2021 23:14:20 +0100 Subject: [PATCH 1/5] HID: lenovo: Fix false positive errors on setting tp10ubkbd LEDs Fix the error check in lenovo_led_set_tp10ubkbd(), on success hid_hw_raw_request() returns the number of bytes send. So we should check for (ret != 3) rather then for (ret != 0). Fixes: bc04b37ea0ec ("HID: lenovo: Add ThinkPad 10 Ultrabook Keyboard support") Signed-off-by: Hans de Goede <hdegoede@redhat.com> --- drivers/hid/hid-lenovo.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/hid/hid-lenovo.c b/drivers/hid/hid-lenovo.c index c6c8e20f3e8d..69d709439676 100644 --- a/drivers/hid/hid-lenovo.c +++ b/drivers/hid/hid-lenovo.c @@ -75,7 +75,7 @@ static void lenovo_led_set_tp10ubkbd(struct hid_device *hdev, u8 led_code, data->led_report[2] = value ? TP10UBKBD_LED_ON : TP10UBKBD_LED_OFF; ret = hid_hw_raw_request(hdev, data->led_report[0], data->led_report, 3, HID_OUTPUT_REPORT, HID_REQ_SET_REPORT); - if (ret) + if (ret != 3) hid_err(hdev, "Set LED output report error: %d\n", ret); mutex_unlock(&data->led_report_mutex); -- 2.30.1 [-- Attachment #3: 0002-HID-lenovo-Check-hid_get_drvdata-returns-non-NULL-in.patch --] [-- Type: text/x-patch, Size: 1404 bytes --] From c24649efa10189d49b87a19b6a999ccfa8987801 Mon Sep 17 00:00:00 2001 From: Hans de Goede <hdegoede@redhat.com> Date: Thu, 11 Feb 2021 23:41:53 +0100 Subject: [PATCH 2/5] HID: lenovo: Check hid_get_drvdata() returns non NULL in lenovo_event() The HID lenovo probe function only attaches drvdata to one of the USB interfaces, but lenovo_event() will get called for all USB interfaces to which hid-lenovo is bound. This allows a malicious device to fake being a device handled by hid-lenovo, which generates events for which lenovo_event() has special handling (and thus dereferences hid_get_drvdata()) on another interface triggering a NULL pointer exception. Add a check for hid_get_drvdata() returning NULL, avoiding this possible NULL pointer exception. Signed-off-by: Hans de Goede <hdegoede@redhat.com> --- drivers/hid/hid-lenovo.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/hid/hid-lenovo.c b/drivers/hid/hid-lenovo.c index 69d709439676..8a040f6040eb 100644 --- a/drivers/hid/hid-lenovo.c +++ b/drivers/hid/hid-lenovo.c @@ -498,6 +498,9 @@ static int lenovo_event_cptkbd(struct hid_device *hdev, static int lenovo_event(struct hid_device *hdev, struct hid_field *field, struct hid_usage *usage, __s32 value) { + if (!hid_get_drvdata(hdev)) + return 0; + switch (hdev->product) { case USB_DEVICE_ID_LENOVO_CUSBKBD: case USB_DEVICE_ID_LENOVO_CBTKBD: -- 2.30.1 [-- Attachment #4: 0003-HID-lenovo-Set-default_trigger-s-for-the-mute-and-mi.patch --] [-- Type: text/x-patch, Size: 1705 bytes --] From 0fde88dac366cca64fd38b4303b329adfec643ef Mon Sep 17 00:00:00 2001 From: Hans de Goede <hdegoede@redhat.com> Date: Thu, 11 Feb 2021 23:21:39 +0100 Subject: [PATCH 3/5] HID: lenovo: Set default_trigger-s for the mute and micmute LEDs The mute and mic-mute LEDs should be automatically turned on/off based on the audio-cards mixer settings. Add the standardized default-trigger names for this, so that the alsa code can turn the LEDs on/off as appropriate (on supported audo cards). This brings the mute/mic-mute LED support inline with the thinkpad_acpi support for the same LEDs in keyboards directly connected to the laptop's embedded-controller. Signed-off-by: Hans de Goede <hdegoede@redhat.com> --- drivers/hid/hid-lenovo.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/hid/hid-lenovo.c b/drivers/hid/hid-lenovo.c index 8a040f6040eb..c4cd4f69cdfd 100644 --- a/drivers/hid/hid-lenovo.c +++ b/drivers/hid/hid-lenovo.c @@ -824,6 +824,7 @@ static int lenovo_register_leds(struct hid_device *hdev) snprintf(name_micm, name_sz, "%s:amber:micmute", dev_name(&hdev->dev)); data->led_mute.name = name_mute; + data->led_mute.default_trigger = "audio-mute"; data->led_mute.brightness_get = lenovo_led_brightness_get; data->led_mute.brightness_set = lenovo_led_brightness_set; data->led_mute.dev = &hdev->dev; @@ -832,6 +833,7 @@ static int lenovo_register_leds(struct hid_device *hdev) return ret; data->led_micmute.name = name_micm; + data->led_micmute.default_trigger = "audio-micmute"; data->led_micmute.brightness_get = lenovo_led_brightness_get; data->led_micmute.brightness_set = lenovo_led_brightness_set; data->led_micmute.dev = &hdev->dev; -- 2.30.1 [-- Attachment #5: 0004-HID-lenovo-Rework-how-the-tp10ubkbd-code-decides-whi.patch --] [-- Type: text/x-patch, Size: 1809 bytes --] From 7f03da5567b810f1b3790674a0fb34db4866ceca Mon Sep 17 00:00:00 2001 From: Hans de Goede <hdegoede@redhat.com> Date: Thu, 11 Feb 2021 23:10:27 +0100 Subject: [PATCH 4/5] HID: lenovo: Rework how the tp10ubkbd code decides which USB interface to use Instead of looking for a hdev with a type of HID_TYPE_USBMOUSE find the interface for the mute/mic-mute/fn-lock LEDs by checking for the output-report which is used to set them. This is a preparation patch for adding support for the LEDs on the X1 tablet thin keyboard which uses the same output-report, but has a separate (third) USB interface for the touchpad/mouse functionality. Signed-off-by: Hans de Goede <hdegoede@redhat.com> --- drivers/hid/hid-lenovo.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/drivers/hid/hid-lenovo.c b/drivers/hid/hid-lenovo.c index c4cd4f69cdfd..33033b74b434 100644 --- a/drivers/hid/hid-lenovo.c +++ b/drivers/hid/hid-lenovo.c @@ -957,11 +957,24 @@ static const struct attribute_group lenovo_attr_group_tp10ubkbd = { static int lenovo_probe_tp10ubkbd(struct hid_device *hdev) { + struct hid_report_enum *rep_enum; struct lenovo_drvdata *data; + struct hid_report *rep; + bool found; int ret; - /* All the custom action happens on the USBMOUSE device for USB */ - if (hdev->type != HID_TYPE_USBMOUSE) + /* + * The LEDs and the Fn-lock functionality use output report 9, + * with an application of 0xffa0001, add the LEDs on the interface + * with this output report. + */ + found = false; + rep_enum = &hdev->report_enum[HID_OUTPUT_REPORT]; + list_for_each_entry(rep, &rep_enum->report_list, list) { + if (rep->application == 0xffa00001) + found = true; + } + if (!found) return 0; data = devm_kzalloc(&hdev->dev, sizeof(*data), GFP_KERNEL); -- 2.30.1 [-- Attachment #6: 0005-HID-lenovo-WIP-Add-support-for-Thinkpad-X1-Tablet-Th.patch --] [-- Type: text/x-patch, Size: 4339 bytes --] From 44a8670e26c6cb57c03c26d0476f813a2856434f Mon Sep 17 00:00:00 2001 From: Hans de Goede <hdegoede@redhat.com> Date: Thu, 11 Feb 2021 23:40:11 +0100 Subject: [PATCH 5/5] HID: lenovo: WIP: Add support for Thinkpad X1 Tablet Thin keyboard WIP: untested and the key mappings in lenovo_input_mapping_x1_tab_kbd() need work. Signed-off-by: Hans de Goede <hdegoede@redhat.com> --- drivers/hid/hid-lenovo.c | 46 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/drivers/hid/hid-lenovo.c b/drivers/hid/hid-lenovo.c index 33033b74b434..9a628e7a2382 100644 --- a/drivers/hid/hid-lenovo.c +++ b/drivers/hid/hid-lenovo.c @@ -255,6 +255,39 @@ static int lenovo_input_mapping_tp10_ultrabook_kbd(struct hid_device *hdev, return 0; } +static int lenovo_input_mapping_x1_tab_kbd(struct hid_device *hdev, + struct hid_input *hi, struct hid_field *field, + struct hid_usage *usage, unsigned long **bit, int *max) +{ + /* + * The ThinkPad X1 Tablet Thin Keyboard uses 0x000c0001 usage for + * a bunch of keys which have no standard consumer page code. + */ + // FIXME the below mappings are taken for the tp10_ultrabook_kbd mapping function + // these may very well need to be changed for the X1 Tablet Thin Keyboard + if (usage->hid == 0x000c0001) { + switch (usage->usage_index) { + case 8: /* Fn-Esc: Fn-lock toggle */ + map_key_clear(KEY_FN_ESC); + return 1; + case 9: /* Fn-F4: Mic mute */ + map_key_clear(KEY_MICMUTE); + return 1; + case 10: /* Fn-F7: Control panel */ + map_key_clear(KEY_CONFIG); + return 1; + case 11: /* Fn-F8: Search (magnifier glass) */ + map_key_clear(KEY_SEARCH); + return 1; + case 12: /* Fn-F10: Open My computer (6 boxes) */ + map_key_clear(KEY_FILE); + return 1; + } + } + + return 0; +} + static int lenovo_input_mapping(struct hid_device *hdev, struct hid_input *hi, struct hid_field *field, struct hid_usage *usage, unsigned long **bit, int *max) @@ -278,6 +311,8 @@ static int lenovo_input_mapping(struct hid_device *hdev, case USB_DEVICE_ID_LENOVO_TP10UBKBD: return lenovo_input_mapping_tp10_ultrabook_kbd(hdev, hi, field, usage, bit, max); + case USB_DEVICE_ID_LENOVO_X1_TAB: + return lenovo_input_mapping_x1_tab_kbd(hdev, hi, field, usage, bit, max); default: return 0; } @@ -364,6 +399,7 @@ static ssize_t attr_fn_lock_store(struct device *dev, lenovo_features_set_cptkbd(hdev); break; case USB_DEVICE_ID_LENOVO_TP10UBKBD: + case USB_DEVICE_ID_LENOVO_X1_TAB: lenovo_led_set_tp10ubkbd(hdev, TP10UBKBD_FN_LOCK_LED, value); break; } @@ -506,6 +542,7 @@ static int lenovo_event(struct hid_device *hdev, struct hid_field *field, case USB_DEVICE_ID_LENOVO_CBTKBD: return lenovo_event_cptkbd(hdev, field, usage, value); case USB_DEVICE_ID_LENOVO_TP10UBKBD: + case USB_DEVICE_ID_LENOVO_X1_TAB: return lenovo_event_tp10ubkbd(hdev, field, usage, value); default: return 0; @@ -802,6 +839,7 @@ static void lenovo_led_brightness_set(struct led_classdev *led_cdev, lenovo_led_set_tpkbd(hdev); break; case USB_DEVICE_ID_LENOVO_TP10UBKBD: + case USB_DEVICE_ID_LENOVO_X1_TAB: lenovo_led_set_tp10ubkbd(hdev, tp10ubkbd_led[led_nr], value); break; } @@ -1036,6 +1074,7 @@ static int lenovo_probe(struct hid_device *hdev, ret = lenovo_probe_cptkbd(hdev); break; case USB_DEVICE_ID_LENOVO_TP10UBKBD: + case USB_DEVICE_ID_LENOVO_X1_TAB: ret = lenovo_probe_tp10ubkbd(hdev); break; default: @@ -1101,6 +1140,7 @@ static void lenovo_remove(struct hid_device *hdev) lenovo_remove_cptkbd(hdev); break; case USB_DEVICE_ID_LENOVO_TP10UBKBD: + case USB_DEVICE_ID_LENOVO_X1_TAB: lenovo_remove_tp10ubkbd(hdev); break; } @@ -1140,6 +1180,12 @@ static const struct hid_device_id lenovo_devices[] = { { HID_USB_DEVICE(USB_VENDOR_ID_IBM, USB_DEVICE_ID_IBM_SCROLLPOINT_800DPI_OPTICAL_PRO) }, { HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_SCROLLPOINT_OPTICAL) }, { HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_TP10UBKBD) }, + /* + * Note bind to the HID_GROUP_GENERIC group, so that we only bind to the keyboard + * part, while letting hid-multitouch.c handle the touchpad and trackpoint. + */ + { HID_DEVICE(BUS_USB, HID_GROUP_GENERIC, + USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_X1_TAB) }, { } }; -- 2.30.1 ^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: Support for X1 tablet keyboard (was Re: [PATCH] platform/x86: thinkpad_acpi: handle HKEY 0x4012, 0x4013 events) 2021-02-11 23:42 ` Hans de Goede @ 2021-02-21 13:17 ` Alexander Kobel 2021-02-21 16:30 ` Hans de Goede 0 siblings, 1 reply; 9+ messages in thread From: Alexander Kobel @ 2021-02-21 13:17 UTC (permalink / raw) To: Hans de Goede, platform-driver-x86, Mark Pearson, Nitin Joshi1 Cc: linux-input [-- Attachment #1.1: Type: text/plain, Size: 10421 bytes --] Hi, finally I got to investigate that patch. Thanks for your draft and explanations! On 2/12/21 12:42 AM, Hans de Goede wrote: > Hi, > > On 2/9/21 4:16 PM, Alexander Kobel wrote: >> Hi, >> >> On 2/8/21 11:17 AM, Hans de Goede wrote: >>> On 2/7/21 6:55 PM, Alexander Kobel wrote: >>>> <snip> >>>> I'll go off and try to improve. >>> >>> So Nitin has been kind enough to provide us with some docs for this, >>> please see me reply to Nitin's email and lets continue this part of this mail >>> thread there. >> >> Right. I have the other patch ready, thanks to your great help. I'm >> waiting for Nitin's okay whether / how much info I can copy from the >> reference sheet to source code comments. Once I have that confirmation, >> I will post the revised patch. >> >>> <snip> >>> >>>> Finally, I mentioned some open ends already on a post to ibm-acpi-devel >>>> at https://sourceforge.net/p/ibm-acpi/mailman/message/37200082/; this >>>> very question is among them. >>>> I will start tackling the SW_TABLET_MODE event issue first, but if Mark >>>> and Nitin can already hint about the keyboard shortcuts, it'd be highly >>>> appreciated. >>> >>> I think I might be able to help there, a couple of months ago I bought >>> a second-hand thinkpad-10 tablet which also has a USB attached keyboard. >>> >>> In hindsight I guess I could have asked Mark and Nitin for some more info, >>> but I went on autopilot and just ran hexdump -C on the /dev/hidraw node >>> to see which events all the keys send. >>> >>> And I fired up an usb-sniffer under Windows to figure out the audio-leds, >>> since I'm used to just figure these things out without help from the vendor :) >> >> Yeah, why take the boring route if you know how to do all the work on >> your own... ;-) >> >>> See the recent commits here for my work on this: >>> >>> https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/log/drivers/hid/hid-lenovo.c >> >> Thanks, very helpful. >> >>> So on the ibm-acpi list message you said that the kbd sends the following: >>> >>> type 4 (EV_MSC), code 4 (MSC_SCAN), value c0001 >>> type 1 (EV_KEY), code 240 (KEY_UNKNOWN), value 1 >>> >>> For the Fn-keys, does it send the same MSC_SCAN code for *all* the >>> non-working Fn-keys ? >> >> Correct. And I can confirm that /dev/hidraw1 lets me distinguish between >> the keys. >> >>> If so then it seems that this is very much like the thinkpad 10 kbd dock >>> which also does this, see the lenovo_input_mapping_tp10_ultrabook_kbd() >>> function in drivers/hid/hid-lenovo.c . >>> >>> If I have that right, then I think we should be able to get the >>> Fn keys to work without too much trouble. You could try hacking up >>> drivers/hid/hid-lenovo.c a bit: >> >> (Not yet there, but will investigate.) >> >>> 1. Add an entry to the lenovo_devices array like this: >>> >>> /* >>> * Note bind to the HID_GROUP_GENERIC group, so that we only bind to the keyboard part, >>> * while letting hid-multitouch.c handle the touchpad and trackpoint. >>> */ >>> { HID_DEVICE(BUS_USB, HID_GROUP_GENERIC, >>> USB_VENDOR_ID_LENOVO, >>> USB_DEVICE_ID_LENOVO_X1_TAB), >>> >>> 2. Add the following entry to the switch-case in lenovo_input_mapping() : >>> >>> case USB_DEVICE_ID_LENOVO_X1_TAB: >>> return lenovo_input_mapping_tp10_ultrabook_kbd(hdev, hi, field, >>> usage, bit, max); >>> >>> And then build hid-lenovo.c and modprobe it. >>> >>> After the modprobe to: >>> >>> ls -l /sys/bus/hid/devices/0003:17EF:60A3.*/driver >>> >>> This should show 2 devices (I guess) with one being bound to hid-lenovo >>> and 1 being bound to hid-multitouch. >> >> So far (without patching hid-lenovo), 2 bound to hid-generic and 1 to >> hid-multitouch. > > Ok, so it seems that they kept the thinkpad 10 kbd bits (mostly) with > 1 keyboard interface using the usb boot kbd interface (so that it will > also work inside the BIOS) and a second interface for multimedia-keys + > the mouse emulation of the thinkpad 10 touchpad, those are interfaces > 1 and 2, except that they removed the mouse emulation as they added a > new proper multi-touch capable touchpad as interface 3; and that one > also handles the pointing stick I believe. > > So yes 2 bound to hid-generic, 1 bound to hid-multitouch seems to be > correct. Right, that's what I observe. >>> If this works some of your Fn + F# keys will now hopefully start doing >>> something, you can play around with modifying lenovo_input_mapping_tp10_ultrabook_kbd >>> to make it do the right thing for your kbd. >>> z >>> ### >>> >>> About LED support, just enabling the LED support bits for the >>> USB_DEVICE_ID_LENOVO_TP10UBKBD handling for now might work fine, >>> but there is a tiny chance that sending the wrong command somehow puts >>> the kbd in firmware update mode, I had that happen once with a Logitech >>> kbd which did not seem to have any kind of handshake / passcode to avoid >>> accidental fw updates (*). >>> >>> If you can give me a dump of the hid-descriptors for your keyboard, >>> then I can check if that the LEDs might work the same way too (or not). >>> >>> The easiest way to get a dump is to run the following command as root: >>> >>> cat /sys/kernel/debug/hid/0003:17EF:60A3.*/rdesc > rdesc >>> >>> And then attach rdesc to your next email. >> >> Please find this one attached already now. >> In case it helps, the * expands to 0057 0058 0059 on my system. > > Ok, so there still is an output-report number 9 on the second interface, > which probably still controls the LEDS but its descriptors are subtly > different. Although different in a good way I guess because the thinkpad > 10 dock descriptor describes the 2 bytes in the output report as being > in the range of 0-1 which is not how they are actually used. > > So I think that the code for the Thinkpad 10 ultrabook keyboard as > Lenovo calls it, should also work on the X1 tablet thin keyboard. Mostly, modulo some key mappings, as expected. The good: LEDs are working exactly as expected with your patch, with the appropriate triggers automatically active. Perfect! The bad: I could adjust some of the key mappings for the X1 Tablet 2nd keyboard. What I couldn't do is to get Fn+F10, Fn+F11, Fn+F12 and Fn+PrtSc to work. Following the logic of /dev/hidraw1 capture (attached), those should be on usage_index 16 to 19. But apparently those are on a different usage page or something like that? Unfortunately, my RTFM skills didn't really help with figuring out how that's supposed to work. (Is looking at the bit indices in /dev/hidraw traces how you figure out those mappings? If there's a better way, I'm eager to be told...) Similarly - I assume - Fn+S should emit SysRq according to https://download.lenovo.com/pccbbs/mobiles_pdf/x1_tablet_gen_2_ug_en.pdf, page 51. This is not on the "consumer control" device, but the usual keyboard, so /dev/hidraw0. Again, couldn't get much further than producing a capture. But I cannot make sense of this one, because way more bits are set, so I cannot extrapolate from your code. The ugly: Fn+4 ("sleep") triggers the appropriate ACPI event button/sleep and emits something on /dev/hidraw0, too, but *only once*. After resuming, no reaction at all (neither on ACPI nor hidraw) until I unload and reload the hid_lenovo module. Finally, keyboard backlight is handled in firmware, apparently; Fn+Space is visible on /dev/hidraw1 (see attached capture), but it toggles the backlight levels without any userspace code involved, as far as I can see. Also, the keyboard backlight doesn't create an entry in /sys/class/backlight or the like, so neither read nor write access. Out-of-the-box, at least. But I'm not even sure if this is possible in Windows. Bottom line: this is mostly usable already, modulo the adjustments for the different keys. I'd like to make F10 to F12 work before it hits testing; everything else is icing on the cake, I suppose. Do you have an hint for me how I can approach that? Also, I'd make sure that this is about the "ThinkPad X1 Tablet Thin Keyboard **Gen 2**". The consumer functions are different for the **Gen 1** keyboard, so I would also adjust the function names. I do have an old Gen 1 keyboard lying around, but unfortunately it's either broken (it lights up shortly after attaching in Windows, but doesn't report keypresses at all, and pretends to be completely dead in Linux), or it's incompatible with my X1 Tablet 2nd Gen. So I cannot test how your patch might impact the Gen1, too... :-/ > I've prepared a set of patches which enable the tp10ubkbd code on > the X1 tablet thin keyboard. But beware as mentioned before there is a > tiny chance that sending the wrong command somehow puts the kbd in > firmware update mode. I believe that trying the tp10ubkbd code is safe, > esp. since this is using a 2 byte large output report and using that > for fw-updating would be a bit weird. Still there is a small risk > (there always is when poking hw) so I will leave it up to you if > you are willing to try this. No issue at all, and everything below works just as expected. > Here is how I test this (note you will need to adjust the paths a bit) : > > Toggle the 2 mute LEDs: > > [root@localhost ~]# echo 1 > /sys/class/leds/0003:17EF:6062.000E:amber:micmute/brightness > [root@localhost ~]# echo 0 > /sys/class/leds/0003:17EF:6062.000E:amber:micmute/brightness > [root@localhost ~]# echo 1 > /sys/class/leds/0003:17EF:6062.000E:amber:mute/brightness > [root@localhost ~]# echo 0 > /sys/class/leds/0003:17EF:6062.000E:amber:mute/brightness > > Check Fnlock LED state (toggle on kbd by pressing Fn + Esc) : > > [root@localhost ~]# cat /sys/bus/hid/devices/0003:17EF:6062.000E/fn_lock > 1 > [root@localhost ~]# cat /sys/bus/hid/devices/0003:17EF:6062.000E/fn_lock > 0 > > Change Fnlock state from within Linux: > > [root@localhost ~]# echo 1 > /sys/bus/hid/devices/0003:17EF:6062.000E/fn_lock > [root@localhost ~]# echo 0 > /sys/bus/hid/devices/0003:17EF:6062.000E/fn_lock > > (The Led on the kbd should update; and the F## key behavior should change) > > Regards, > > Hans Cheers, Alex [-- Attachment #1.2: hidrawscan0 --] [-- Type: text/plain, Size: 752 bytes --] # echo 'Fn + [ s, 4 ]'; sleep 1; sudo xxd -b -c4 /dev/hidraw0 Fn + [ s, 4 ] # Fn+S should be SysRq Fn+S press: 00000000: 00000000 00000000 10011010 00000000 .... 00000004: 00000000 00000000 00000000 00000000 .... Fn+S release: 00000008: 00000000 00000000 00000000 00000000 .... 0000000c: 00000000 00000000 00000000 00000000 .... # Fn+4 should be "sleep" Fn+4 press: 00000000: 00000000 00000000 01110010 00000000 ..r. 00000004: 00000000 00000000 00000000 00000000 .... Fn+4 release: 00000008: 00000000 00000000 00000000 00000000 .... 0000000c: 00000000 00000000 00000000 00000000 .... # subsequent presses of Fn+4 do not report anything # until hid_lenovo is removed and re-inserted [-- Attachment #1.3: hidrawscan1 --] [-- Type: text/plain, Size: 2343 bytes --] # echo 'Fn + [ FnLock, F1, ..., F12, PrtSc, Space, Space, Space, Space ]'; xxd -b -c4 /dev/hidraw1 Fn + [ FnLock, F1, ..., F12, PrtSc, Space, Space, Space, Space ] FnLock Press: 00000000: 00000011 00000000 00000001 00000000 .... FnLock Release: 00000004: 00000011 00000000 00000000 00000000 .... F1 Press: 00000008: 00000011 00100000 00000000 00000000 . .. F1 Release: 0000000c: 00000011 00000000 00000000 00000000 .... F2 Press: 00000010: 00000011 00000000 00000000 00010000 .... F2 Release: 00000014: 00000011 00000000 00000000 00000000 .... F3 Press: 00000018: 00000011 00000000 00000000 00100000 ... F3 Release: 0000001c: 00000011 00000000 00000000 00000000 .... F4 Press: 00000020: 00000011 00000000 00000010 00000000 .... F4 Release: 00000024: 00000011 00000000 00000000 00000000 .... F5 Press: 00000028: 00000011 00000000 00000000 01000000 ...@ F5 Release: 0000002c: 00000011 00000000 00000000 00000000 .... F6 Press: 00000030: 00000011 00000000 00000000 00001000 .... F6 Release: 00000034: 00000011 00000000 00000000 00000000 .... F7 Press: 00000038: 00000011 00000000 00100000 00000000 .. . F7 Release: 0000003c: 00000011 00000000 00000000 00000000 .... F8 Press: 00000040: 00000011 00000000 01000000 00000000 ..@. F8 Release: 00000044: 00000011 00000000 00000000 00000000 .... F9 Press: 00000048: 00000011 00000000 00000100 00000000 .... F9 Release: 0000004c: 00000011 00000000 00000000 00000000 .... F10 Press: 00000050: 00000011 00000001 00000000 00000000 .... F10 Release: 00000054: 00000011 00000000 00000000 00000000 .... F11 Press: 00000058: 00000011 00000010 00000000 00000000 .... F11 Release: 0000005c: 00000011 00000000 00000000 00000000 .... F12 Press: 00000060: 00000011 00000100 00000000 00000000 .... F12 Release: 00000064: 00000011 00000000 00000000 00000000 .... PrtSc Press: 00000068: 00000011 00001000 00000000 00000000 .... PrtSc Release: 0000006c: 00000011 00000000 00000000 00000000 .... Space Press: 00000070: 00000011 00000000 10010000 00000001 .... Space Press: 00000074: 00000011 00000000 10010000 00000001 .... Space Press: 00000078: 00000011 00000000 10010000 00000001 .... Space Press: 0000007c: 00000011 00000000 10010000 00000001 .... [-- Attachment #1.4: lenovo_input_mapping_x1_tab_kbd.c --] [-- Type: text/x-csrc, Size: 1453 bytes --] static int lenovo_input_mapping_x1_tab_kbd(struct hid_device *hdev, struct hid_input *hi, struct hid_field *field, struct hid_usage *usage, unsigned long **bit, int *max) { /* * The ThinkPad X1 Tablet Thin Keyboard uses 0x000c0001 usage for * a bunch of keys which have no standard consumer page code. */ // FIXME the below mappings are taken for the tp10_ultrabook_kbd mapping function // these may very well need to be changed for the X1 Tablet Thin Keyboard if (usage->hid == 0x000c0001) { switch (usage->usage_index) { case 8: /* Fn-Esc: Fn-lock toggle */ map_key_clear(KEY_FN_ESC); return 1; case 9: /* Fn-F4: Mute/unmute microphone */ map_key_clear(KEY_MICMUTE); return 1; case 10: /* Fn-F9: Settings */ map_key_clear(KEY_CONFIG); return 1; case 13: /* Fn-F7: Manage external displays */ map_key_clear(KEY_SWITCHVIDEOMODE); return 1; case 14: /* Fn-F8: Enable/disable wifi */ map_key_clear(KEY_WLAN); return 1; /* FIXME: cases 16-19 don't work */ case 16: /* Fn-F10: Enable/disable bluetooth */ map_key_clear(KEY_BLUETOOTH); return 1; case 17: /* Fn-F11: Keyboard settings */ map_key_clear(KEY_KEYBOARD); return 1; case 18: /* Fn-F12: User function / Cortana */ map_key_clear(KEY_MACRO1); return 1; case 19: /* Fn-PrtSc: Snipping tool */ map_key_clear(KEY_SELECTIVE_SCREENSHOT); return 1; } } return 0; } [-- Attachment #2: S/MIME Cryptographic Signature --] [-- Type: application/pkcs7-signature, Size: 5916 bytes --] ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Support for X1 tablet keyboard (was Re: [PATCH] platform/x86: thinkpad_acpi: handle HKEY 0x4012, 0x4013 events) 2021-02-21 13:17 ` Alexander Kobel @ 2021-02-21 16:30 ` Hans de Goede 2021-02-22 12:31 ` Alexander Kobel 0 siblings, 1 reply; 9+ messages in thread From: Hans de Goede @ 2021-02-21 16:30 UTC (permalink / raw) To: Alexander Kobel, platform-driver-x86, Mark Pearson, Nitin Joshi1 Cc: linux-input Hi, On 2/21/21 2:17 PM, Alexander Kobel wrote: > Hi, > > finally I got to investigate that patch. Thanks for your draft and explanations! > > On 2/12/21 12:42 AM, Hans de Goede wrote: >> Hi, >> >> On 2/9/21 4:16 PM, Alexander Kobel wrote: >>> Hi, >>> >>> On 2/8/21 11:17 AM, Hans de Goede wrote: >>>> On 2/7/21 6:55 PM, Alexander Kobel wrote: >>>>> <snip> >>>>> I'll go off and try to improve. >>>> >>>> So Nitin has been kind enough to provide us with some docs for this, >>>> please see me reply to Nitin's email and lets continue this part of this mail >>>> thread there. >>> >>> Right. I have the other patch ready, thanks to your great help. I'm >>> waiting for Nitin's okay whether / how much info I can copy from the >>> reference sheet to source code comments. Once I have that confirmation, >>> I will post the revised patch. >>> >>>> <snip> >>>> >>>>> Finally, I mentioned some open ends already on a post to ibm-acpi-devel >>>>> at https://sourceforge.net/p/ibm-acpi/mailman/message/37200082/; this >>>>> very question is among them. >>>>> I will start tackling the SW_TABLET_MODE event issue first, but if Mark >>>>> and Nitin can already hint about the keyboard shortcuts, it'd be highly >>>>> appreciated. >>>> >>>> I think I might be able to help there, a couple of months ago I bought >>>> a second-hand thinkpad-10 tablet which also has a USB attached keyboard. >>>> >>>> In hindsight I guess I could have asked Mark and Nitin for some more info, >>>> but I went on autopilot and just ran hexdump -C on the /dev/hidraw node >>>> to see which events all the keys send. >>>> >>>> And I fired up an usb-sniffer under Windows to figure out the audio-leds, >>>> since I'm used to just figure these things out without help from the vendor :) >>> >>> Yeah, why take the boring route if you know how to do all the work on >>> your own... ;-) >>> >>>> See the recent commits here for my work on this: >>>> >>>> https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/log/drivers/hid/hid-lenovo.c >>> >>> Thanks, very helpful. >>> >>>> So on the ibm-acpi list message you said that the kbd sends the following: >>>> >>>> type 4 (EV_MSC), code 4 (MSC_SCAN), value c0001 >>>> type 1 (EV_KEY), code 240 (KEY_UNKNOWN), value 1 >>>> >>>> For the Fn-keys, does it send the same MSC_SCAN code for *all* the >>>> non-working Fn-keys ? >>> >>> Correct. And I can confirm that /dev/hidraw1 lets me distinguish between >>> the keys. >>> >>>> If so then it seems that this is very much like the thinkpad 10 kbd dock >>>> which also does this, see the lenovo_input_mapping_tp10_ultrabook_kbd() >>>> function in drivers/hid/hid-lenovo.c . >>>> >>>> If I have that right, then I think we should be able to get the >>>> Fn keys to work without too much trouble. You could try hacking up >>>> drivers/hid/hid-lenovo.c a bit: >>> >>> (Not yet there, but will investigate.) >>> >>>> 1. Add an entry to the lenovo_devices array like this: >>>> >>>> /* >>>> * Note bind to the HID_GROUP_GENERIC group, so that we only bind to the keyboard part, >>>> * while letting hid-multitouch.c handle the touchpad and trackpoint. >>>> */ >>>> { HID_DEVICE(BUS_USB, HID_GROUP_GENERIC, >>>> USB_VENDOR_ID_LENOVO, >>>> USB_DEVICE_ID_LENOVO_X1_TAB), >>>> >>>> 2. Add the following entry to the switch-case in lenovo_input_mapping() : >>>> >>>> case USB_DEVICE_ID_LENOVO_X1_TAB: >>>> return lenovo_input_mapping_tp10_ultrabook_kbd(hdev, hi, field, >>>> usage, bit, max); >>>> >>>> And then build hid-lenovo.c and modprobe it. >>>> >>>> After the modprobe to: >>>> >>>> ls -l /sys/bus/hid/devices/0003:17EF:60A3.*/driver >>>> >>>> This should show 2 devices (I guess) with one being bound to hid-lenovo >>>> and 1 being bound to hid-multitouch. >>> >>> So far (without patching hid-lenovo), 2 bound to hid-generic and 1 to >>> hid-multitouch. >> >> Ok, so it seems that they kept the thinkpad 10 kbd bits (mostly) with >> 1 keyboard interface using the usb boot kbd interface (so that it will >> also work inside the BIOS) and a second interface for multimedia-keys + >> the mouse emulation of the thinkpad 10 touchpad, those are interfaces >> 1 and 2, except that they removed the mouse emulation as they added a >> new proper multi-touch capable touchpad as interface 3; and that one >> also handles the pointing stick I believe. >> >> So yes 2 bound to hid-generic, 1 bound to hid-multitouch seems to be >> correct. > > Right, that's what I observe. > >>>> If this works some of your Fn + F# keys will now hopefully start doing >>>> something, you can play around with modifying lenovo_input_mapping_tp10_ultrabook_kbd >>>> to make it do the right thing for your kbd. >>>> z >>>> ### >>>> >>>> About LED support, just enabling the LED support bits for the >>>> USB_DEVICE_ID_LENOVO_TP10UBKBD handling for now might work fine, >>>> but there is a tiny chance that sending the wrong command somehow puts >>>> the kbd in firmware update mode, I had that happen once with a Logitech >>>> kbd which did not seem to have any kind of handshake / passcode to avoid >>>> accidental fw updates (*). >>>> >>>> If you can give me a dump of the hid-descriptors for your keyboard, >>>> then I can check if that the LEDs might work the same way too (or not). >>>> >>>> The easiest way to get a dump is to run the following command as root: >>>> >>>> cat /sys/kernel/debug/hid/0003:17EF:60A3.*/rdesc > rdesc >>>> >>>> And then attach rdesc to your next email. >>> >>> Please find this one attached already now. >>> In case it helps, the * expands to 0057 0058 0059 on my system. >> >> Ok, so there still is an output-report number 9 on the second interface, >> which probably still controls the LEDS but its descriptors are subtly >> different. Although different in a good way I guess because the thinkpad >> 10 dock descriptor describes the 2 bytes in the output report as being >> in the range of 0-1 which is not how they are actually used. >> >> So I think that the code for the Thinkpad 10 ultrabook keyboard as >> Lenovo calls it, should also work on the X1 tablet thin keyboard. > > Mostly, modulo some key mappings, as expected. > > The good: > > LEDs are working exactly as expected with your patch, with the appropriate triggers automatically active. Perfect! Good :) > The bad: > > I could adjust some of the key mappings for the X1 Tablet 2nd keyboard. What I couldn't do is to get Fn+F10, Fn+F11, Fn+F12 and Fn+PrtSc to work. > Following the logic of /dev/hidraw1 capture (attached), those should be on usage_index 16 to 19. But apparently those are on a different usage page or something like that? Unfortunately, my RTFM skills didn't really help with figuring out how that's supposed to work. > (Is looking at the bit indices in /dev/hidraw traces how you figure out those mappings? If there's a better way, I'm eager to be told...) You are swapping to low and high byte of the 3 data bytes in the report. Here is an annotated part of the descriptors to explain better: INPUT(3)[INPUT] Field(0) Application(Consumer.0001) Usage(24) 0 Consumer.0001 F10 00000001 00000000 00000000 1 Consumer.0001 F11 00000010 00000000 00000000 2 Consumer.0001 F12 00000100 00000000 00000000 3 Consumer.0001 Prt 00001000 00000000 00000000 4 Consumer.0001 5 Consumer.00e2 F1 00100000 00000000 00000000 6 Consumer.0001 7 Consumer.0001 8 Consumer.0001 ESC 00000000 00000001 00000000 9 Consumer.0001 F4 00000000 00000010 00000000 10 Consumer.0001 F9 00000000 00000100 00000000 11 Consumer.00b7 12 Consumer.0001 13 Consumer.0001 F7 00000000 00100000 00000000 14 Consumer.0001 F8 00000000 01000000 00000000 15 Consumer.0001 16 Consumer.0001 17 Consumer.0001 18 Consumer.0001 19 Consumer.006f F6 00000000 00000000 00001000 20 Consumer.00ea F2 00000000 00000000 00010000 21 Consumer.00e9 F3 00000000 00000000 00100000 22 Consumer.0070 F5 00000000 00000000 01000000 23 Consumer.0001 Logical Minimum(0) Logical Maximum(1) Report Size(1) Report Count(24) Report Offset(0) Flags( Variable Absolute ) Notice how the keys with standard codes (which work without mapping) F1 - F3, F5, F6 now all line up with _none_ Consumer.0001 entries. And if you check those codes in drivers/hid/hid-input.c around line 960 you will see the standard mappings line up too. IOW your case 16 needs to be case 0, case 17, case 1, etc. > Similarly - I assume - Fn+S should emit SysRq according to https://download.lenovo.com/pccbbs/mobiles_pdf/x1_tablet_gen_2_ug_en.pdf, page 51. This is not on the "consumer control" device, but the usual keyboard, so /dev/hidraw0. Again, couldn't get much further than producing a capture. But I cannot make sense of this one, because way more bits are set, so I cannot extrapolate from your code. The input report used by the Fn + key "media keys" use a 24 bit report with 1 bit per key. The standard keyboard interface uses 1 byte per pressed key (with a maximum of 6 pressed keys) where the full byte encodes the scancode of the key. Normally SysRq is 0x46 but for some reason your keyboard is sending 0x9a you can map this by adding the following to the mapping function: if (usage->hid == (HID_UP_KEYBOARD | 0x009a)) map_key_clear(KEY_SYSRQ); Likewise for the sleep combo: if (usage->hid == (HID_UP_KEYBOARD | 0x0072)) map_key_clear(KEY_SLEEP); ### Note chances are you have more Fn + 'letter' combinations at least on the thinkpad10 kbd I have: Fn + T -> SysRq Fn + I -> Insert Fn + P -> Pause Fn + S -> Sysrq Fn + K -> ScrollLock Fn + B -> Pause Note these do not need any special mappings on the thinkpad10 kbd and I guess the doubles may have something to do with some non qwerty keymaps. > The ugly: > > Fn+4 ("sleep") triggers the appropriate ACPI event button/sleep and emits something on /dev/hidraw0, too, but *only once*. After resuming, no reaction at all (neither on ACPI nor hidraw) until I unload and reload the hid_lenovo module. As for the sleep key working only once, what happens after a suspend/resume ? I think the key may have some special handling to avoid it sending a second KEY_SLEEP when the user uses it to wakeup the system, to avoid the system immediately going to sleep again when the user tries to wake the system this way. > Finally, keyboard backlight is handled in firmware, apparently; Fn+Space is visible on /dev/hidraw1 (see attached capture), but it toggles the backlight levels without any userspace code involved, as far as I can see. Yes I saw this in your dump, this is really weird because it sets 3 bits at once in the INPUT(3) report. Does it always set the same 3 bits independent of the brightness level ? > Also, the keyboard backlight doesn't create an entry in /sys/class/backlight or the like, so neither read nor write access. Out-of-the-box, at least. But I'm not even sure if this is possible in Windows. Actuallu kbd-backlighting used the /sys/class/leds interface, but yeah that is not support by Linux ATM for this kbd. Yeah, adding support for that (assuming the hw can do it) would definitely require making some USB dumps under Windows (after finding sw which can change it from within the OS under Windows). > Bottom line: this is mostly usable already, modulo the adjustments for the different keys. I'd like to make F10 to F12 work before it hits testing; everything else is icing on the cake, I suppose. Do you have an hint for me how I can approach that? See above, I think we are pretty close to solving this. Note in the mean time I've posted a hid-lenovo patch-series with various improvements related to the LED handling. I'll send you an offlist mail with the latest patches so that you can base any work you do on top of those. > Also, I'd make sure that this is about the "ThinkPad X1 Tablet Thin Keyboard **Gen 2**". The consumer functions are different for the **Gen 1** keyboard, so I would also adjust the function names. I do have an old Gen 1 keyboard lying around, but unfortunately it's either broken (it lights up shortly after attaching in Windows, but doesn't report keypresses at all, and pretends to be completely dead in Linux), or it's incompatible with my X1 Tablet 2nd Gen. So I cannot test how your patch might impact the Gen1, too... :-/ I would expect the Gen1 to have a different product-id, so my patch shouldn't do anything. >> I've prepared a set of patches which enable the tp10ubkbd code on >> the X1 tablet thin keyboard. But beware as mentioned before there is a >> tiny chance that sending the wrong command somehow puts the kbd in >> firmware update mode. I believe that trying the tp10ubkbd code is safe, >> esp. since this is using a 2 byte large output report and using that >> for fw-updating would be a bit weird. Still there is a small risk >> (there always is when poking hw) so I will leave it up to you if >> you are willing to try this. > > No issue at all, and everything below works just as expected. Good. Regards, Hans ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Support for X1 tablet keyboard (was Re: [PATCH] platform/x86: thinkpad_acpi: handle HKEY 0x4012, 0x4013 events) 2021-02-21 16:30 ` Hans de Goede @ 2021-02-22 12:31 ` Alexander Kobel 2021-02-24 21:00 ` Hans de Goede 0 siblings, 1 reply; 9+ messages in thread From: Alexander Kobel @ 2021-02-22 12:31 UTC (permalink / raw) To: Hans de Goede, platform-driver-x86, Mark Pearson, Nitin Joshi1 Cc: linux-input [-- Attachment #1.1: Type: text/plain, Size: 16852 bytes --] Hi, On 2/21/21 5:30 PM, Hans de Goede wrote: > Hi, > > On 2/21/21 2:17 PM, Alexander Kobel wrote: >> Hi, >> >> finally I got to investigate that patch. Thanks for your draft and explanations! >> >> On 2/12/21 12:42 AM, Hans de Goede wrote: >>> Hi, >>> >>> On 2/9/21 4:16 PM, Alexander Kobel wrote: >>>> Hi, >>>> >>>> On 2/8/21 11:17 AM, Hans de Goede wrote: >>>>> On 2/7/21 6:55 PM, Alexander Kobel wrote: >>>>>> <snip> >>>>>> I'll go off and try to improve. >>>>> >>>>> So Nitin has been kind enough to provide us with some docs for this, >>>>> please see me reply to Nitin's email and lets continue this part of this mail >>>>> thread there. >>>> >>>> Right. I have the other patch ready, thanks to your great help. I'm >>>> waiting for Nitin's okay whether / how much info I can copy from the >>>> reference sheet to source code comments. Once I have that confirmation, >>>> I will post the revised patch. >>>> >>>>> <snip> >>>>> >>>>>> Finally, I mentioned some open ends already on a post to ibm-acpi-devel >>>>>> at https://sourceforge.net/p/ibm-acpi/mailman/message/37200082/; this >>>>>> very question is among them. >>>>>> I will start tackling the SW_TABLET_MODE event issue first, but if Mark >>>>>> and Nitin can already hint about the keyboard shortcuts, it'd be highly >>>>>> appreciated. >>>>> >>>>> I think I might be able to help there, a couple of months ago I bought >>>>> a second-hand thinkpad-10 tablet which also has a USB attached keyboard. >>>>> >>>>> In hindsight I guess I could have asked Mark and Nitin for some more info, >>>>> but I went on autopilot and just ran hexdump -C on the /dev/hidraw node >>>>> to see which events all the keys send. >>>>> >>>>> And I fired up an usb-sniffer under Windows to figure out the audio-leds, >>>>> since I'm used to just figure these things out without help from the vendor :) >>>> >>>> Yeah, why take the boring route if you know how to do all the work on >>>> your own... ;-) >>>> >>>>> See the recent commits here for my work on this: >>>>> >>>>> https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/log/drivers/hid/hid-lenovo.c >>>> >>>> Thanks, very helpful. >>>> >>>>> So on the ibm-acpi list message you said that the kbd sends the following: >>>>> >>>>> type 4 (EV_MSC), code 4 (MSC_SCAN), value c0001 >>>>> type 1 (EV_KEY), code 240 (KEY_UNKNOWN), value 1 >>>>> >>>>> For the Fn-keys, does it send the same MSC_SCAN code for *all* the >>>>> non-working Fn-keys ? >>>> >>>> Correct. And I can confirm that /dev/hidraw1 lets me distinguish between >>>> the keys. >>>> >>>>> If so then it seems that this is very much like the thinkpad 10 kbd dock >>>>> which also does this, see the lenovo_input_mapping_tp10_ultrabook_kbd() >>>>> function in drivers/hid/hid-lenovo.c . >>>>> >>>>> If I have that right, then I think we should be able to get the >>>>> Fn keys to work without too much trouble. You could try hacking up >>>>> drivers/hid/hid-lenovo.c a bit: >>>> >>>> (Not yet there, but will investigate.) >>>> >>>>> 1. Add an entry to the lenovo_devices array like this: >>>>> >>>>> /* >>>>> * Note bind to the HID_GROUP_GENERIC group, so that we only bind to the keyboard part, >>>>> * while letting hid-multitouch.c handle the touchpad and trackpoint. >>>>> */ >>>>> { HID_DEVICE(BUS_USB, HID_GROUP_GENERIC, >>>>> USB_VENDOR_ID_LENOVO, >>>>> USB_DEVICE_ID_LENOVO_X1_TAB), >>>>> >>>>> 2. Add the following entry to the switch-case in lenovo_input_mapping() : >>>>> >>>>> case USB_DEVICE_ID_LENOVO_X1_TAB: >>>>> return lenovo_input_mapping_tp10_ultrabook_kbd(hdev, hi, field, >>>>> usage, bit, max); >>>>> >>>>> And then build hid-lenovo.c and modprobe it. >>>>> >>>>> After the modprobe to: >>>>> >>>>> ls -l /sys/bus/hid/devices/0003:17EF:60A3.*/driver >>>>> >>>>> This should show 2 devices (I guess) with one being bound to hid-lenovo >>>>> and 1 being bound to hid-multitouch. >>>> >>>> So far (without patching hid-lenovo), 2 bound to hid-generic and 1 to >>>> hid-multitouch. >>> >>> Ok, so it seems that they kept the thinkpad 10 kbd bits (mostly) with >>> 1 keyboard interface using the usb boot kbd interface (so that it will >>> also work inside the BIOS) and a second interface for multimedia-keys + >>> the mouse emulation of the thinkpad 10 touchpad, those are interfaces >>> 1 and 2, except that they removed the mouse emulation as they added a >>> new proper multi-touch capable touchpad as interface 3; and that one >>> also handles the pointing stick I believe. >>> >>> So yes 2 bound to hid-generic, 1 bound to hid-multitouch seems to be >>> correct. >> >> Right, that's what I observe. >> >>>>> If this works some of your Fn + F# keys will now hopefully start doing >>>>> something, you can play around with modifying lenovo_input_mapping_tp10_ultrabook_kbd >>>>> to make it do the right thing for your kbd. >>>>> z >>>>> ### >>>>> >>>>> About LED support, just enabling the LED support bits for the >>>>> USB_DEVICE_ID_LENOVO_TP10UBKBD handling for now might work fine, >>>>> but there is a tiny chance that sending the wrong command somehow puts >>>>> the kbd in firmware update mode, I had that happen once with a Logitech >>>>> kbd which did not seem to have any kind of handshake / passcode to avoid >>>>> accidental fw updates (*). >>>>> >>>>> If you can give me a dump of the hid-descriptors for your keyboard, >>>>> then I can check if that the LEDs might work the same way too (or not). >>>>> >>>>> The easiest way to get a dump is to run the following command as root: >>>>> >>>>> cat /sys/kernel/debug/hid/0003:17EF:60A3.*/rdesc > rdesc >>>>> >>>>> And then attach rdesc to your next email. >>>> >>>> Please find this one attached already now. >>>> In case it helps, the * expands to 0057 0058 0059 on my system. >>> >>> Ok, so there still is an output-report number 9 on the second interface, >>> which probably still controls the LEDS but its descriptors are subtly >>> different. Although different in a good way I guess because the thinkpad >>> 10 dock descriptor describes the 2 bytes in the output report as being >>> in the range of 0-1 which is not how they are actually used. >>> >>> So I think that the code for the Thinkpad 10 ultrabook keyboard as >>> Lenovo calls it, should also work on the X1 tablet thin keyboard. >> >> Mostly, modulo some key mappings, as expected. >> >> The good: >> >> LEDs are working exactly as expected with your patch, with the appropriate triggers automatically active. Perfect! > > Good :) > >> The bad: >> >> I could adjust some of the key mappings for the X1 Tablet 2nd keyboard. What I couldn't do is to get Fn+F10, Fn+F11, Fn+F12 and Fn+PrtSc to work. >> Following the logic of /dev/hidraw1 capture (attached), those should be on usage_index 16 to 19. But apparently those are on a different usage page or something like that? Unfortunately, my RTFM skills didn't really help with figuring out how that's supposed to work. >> (Is looking at the bit indices in /dev/hidraw traces how you figure out those mappings? If there's a better way, I'm eager to be told...) > > You are swapping to low and high byte of the 3 data bytes in the report. Here is an annotated part of the descriptors to explain better: > > INPUT(3)[INPUT] > Field(0) > Application(Consumer.0001) > Usage(24) > 0 Consumer.0001 F10 00000001 00000000 00000000 > 1 Consumer.0001 F11 00000010 00000000 00000000 > 2 Consumer.0001 F12 00000100 00000000 00000000 > 3 Consumer.0001 Prt 00001000 00000000 00000000 > 4 Consumer.0001 > 5 Consumer.00e2 F1 00100000 00000000 00000000 > 6 Consumer.0001 > 7 Consumer.0001 > 8 Consumer.0001 ESC 00000000 00000001 00000000 > 9 Consumer.0001 F4 00000000 00000010 00000000 > 10 Consumer.0001 F9 00000000 00000100 00000000 > 11 Consumer.00b7 > 12 Consumer.0001 > 13 Consumer.0001 F7 00000000 00100000 00000000 > 14 Consumer.0001 F8 00000000 01000000 00000000 > 15 Consumer.0001 > 16 Consumer.0001 > 17 Consumer.0001 > 18 Consumer.0001 > 19 Consumer.006f F6 00000000 00000000 00001000 > 20 Consumer.00ea F2 00000000 00000000 00010000 > 21 Consumer.00e9 F3 00000000 00000000 00100000 > 22 Consumer.0070 F5 00000000 00000000 01000000 > 23 Consumer.0001 > Logical Minimum(0) > Logical Maximum(1) > Report Size(1) > Report Count(24) > Report Offset(0) > Flags( Variable Absolute ) > > Notice how the keys with standard codes (which work without mapping) > F1 - F3, F5, F6 now all line up with _none_ Consumer.0001 entries. > And if you check those codes in drivers/hid/hid-input.c around > line 960 you will see the standard mappings line up too. > > IOW your case 16 needs to be case 0, case 17, case 1, etc. Gotcha, I suppose. At least on a shallow level... Thanks! And, yes: that works perfectly. >> Similarly - I assume - Fn+S should emit SysRq according to https://download.lenovo.com/pccbbs/mobiles_pdf/x1_tablet_gen_2_ug_en.pdf, page 51. This is not on the "consumer control" device, but the usual keyboard, so /dev/hidraw0. Again, couldn't get much further than producing a capture. But I cannot make sense of this one, because way more bits are set, so I cannot extrapolate from your code. > > The input report used by the Fn + key "media keys" use a 24 bit report > with 1 bit per key. The standard keyboard interface uses 1 byte per > pressed key (with a maximum of 6 pressed keys) where the full byte > encodes the scancode of the key. Normally SysRq is 0x46 but for some > reason your keyboard is sending 0x9a you can map this by adding the following > to the mapping function: > > if (usage->hid == (HID_UP_KEYBOARD | 0x009a)) > map_key_clear(KEY_SYSRQ); And the same here, I think. Works with return 1; after the map_key_clear, see the attached function. > Likewise for the sleep combo: > > if (usage->hid == (HID_UP_KEYBOARD | 0x0072)) > map_key_clear(KEY_SLEEP); This seems unnecessary, as the sleep combo already emits KEY_SLEEP. Which I don't quite get, cause - if I learned correctly how to read the rdesc - sleep should be on 0x0072 should emit F23 (and 0x0078 sleep), but the key produces the 0x0072 pattern according to hidraw. By the way, the Fn+4 for sleep also works in hid-generic, and also just once, see below. > ### > > Note chances are you have more Fn + 'letter' combinations at least on > the thinkpad10 kbd I have: > > Fn + T -> SysRq > Fn + I -> Insert > Fn + P -> Pause > Fn + S -> Sysrq > Fn + K -> ScrollLock > Fn + B -> Pause > > Note these do not need any special mappings on the thinkpad10 kbd and I guess > the doubles may have something to do with some non qwerty keymaps. Not the same on this keyboard. I have Fn + {B,K,P,S,End,4} for {Break,ScrLk,Pause,SysRq,Insert,Sleep}, but only SysRq was missing; the others are available on the "default" device, both with hid-lenovo and hid-generic. >> The ugly: >> >> Fn+4 ("sleep") triggers the appropriate ACPI event button/sleep and emits something on /dev/hidraw0, too, but *only once*. After resuming, no reaction at all (neither on ACPI nor hidraw) until I unload and reload the hid_lenovo module. > > As for the sleep key working only once, what happens after a suspend/resume ? Nothing. At least nothing I can measure (via evtest, libinput debug-events, cat /dev/hidraw*, dmesg, journal, acpi_listen). The key simply doesn't react anymore. Irrespective on how I wake the device. Even irrespective of whether I actually suspend the device or disable the sleep handler altogether, e.g. by systemd-inhibit. In only see the KEY_SLEEP press (no release!) event once until I reload the module or unplug and reattach the keyboard. Very strange. And, by the way: the same for hid-generic. > I think the key may have some special handling to avoid it sending > a second KEY_SLEEP when the user uses it to wakeup the system, to > avoid the system immediately going to sleep again when the user tries > to wake the system this way. Yes, that'd make sense. So probably the handler should restore something; apparently, that part is initialized when the module is loaded, so it's not just the keyboard firmware. >> Finally, keyboard backlight is handled in firmware, apparently; Fn+Space is visible on /dev/hidraw1 (see attached capture), but it toggles the backlight levels without any userspace code involved, as far as I can see. > > Yes I saw this in your dump, this is really weird because it sets 3 bits at once in the INPUT(3) report. > Does it always set the same 3 bits independent of the brightness level ? Yes; the four key presses are actually one full cycle over off, auto, dim, and bright. hidraw dumps are identical. >> Also, the keyboard backlight doesn't create an entry in /sys/class/backlight or the like, so neither read nor write access. Out-of-the-box, at least. But I'm not even sure if this is possible in Windows. > > Actuallu kbd-backlighting used the /sys/class/leds interface, but yeah that is not support by Linux ATM for this kbd. > > Yeah, adding support for that (assuming the hw can do it) would definitely require making some USB dumps under Windows > (after finding sw which can change it from within the OS under Windows). I double-checked; somewhat unsurprisingly, there is at least a notification client on Windows that displays the new configuration after Fn+Space. The client only reports the setting; not sure if it would be technically feasible to also set the brightness level in software. But anyways: I feel that I exploited your generosity in helping me far enough. I hope I wasn't just fed, but learned a bit how to fish for myself in the future. So, unless you're really committed to walk me through this further, I won't beg any further. And in case you're looking for problems to tackle on the Tablet 2nd Gen, this one about the power button could be way more significant - but not sure if it's in an area that you are familiar in: https://bbs.archlinux.org/viewtopic.php?id=248857 https://bugzilla.kernel.org/show_bug.cgi?id=204763 >> Bottom line: this is mostly usable already, modulo the adjustments for the different keys. I'd like to make F10 to F12 work before it hits testing; everything else is icing on the cake, I suppose. Do you have an hint for me how I can approach that? > > See above, I think we are pretty close to solving this. Attached is the modified version of the input mapping for this keyboard, working subject to the above mentioned restrictions. I think this is fine. As you did all the real work, I feel this should be your contribution. But of course I can also prepare a patch on top of yours. > Note in the mean time I've posted a hid-lenovo patch-series with various improvements related to > the LED handling. I'll send you an offlist mail with the latest patches so that you can base any work you do on top of those. Didn't have a look yet, but will do. >> Also, I'd make sure that this is about the "ThinkPad X1 Tablet Thin Keyboard **Gen 2**". The consumer functions are different for the **Gen 1** keyboard, so I would also adjust the function names. I do have an old Gen 1 keyboard lying around, but unfortunately it's either broken (it lights up shortly after attaching in Windows, but doesn't report keypresses at all, and pretends to be completely dead in Linux), or it's incompatible with my X1 Tablet 2nd Gen. So I cannot test how your patch might impact the Gen1, too... :-/ > > I would expect the Gen1 to have a different product-id, so my patch shouldn't do anything. Right. In this light, perhaps the function should still be called lenovo_input_mapping_x1_tab2_kbd (note the "2")? >>> I've prepared a set of patches which enable the tp10ubkbd code on >>> the X1 tablet thin keyboard. But beware as mentioned before there is a >>> tiny chance that sending the wrong command somehow puts the kbd in >>> firmware update mode. I believe that trying the tp10ubkbd code is safe, >>> esp. since this is using a 2 byte large output report and using that >>> for fw-updating would be a bit weird. Still there is a small risk >>> (there always is when poking hw) so I will leave it up to you if >>> you are willing to try this. >> >> No issue at all, and everything below works just as expected. > > Good. > > Regards, > > Hans Thanks a lot, Alex [-- Attachment #1.2: lenovo_input_mapping_x1_tab_kbd.c --] [-- Type: text/x-csrc, Size: 1346 bytes --] static int lenovo_input_mapping_x1_tab_kbd(struct hid_device *hdev, struct hid_input *hi, struct hid_field *field, struct hid_usage *usage, unsigned long **bit, int *max) { /* * The ThinkPad X1 Tablet Thin Keyboard uses 0x000c0001 usage for * a bunch of keys which have no standard consumer page code. */ if (usage->hid == 0x000c0001) { switch (usage->usage_index) { case 0: /* Fn-F10: Enable/disable bluetooth */ map_key_clear(KEY_BLUETOOTH); return 1; case 1: /* Fn-F11: Keyboard settings */ map_key_clear(KEY_KEYBOARD); return 1; case 2: /* Fn-F12: User function / Cortana */ map_key_clear(KEY_MACRO1); return 1; case 3: /* Fn-PrtSc: Snipping tool */ map_key_clear(KEY_SELECTIVE_SCREENSHOT); return 1; case 8: /* Fn-Esc: Fn-lock toggle */ map_key_clear(KEY_FN_ESC); return 1; case 9: /* Fn-F4: Mute/unmute microphone */ map_key_clear(KEY_MICMUTE); return 1; case 10: /* Fn-F9: Settings */ map_key_clear(KEY_CONFIG); return 1; case 13: /* Fn-F7: Manage external displays */ map_key_clear(KEY_SWITCHVIDEOMODE); return 1; case 14: /* Fn-F8: Enable/disable wifi */ map_key_clear(KEY_WLAN); return 1; } } if (usage->hid == (HID_UP_KEYBOARD | 0x009a)) { map_key_clear(KEY_SYSRQ); return 1; } return 0; } [-- Attachment #2: S/MIME Cryptographic Signature --] [-- Type: application/pkcs7-signature, Size: 5916 bytes --] ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Support for X1 tablet keyboard (was Re: [PATCH] platform/x86: thinkpad_acpi: handle HKEY 0x4012, 0x4013 events) 2021-02-22 12:31 ` Alexander Kobel @ 2021-02-24 21:00 ` Hans de Goede 2021-02-24 21:59 ` Alexander Kobel 0 siblings, 1 reply; 9+ messages in thread From: Hans de Goede @ 2021-02-24 21:00 UTC (permalink / raw) To: Alexander Kobel, platform-driver-x86, Mark Pearson, Nitin Joshi1 Cc: linux-input Hi, On 2/22/21 1:31 PM, Alexander Kobel wrote: > On 2/21/21 5:30 PM, Hans de Goede wrote: <snip> >>> I could adjust some of the key mappings for the X1 Tablet 2nd keyboard. What I couldn't do is to get Fn+F10, Fn+F11, Fn+F12 and Fn+PrtSc to work. >>> Following the logic of /dev/hidraw1 capture (attached), those should be on usage_index 16 to 19. But apparently those are on a different usage page or something like that? Unfortunately, my RTFM skills didn't really help with figuring out how that's supposed to work. >>> (Is looking at the bit indices in /dev/hidraw traces how you figure out those mappings? If there's a better way, I'm eager to be told...) >> >> You are swapping to low and high byte of the 3 data bytes in the report. Here is an annotated part of the descriptors to explain better: >> >> INPUT(3)[INPUT] >> Field(0) >> Application(Consumer.0001) >> Usage(24) >> 0 Consumer.0001 F10 00000001 00000000 00000000 >> 1 Consumer.0001 F11 00000010 00000000 00000000 >> 2 Consumer.0001 F12 00000100 00000000 00000000 >> 3 Consumer.0001 Prt 00001000 00000000 00000000 >> 4 Consumer.0001 >> 5 Consumer.00e2 F1 00100000 00000000 00000000 >> 6 Consumer.0001 >> 7 Consumer.0001 >> 8 Consumer.0001 ESC 00000000 00000001 00000000 >> 9 Consumer.0001 F4 00000000 00000010 00000000 >> 10 Consumer.0001 F9 00000000 00000100 00000000 >> 11 Consumer.00b7 >> 12 Consumer.0001 >> 13 Consumer.0001 F7 00000000 00100000 00000000 >> 14 Consumer.0001 F8 00000000 01000000 00000000 >> 15 Consumer.0001 >> 16 Consumer.0001 >> 17 Consumer.0001 >> 18 Consumer.0001 >> 19 Consumer.006f F6 00000000 00000000 00001000 >> 20 Consumer.00ea F2 00000000 00000000 00010000 >> 21 Consumer.00e9 F3 00000000 00000000 00100000 >> 22 Consumer.0070 F5 00000000 00000000 01000000 >> 23 Consumer.0001 >> Logical Minimum(0) >> Logical Maximum(1) >> Report Size(1) >> Report Count(24) >> Report Offset(0) >> Flags( Variable Absolute ) >> >> Notice how the keys with standard codes (which work without mapping) >> F1 - F3, F5, F6 now all line up with _none_ Consumer.0001 entries. >> And if you check those codes in drivers/hid/hid-input.c around >> line 960 you will see the standard mappings line up too. >> >> IOW your case 16 needs to be case 0, case 17, case 1, etc. > > Gotcha, I suppose. At least on a shallow level... Thanks! > And, yes: that works perfectly. > >>> Similarly - I assume - Fn+S should emit SysRq according to https://download.lenovo.com/pccbbs/mobiles_pdf/x1_tablet_gen_2_ug_en.pdf, page 51. This is not on the "consumer control" device, but the usual keyboard, so /dev/hidraw0. Again, couldn't get much further than producing a capture. But I cannot make sense of this one, because way more bits are set, so I cannot extrapolate from your code. >> >> The input report used by the Fn + key "media keys" use a 24 bit report >> with 1 bit per key. The standard keyboard interface uses 1 byte per >> pressed key (with a maximum of 6 pressed keys) where the full byte >> encodes the scancode of the key. Normally SysRq is 0x46 but for some >> reason your keyboard is sending 0x9a you can map this by adding the following >> to the mapping function: >> >> if (usage->hid == (HID_UP_KEYBOARD | 0x009a)) >> map_key_clear(KEY_SYSRQ); > > And the same here, I think. Works with return 1; after the map_key_clear, see the attached function. Ah yes, I forgot the return 1, sorry about that. > >> Likewise for the sleep combo: >> >> if (usage->hid == (HID_UP_KEYBOARD | 0x0072)) >> map_key_clear(KEY_SLEEP); > > This seems unnecessary, as the sleep combo already emits KEY_SLEEP. Which I don't quite get, cause - if I learned correctly how to read the rdesc - sleep should be on 0x0072 should emit F23 (and 0x0078 sleep), but the key produces the 0x0072 pattern according to hidraw. > By the way, the Fn+4 for sleep also works in hid-generic, and also just once, see below. Ok. >> ### >> >> Note chances are you have more Fn + 'letter' combinations at least on >> the thinkpad10 kbd I have: >> >> Fn + T -> SysRq >> Fn + I -> Insert >> Fn + P -> Pause >> Fn + S -> Sysrq >> Fn + K -> ScrollLock >> Fn + B -> Pause >> >> Note these do not need any special mappings on the thinkpad10 kbd and I guess >> the doubles may have something to do with some non qwerty keymaps. > > Not the same on this keyboard. I have Fn + {B,K,P,S,End,4} for {Break,ScrLk,Pause,SysRq,Insert,Sleep}, but only SysRq was missing; the others are available on the "default" device, both with hid-lenovo and hid-generic. Ok. >>> The ugly: >>> >>> Fn+4 ("sleep") triggers the appropriate ACPI event button/sleep and emits something on /dev/hidraw0, too, but *only once*. After resuming, no reaction at all (neither on ACPI nor hidraw) until I unload and reload the hid_lenovo module. >> >> As for the sleep key working only once, what happens after a suspend/resume ? > > Nothing. At least nothing I can measure (via evtest, libinput debug-events, cat /dev/hidraw*, dmesg, journal, acpi_listen). The key simply doesn't react anymore. > Irrespective on how I wake the device. Even irrespective of whether I actually suspend the device or disable the sleep handler altogether, e.g. by systemd-inhibit. In only see the KEY_SLEEP press (no release!) event once until I reload the module or unplug and reattach the keyboard. > Very strange. And, by the way: the same for hid-generic. > >> I think the key may have some special handling to avoid it sending >> a second KEY_SLEEP when the user uses it to wakeup the system, to >> avoid the system immediately going to sleep again when the user tries >> to wake the system this way. > > Yes, that'd make sense. So probably the handler should restore something; apparently, that part is initialized when the module is loaded, so it's not just the keyboard firmware. Maybe echo-ing to the fnlock attribute resets the key ? The driver does always force the fnlock LED on when it is loaded. >>> Finally, keyboard backlight is handled in firmware, apparently; Fn+Space is visible on /dev/hidraw1 (see attached capture), but it toggles the backlight levels without any userspace code involved, as far as I can see. >> >> Yes I saw this in your dump, this is really weird because it sets 3 bits at once in the INPUT(3) report. >> Does it always set the same 3 bits independent of the brightness level ? > > Yes; the four key presses are actually one full cycle over off, auto, dim, and bright. hidraw dumps are identical. > >>> Also, the keyboard backlight doesn't create an entry in /sys/class/backlight or the like, so neither read nor write access. Out-of-the-box, at least. But I'm not even sure if this is possible in Windows. >> >> Actuallu kbd-backlighting used the /sys/class/leds interface, but yeah that is not support by Linux ATM for this kbd. >> >> Yeah, adding support for that (assuming the hw can do it) would definitely require making some USB dumps under Windows >> (after finding sw which can change it from within the OS under Windows). > > I double-checked; somewhat unsurprisingly, there is at least a notification client on Windows that displays the new configuration after Fn+Space. The client only reports the setting; not sure if it would be technically feasible to also set the brightness level in software. We could try asking Nitin if he has any info about this, but I agree that this is a low priority item. > But anyways: I feel that I exploited your generosity in helping me far enough. I hope I wasn't just fed, but learned a bit how to fish for myself in the future. So, unless you're really committed to walk me through this further, I won't beg any further. > > And in case you're looking for problems to tackle on the Tablet 2nd Gen, this one about the power button could be way more significant - but not sure if it's in an area that you are familiar in: > https://bbs.archlinux.org/viewtopic.php?id=248857 > https://bugzilla.kernel.org/show_bug.cgi?id=204763 I see that you have already tested the patch which was posted for this, so I assume that this is resolved now ? >>> Bottom line: this is mostly usable already, modulo the adjustments for the different keys. I'd like to make F10 to F12 work before it hits testing; everything else is icing on the cake, I suppose. Do you have an hint for me how I can approach that? >> >> See above, I think we are pretty close to solving this. > > Attached is the modified version of the input mapping for this keyboard, working subject to the above mentioned restrictions. I think this is fine. > As you did all the real work, I feel this should be your contribution. But of course I can also prepare a patch on top of yours. I think you're underestimating your own contribution here... For cases like this we usually add a co-authored tag. Since this applies on top of another hid-lenovo series which I recently send out it is probably easier if I upstream this, that I agree on. I would like to attribute your work though, so I would like to suggest adding the following 2 tags to the commit msg for the "HID: lenovo: Add support for Thinkpad X1 Tablet Thin keyboard" patch: Co-authored-by: Alexander Kobel <a-kobel@a-kobel.de> Signed-off-by: Alexander Kobel <a-kobel@a-kobel.de> Alternatively I could add: Reported-and-tested-by: Alexander Kobel <a-kobel@a-kobel.de> But I believe that co-authored-by + s-o-b are more appropriate. If you can let me know which one you prefer, then I will drop in your fixed lenovo_input_mapping_x1_tab_kbd() function, remove the WIP from the commit subject and submit the last 2 patches of the set which I send you upstream (the rest was already submitted earlier). >> Note in the mean time I've posted a hid-lenovo patch-series with various improvements related to >> the LED handling. I'll send you an offlist mail with the latest patches so that you can base any work you do on top of those. > > Didn't have a look yet, but will do. > >>> Also, I'd make sure that this is about the "ThinkPad X1 Tablet Thin Keyboard **Gen 2**". The consumer functions are different for the **Gen 1** keyboard, so I would also adjust the function names. I do have an old Gen 1 keyboard lying around, but unfortunately it's either broken (it lights up shortly after attaching in Windows, but doesn't report keypresses at all, and pretends to be completely dead in Linux), or it's incompatible with my X1 Tablet 2nd Gen. So I cannot test how your patch might impact the Gen1, too... :-/ >> >> I would expect the Gen1 to have a different product-id, so my patch shouldn't do anything. > > Right. In this light, perhaps the function should still be called lenovo_input_mapping_x1_tab2_kbd (note the "2")? Well drivers/hid/hid-ids.h has this: #define USB_DEVICE_ID_LENOVO_X1_COVER 0x6085 #define USB_DEVICE_ID_LENOVO_X1_TAB 0x60a3 #define USB_DEVICE_ID_LENOVO_X1_TAB3 0x60b5 And I guess that the COVER might be the X1 gen1 product-id ? Your working kbd is using the USB_DEVICE_ID_LENOVO_X1_TAB id. note not TAB2 just tab. I don't know, but it is not all that important really, we can always rename both the #define USB_DEVICE_ID_LENOVO_X1_TAB and the function later if there is a reason to do so. > Thanks a lot, You're welcome and thank you for helping with improving support for Linux on these devices. Regards, Hans ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Support for X1 tablet keyboard (was Re: [PATCH] platform/x86: thinkpad_acpi: handle HKEY 0x4012, 0x4013 events) 2021-02-24 21:00 ` Hans de Goede @ 2021-02-24 21:59 ` Alexander Kobel 2021-03-04 19:23 ` Hans de Goede 0 siblings, 1 reply; 9+ messages in thread From: Alexander Kobel @ 2021-02-24 21:59 UTC (permalink / raw) To: Hans de Goede, platform-driver-x86, Mark Pearson, Nitin Joshi1 Cc: linux-input [-- Attachment #1: Type: text/plain, Size: 9944 bytes --] Hi, On 2/24/21 10:00 PM, Hans de Goede wrote: > Hi, > > On 2/22/21 1:31 PM, Alexander Kobel wrote: >> On 2/21/21 5:30 PM, Hans de Goede wrote: <snip> >>> The input report used by the Fn + key "media keys" use a 24 bit report >>> with 1 bit per key. The standard keyboard interface uses 1 byte per >>> pressed key (with a maximum of 6 pressed keys) where the full byte >>> encodes the scancode of the key. Normally SysRq is 0x46 but for some >>> reason your keyboard is sending 0x9a you can map this by adding the following >>> to the mapping function: >>> >>> if (usage->hid == (HID_UP_KEYBOARD | 0x009a)) >>> map_key_clear(KEY_SYSRQ); >> >> And the same here, I think. Works with return 1; after the map_key_clear, see the attached function. > > Ah yes, I forgot the return 1, sorry about that. No problem, nearby pattern matching and copy-paste is a great way to learn sometimes. ;-) >>> Likewise for the sleep combo: >>> >>> if (usage->hid == (HID_UP_KEYBOARD | 0x0072)) >>> map_key_clear(KEY_SLEEP); >> >> This seems unnecessary, as the sleep combo already emits KEY_SLEEP. Which I don't quite get, cause - if I learned correctly how to read the rdesc - sleep should be on 0x0072 should emit F23 (and 0x0078 sleep), but the key produces the 0x0072 pattern according to hidraw. >> By the way, the Fn+4 for sleep also works in hid-generic, and also just once, see below. > > Ok. > >>> ### >>> >>> Note chances are you have more Fn + 'letter' combinations at least on >>> the thinkpad10 kbd I have: >>> >>> Fn + T -> SysRq >>> Fn + I -> Insert >>> Fn + P -> Pause >>> Fn + S -> Sysrq >>> Fn + K -> ScrollLock >>> Fn + B -> Pause >>> >>> Note these do not need any special mappings on the thinkpad10 kbd and I guess >>> the doubles may have something to do with some non qwerty keymaps. >> >> Not the same on this keyboard. I have Fn + {B,K,P,S,End,4} for {Break,ScrLk,Pause,SysRq,Insert,Sleep}, but only SysRq was missing; the others are available on the "default" device, both with hid-lenovo and hid-generic. > > Ok. > >>>> The ugly: >>>> >>>> Fn+4 ("sleep") triggers the appropriate ACPI event button/sleep and emits something on /dev/hidraw0, too, but *only once*. After resuming, no reaction at all (neither on ACPI nor hidraw) until I unload and reload the hid_lenovo module. >>> >>> As for the sleep key working only once, what happens after a suspend/resume ? >> >> Nothing. At least nothing I can measure (via evtest, libinput debug-events, cat /dev/hidraw*, dmesg, journal, acpi_listen). The key simply doesn't react anymore. >> Irrespective on how I wake the device. Even irrespective of whether I actually suspend the device or disable the sleep handler altogether, e.g. by systemd-inhibit. In only see the KEY_SLEEP press (no release!) event once until I reload the module or unplug and reattach the keyboard. >> Very strange. And, by the way: the same for hid-generic. >> >>> I think the key may have some special handling to avoid it sending >>> a second KEY_SLEEP when the user uses it to wakeup the system, to >>> avoid the system immediately going to sleep again when the user tries >>> to wake the system this way. >> >> Yes, that'd make sense. So probably the handler should restore something; apparently, that part is initialized when the module is loaded, so it's not just the keyboard firmware. > > Maybe echo-ing to the fnlock attribute resets the key ? The driver does always force the fnlock LED on when it is loaded. Good catch, but that doesn't help, either. It's only a minor nuisance, though; in any case, it can be worked around by reloading the driver in a resume hook. If one actually wants to use that button; I personally won't. >>>> Finally, keyboard backlight is handled in firmware, apparently; Fn+Space is visible on /dev/hidraw1 (see attached capture), but it toggles the backlight levels without any userspace code involved, as far as I can see. >>> >>> Yes I saw this in your dump, this is really weird because it sets 3 bits at once in the INPUT(3) report. >>> Does it always set the same 3 bits independent of the brightness level ? >> >> Yes; the four key presses are actually one full cycle over off, auto, dim, and bright. hidraw dumps are identical. >> >>>> Also, the keyboard backlight doesn't create an entry in /sys/class/backlight or the like, so neither read nor write access. Out-of-the-box, at least. But I'm not even sure if this is possible in Windows. >>> >>> Actuallu kbd-backlighting used the /sys/class/leds interface, but yeah that is not support by Linux ATM for this kbd. >>> >>> Yeah, adding support for that (assuming the hw can do it) would definitely require making some USB dumps under Windows >>> (after finding sw which can change it from within the OS under Windows). >> >> I double-checked; somewhat unsurprisingly, there is at least a notification client on Windows that displays the new configuration after Fn+Space. The client only reports the setting; not sure if it would be technically feasible to also set the brightness level in software. > > We could try asking Nitin if he has any info about this, but I agree that this is a low priority item. Ack. >> But anyways: I feel that I exploited your generosity in helping me far enough. I hope I wasn't just fed, but learned a bit how to fish for myself in the future. So, unless you're really committed to walk me through this further, I won't beg any further. >> >> And in case you're looking for problems to tackle on the Tablet 2nd Gen, this one about the power button could be way more significant - but not sure if it's in an area that you are familiar in: >> https://bbs.archlinux.org/viewtopic.php?id=248857 >> https://bugzilla.kernel.org/show_bug.cgi?id=204763 > > I see that you have already tested the patch which was posted for this, so I assume that this is resolved now ? Correct. I resurrected the bugzilla task shortly after my last mail, and Alban cranked out a patch with you in CC within few hours. Didn't want to add more noise here. >>>> Bottom line: this is mostly usable already, modulo the adjustments for the different keys. I'd like to make F10 to F12 work before it hits testing; everything else is icing on the cake, I suppose. Do you have an hint for me how I can approach that? >>> >>> See above, I think we are pretty close to solving this. >> >> Attached is the modified version of the input mapping for this keyboard, working subject to the above mentioned restrictions. I think this is fine. >> As you did all the real work, I feel this should be your contribution. But of course I can also prepare a patch on top of yours. > > I think you're underestimating your own contribution here... > > For cases like this we usually add a co-authored tag. Since this applies on top of another hid-lenovo series which I recently send out it is probably easier if I upstream this, that I agree on. > > I would like to attribute your work though, so I would like to suggest adding the following 2 tags to the commit msg for > the "HID: lenovo: Add support for Thinkpad X1 Tablet Thin keyboard" patch: > > Co-authored-by: Alexander Kobel <a-kobel@a-kobel.de> > Signed-off-by: Alexander Kobel <a-kobel@a-kobel.de> > > Alternatively <snip> > But I believe that co-authored-by + s-o-b are more appropriate. Okay, so be it. I trust your opinion here. > If you can let me know which one you prefer, then I will drop in your fixed lenovo_input_mapping_x1_tab_kbd() function, remove the WIP from the commit subject and submit the last 2 patches of the set which I send you upstream (the rest was already submitted earlier). co-authored-by + s-o-b it is then. Ack for the rest. >>> Note in the mean time I've posted a hid-lenovo patch-series with various improvements related to >>> the LED handling. I'll send you an offlist mail with the latest patches so that you can base any work you do on top of those. >> >> Didn't have a look yet, but will do. >> >>>> Also, I'd make sure that this is about the "ThinkPad X1 Tablet Thin Keyboard **Gen 2**". The consumer functions are different for the **Gen 1** keyboard, so I would also adjust the function names. I do have an old Gen 1 keyboard lying around, but unfortunately it's either broken (it lights up shortly after attaching in Windows, but doesn't report keypresses at all, and pretends to be completely dead in Linux), or it's incompatible with my X1 Tablet 2nd Gen. So I cannot test how your patch might impact the Gen1, too... :-/ >>> >>> I would expect the Gen1 to have a different product-id, so my patch shouldn't do anything. >> >> Right. In this light, perhaps the function should still be called lenovo_input_mapping_x1_tab2_kbd (note the "2")? > > Well drivers/hid/hid-ids.h has this: > > #define USB_DEVICE_ID_LENOVO_X1_COVER 0x6085 > #define USB_DEVICE_ID_LENOVO_X1_TAB 0x60a3 > #define USB_DEVICE_ID_LENOVO_X1_TAB3 0x60b5 > > And I guess that the COVER might be the X1 gen1 product-id ? AFAICS, yes; confirmed by a quick web search. So it'd be more apt to #define USB_DEVICE_ID_LENOVO_X1_TAB 0x6085 #define USB_DEVICE_ID_LENOVO_X1_TAB2 0x60a3 #define USB_DEVICE_ID_LENOVO_X1_TAB3 0x60b5 but I have no way to really confirm right now, so I'd also be in favor to leave it as-is. > Your working kbd is using the USB_DEVICE_ID_LENOVO_X1_TAB id. note not TAB2 just tab. > > I don't know, but it is not all that important really, we can always rename both the #define USB_DEVICE_ID_LENOVO_X1_TAB and the function later if there is a reason to do so. Ack. Better have #defines and function names in sync and think about more interesting stuff. ;-) >> Thanks a lot, > > You're welcome and thank you for helping with improving support for Linux on these devices. Ditto! Cheers, Alex [-- Attachment #2: S/MIME Cryptographic Signature --] [-- Type: application/pkcs7-signature, Size: 5916 bytes --] ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Support for X1 tablet keyboard (was Re: [PATCH] platform/x86: thinkpad_acpi: handle HKEY 0x4012, 0x4013 events) 2021-02-24 21:59 ` Alexander Kobel @ 2021-03-04 19:23 ` Hans de Goede 0 siblings, 0 replies; 9+ messages in thread From: Hans de Goede @ 2021-03-04 19:23 UTC (permalink / raw) To: Alexander Kobel, platform-driver-x86, Mark Pearson, Nitin Joshi1 Cc: linux-input Hi, On 2/24/21 10:59 PM, Alexander Kobel wrote: > Hi, > > On 2/24/21 10:00 PM, Hans de Goede wrote: >> Hi, >> >> On 2/22/21 1:31 PM, Alexander Kobel wrote: >>> On 2/21/21 5:30 PM, Hans de Goede wrote: > > <snip> > >>>> The input report used by the Fn + key "media keys" use a 24 bit report >>>> with 1 bit per key. The standard keyboard interface uses 1 byte per >>>> pressed key (with a maximum of 6 pressed keys) where the full byte >>>> encodes the scancode of the key. Normally SysRq is 0x46 but for some >>>> reason your keyboard is sending 0x9a you can map this by adding the following >>>> to the mapping function: >>>> >>>> if (usage->hid == (HID_UP_KEYBOARD | 0x009a)) >>>> map_key_clear(KEY_SYSRQ); >>> >>> And the same here, I think. Works with return 1; after the map_key_clear, see the attached function. >> >> Ah yes, I forgot the return 1, sorry about that. > > No problem, nearby pattern matching and copy-paste is a great way to learn sometimes. ;-) > >>>> Likewise for the sleep combo: >>>> >>>> if (usage->hid == (HID_UP_KEYBOARD | 0x0072)) >>>> map_key_clear(KEY_SLEEP); >>> >>> This seems unnecessary, as the sleep combo already emits KEY_SLEEP. Which I don't quite get, cause - if I learned correctly how to read the rdesc - sleep should be on 0x0072 should emit F23 (and 0x0078 sleep), but the key produces the 0x0072 pattern according to hidraw. >>> By the way, the Fn+4 for sleep also works in hid-generic, and also just once, see below. >> >> Ok. >> >>>> ### >>>> >>>> Note chances are you have more Fn + 'letter' combinations at least on >>>> the thinkpad10 kbd I have: >>>> >>>> Fn + T -> SysRq >>>> Fn + I -> Insert >>>> Fn + P -> Pause >>>> Fn + S -> Sysrq >>>> Fn + K -> ScrollLock >>>> Fn + B -> Pause >>>> >>>> Note these do not need any special mappings on the thinkpad10 kbd and I guess >>>> the doubles may have something to do with some non qwerty keymaps. >>> >>> Not the same on this keyboard. I have Fn + {B,K,P,S,End,4} for {Break,ScrLk,Pause,SysRq,Insert,Sleep}, but only SysRq was missing; the others are available on the "default" device, both with hid-lenovo and hid-generic. >> >> Ok. >> >>>>> The ugly: >>>>> >>>>> Fn+4 ("sleep") triggers the appropriate ACPI event button/sleep and emits something on /dev/hidraw0, too, but *only once*. After resuming, no reaction at all (neither on ACPI nor hidraw) until I unload and reload the hid_lenovo module. >>>> >>>> As for the sleep key working only once, what happens after a suspend/resume ? >>> >>> Nothing. At least nothing I can measure (via evtest, libinput debug-events, cat /dev/hidraw*, dmesg, journal, acpi_listen). The key simply doesn't react anymore. >>> Irrespective on how I wake the device. Even irrespective of whether I actually suspend the device or disable the sleep handler altogether, e.g. by systemd-inhibit. In only see the KEY_SLEEP press (no release!) event once until I reload the module or unplug and reattach the keyboard. >>> Very strange. And, by the way: the same for hid-generic. >>> >>>> I think the key may have some special handling to avoid it sending >>>> a second KEY_SLEEP when the user uses it to wakeup the system, to >>>> avoid the system immediately going to sleep again when the user tries >>>> to wake the system this way. >>> >>> Yes, that'd make sense. So probably the handler should restore something; apparently, that part is initialized when the module is loaded, so it's not just the keyboard firmware. >> >> Maybe echo-ing to the fnlock attribute resets the key ? The driver does always force the fnlock LED on when it is loaded. > > Good catch, but that doesn't help, either. > > It's only a minor nuisance, though; in any case, it can be worked around by reloading the driver in a resume hook. If one actually wants to use that button; I personally won't. > >>>>> Finally, keyboard backlight is handled in firmware, apparently; Fn+Space is visible on /dev/hidraw1 (see attached capture), but it toggles the backlight levels without any userspace code involved, as far as I can see. >>>> >>>> Yes I saw this in your dump, this is really weird because it sets 3 bits at once in the INPUT(3) report. >>>> Does it always set the same 3 bits independent of the brightness level ? >>> >>> Yes; the four key presses are actually one full cycle over off, auto, dim, and bright. hidraw dumps are identical. >>> >>>>> Also, the keyboard backlight doesn't create an entry in /sys/class/backlight or the like, so neither read nor write access. Out-of-the-box, at least. But I'm not even sure if this is possible in Windows. >>>> >>>> Actuallu kbd-backlighting used the /sys/class/leds interface, but yeah that is not support by Linux ATM for this kbd. >>>> >>>> Yeah, adding support for that (assuming the hw can do it) would definitely require making some USB dumps under Windows >>>> (after finding sw which can change it from within the OS under Windows). >>> >>> I double-checked; somewhat unsurprisingly, there is at least a notification client on Windows that displays the new configuration after Fn+Space. The client only reports the setting; not sure if it would be technically feasible to also set the brightness level in software. >> >> We could try asking Nitin if he has any info about this, but I agree that this is a low priority item. > > Ack. > >>> But anyways: I feel that I exploited your generosity in helping me far enough. I hope I wasn't just fed, but learned a bit how to fish for myself in the future. So, unless you're really committed to walk me through this further, I won't beg any further. >>> >>> And in case you're looking for problems to tackle on the Tablet 2nd Gen, this one about the power button could be way more significant - but not sure if it's in an area that you are familiar in: >>> https://bbs.archlinux.org/viewtopic.php?id=248857 >>> https://bugzilla.kernel.org/show_bug.cgi?id=204763 >> >> I see that you have already tested the patch which was posted for this, so I assume that this is resolved now ? > > Correct. I resurrected the bugzilla task shortly after my last mail, and Alban cranked out a patch with you in CC within few hours. Didn't want to add more noise here. > >>>>> Bottom line: this is mostly usable already, modulo the adjustments for the different keys. I'd like to make F10 to F12 work before it hits testing; everything else is icing on the cake, I suppose. Do you have an hint for me how I can approach that? >>>> >>>> See above, I think we are pretty close to solving this. >>> >>> Attached is the modified version of the input mapping for this keyboard, working subject to the above mentioned restrictions. I think this is fine. >>> As you did all the real work, I feel this should be your contribution. But of course I can also prepare a patch on top of yours. >> >> I think you're underestimating your own contribution here... >> >> For cases like this we usually add a co-authored tag. Since this applies on top of another hid-lenovo series which I recently send out it is probably easier if I upstream this, that I agree on. >> >> I would like to attribute your work though, so I would like to suggest adding the following 2 tags to the commit msg for >> the "HID: lenovo: Add support for Thinkpad X1 Tablet Thin keyboard" patch: >> >> Co-authored-by: Alexander Kobel <a-kobel@a-kobel.de> >> Signed-off-by: Alexander Kobel <a-kobel@a-kobel.de> >> >> Alternatively > > <snip> > >> But I believe that co-authored-by + s-o-b are more appropriate. > > Okay, so be it. I trust your opinion here. Great, I've submitted a new version of my previous hid-lenovo series upstream now, with the 2 patches to add support for the X1 tablet keyboard added to the series. Regards, Hans ^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2021-03-04 19:25 UTC | newest] Thread overview: 9+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- [not found] <53abdd94-8df4-cc1c-84e9-221face6b07c@a-kobel.de> [not found] ` <9d133a27-751a-a436-d255-3dd4a7d411d8@redhat.com> [not found] ` <38cb8265-1e30-d547-9e12-b4ae290be737@a-kobel.de> 2021-02-08 10:17 ` Support for X1 tablet keyboard (was Re: [PATCH] platform/x86: thinkpad_acpi: handle HKEY 0x4012, 0x4013 events) Hans de Goede 2021-02-09 15:16 ` Alexander Kobel 2021-02-11 23:42 ` Hans de Goede 2021-02-21 13:17 ` Alexander Kobel 2021-02-21 16:30 ` Hans de Goede 2021-02-22 12:31 ` Alexander Kobel 2021-02-24 21:00 ` Hans de Goede 2021-02-24 21:59 ` Alexander Kobel 2021-03-04 19:23 ` Hans de Goede
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).