3

I have a broken laptop built-in keyboard (The shift-button sometimes gets stuck down). I exclusively use an external keyboard, but the internal keyboard interferes with it. (I can not unplug the device.)

I can disable with xinput, but it becomes enabled again (see Permanently disable keyboard).

I have identified the device. (you need install lsinput e.g. with apt install input-utils).

sudo lsinput

/dev/input/event0
   bustype : BUS_I8042
   vendor  : 0x1
   product : 0x1
   version : 43841
   name    : "AT Translated Set 2 keyboard"
   phys    : "isa0060/serio0/input0"
   bits ev : EV_SYN EV_KEY EV_MSC EV_LED EV_REP

How to I disable it?

3 Answers3

3

Blacklisting it could be an option. Like, if that's going through the atkbd module and nothing else needs that particular module, just blacklist the module.

Otherwise, perhaps unbind is an option as well.

Lacking a laptop to test with, I hooked up a spare mouse to my system and then disabled it.

This is the mouse:

I: Bus=0003 Vendor=04f3 Product=0235 Version=0111
N: Name="OM"
P: Phys=usb-0000:00:14.0-10.1/input0
S: Sysfs=/devices/pci0000:00/0000:00:14.0/usb2/2-10/2-10.1/2-10.1:1.0/0003:04F3:0235.0004/input/input12
U: Uniq=
H: Handlers=event12 mouse1 
B: PROP=0
B: EV=17
B: KEY=70000 0 0 0 0
B: REL=903
B: MSC=10

Going through /sys/bus/hid/...:

# head /sys/bus/hid/drivers/*/*/*/*/name
==> /sys/bus/hid/drivers/hid-generic/0003:046A:010D.0001/input/input3/name <==
HID 046a:010d

==> /sys/bus/hid/drivers/hid-generic/0003:046A:010D.0002/input/input4/name <==
HID 046a:010d

==> /sys/bus/hid/drivers/hid-generic/0003:046D:C077.0003/input/input5/name <==
Logitech USB Optical Mouse

==> /sys/bus/hid/drivers/hid-generic/0003:04F3:0235.0004/input/input12/name <==
OM

Well, let's kick it out.

# echo 0003:04F3:0235.0004 > /sys/bus/hid/drivers/hid-generic/unbind

And it's gone. No longer moves the mouse cursor. No longer even listed as input device. It's really gone.

So you can do such things with unbinding, and depending on which driver it uses, also blacklisting. The main problem is locating the correct name and place to unbind it, then automate with a custom udev rule. Otherwise if you pull the plug and put it back in, it's there and back again.

frostschutz
  • 48,978
  • that said, a lot of laptops actually have servicable keyboards. so don't be too quick to rule out a hardware solution entirely. if replacing the keyboard is not an option (laptop too old) it might still be possible to fix or disable the offending key in the hardware specifically. but that's a question for a hardware forum... – frostschutz Jul 24 '19 at 17:14
  • That's an old-school AT keyboard on a PS2 port. While you can blacklist that, too, it won't be under HID devices, and I'm not sure if you can actually unbind it. But you can definitely blacklist it on boot. – dirkt Jul 25 '19 at 16:30
2

If looking on the USB level didn't turn up anything you can fix, then the next two things you can do is to "grab" it on the input layer level, or prevent it becoming active on the X level.

For the first,

evtest --grab /dev/input/event0 > /dev/null

or something similar should do the trick: The grab makes sure only the grabbing application receives events, i.e., X won't receive any.

For the second, add an InputClass section to your xorg.conf, along the lines of

Section "InputClass"
    Identifier "BrokenKeyboard"
    MatchDevicePath "/dev/input/by-path/platform-i8042-serio-0-event-kb"
    Option "Ignore" "true"
EndSection

assuming that this path is actually what links to your keyboard. Don't use /dev/input/event0 etc. here, it's not guaranteed to be consistent across boots.

dirkt
  • 32,309
  • I tried adding the section to /usr/share/X11/xorg.conf.d/10-my-disable-yoga-keyboard.conf, but with added d to path. Nothing happened. Am I doing it correct? Do I need to change the priority number of the file? – ctrl-alt-delor Jul 25 '19 at 16:25
  • I would also like something that works outside of X11: console, wayland (I may use this). – ctrl-alt-delor Jul 25 '19 at 16:26
  • Check via Xorg.log if the matching works, or you need to change it to something else. If you want something outside of X, you'll need to disable it on a lower layer, e.g. input or the kernel module itself as suggested in the other answer. – dirkt Jul 25 '19 at 16:29
1

Belated, but I wanted to expound upon the answers up above just a bit for Apple users. I have a MBP with a busted internal keyboard, and I've been using evtest to grab input from it and send it to /dev/null. This seems to be the most common suggestion floating around. The problem with this solution is that the event number changes if the kernel is updated, and if you have a script that runs at boot like I do, this number has to be manually updated with each kernel update. This is where using unbind comes in, and how the answer above inspired me to finally ditch evtest. I've come up with a simple one-liner, and it seems to do the job perfectly.

Here's the full command:

head /sys/bus/hid/drivers/*/*/*/*/name | grep "apple" | sed -E 's/[^0-9A-F:.]*//g' | awk '{ print substr( $0, 1, length($0)-2 ) }' > /sys/bus/hid/drivers/apple/unbind

We know what the first part of this does, so I'll explain the need for sed and awk. Running just head along with a grep will output something akin to this:

/sys/bus/hid/drivers/apple/0003:046D:C077.0003/input/input18/name

Now, we use sed to get rid of everything that's not a hexadecimal character:

0003:046D:C077.000318

You'll notice that the input number is also included on the end there, which we don't need, so we use awk to remove the last two characters of the string:

0003:046D:C077.0003

And of course, we have the output direction sending this string to /sys/bus/hid/drivers/apple/unbind. Plop this into a script that you can run at boot, and tada! The caveat to this is that it'll have to be modified for hid-generic devices. Apple has its own input driver directory that makes this a bit simpler, and grep'ing for just "apple" suffices.

Edit: This is the beauty of crowd-sourced information. Thanks go to Stephen Kitt down below for this solution. It's much more elegant than mine, and properly takes input device numbers into consideration.

for name in /sys/bus/hid/drivers/apple/*/*/*/name; do device=$(cut -d/ -f7 <<<"$name"); [ "$device" != "*" ] && printf "%s" "$device" > /sys/bus/hid/drivers/apple/unbind; done
Joom
  • 11
  • What happens if the input/inputX part only has one digit? It would be more robust to look in the right directory instead of post-filtering, and then look at the relevant part of the path: for name in /sys/bus/hid/drivers/apple/*/*/*/name; do device=$(cut -d/ -f7 <<<"$name"); [ "$device" != "*" ] && printf "%s" "$device" > /sys/bus/hid/drivers/apple/unbind; done. – Stephen Kitt Aug 23 '22 at 07:50
  • You're right! I'm not sure why I didn't think of that. Was a bit of a long day, and I was a little overly ecstatic. Thanks for the correction. :) – Joom Aug 26 '22 at 19:34
  • No worries, your answer is useful (I upvoted it); feel free to steal my comment and [edit] your answer to make it better ;-). – Stephen Kitt Aug 26 '22 at 20:05