Builtin USB Webcam gets recognized as Keyboard?

I installed some Ubuntu on my Eee Pc a few years ago and the webcam did not work. That didn't really bother me, cause I didn't use it anyway. Recently, I updated to Ubuntu 17.04 (as in formatted the Ubuntu partition and freshly installed). While troubleshooting some other problems I visited /var/log/Xorg.0.log and noticed following section:

[   775.333] (II) config/udev: Adding input device USB2.0 UVC VGA WebCam (/dev/input/event8)
[   775.334] (**) USB2.0 UVC VGA WebCam: Applying InputClass "libinput keyboard catchall"
[   775.334] (II) Using input driver 'libinput' for 'USB2.0 UVC VGA WebCam'
[   775.334] (**) USB2.0 UVC VGA WebCam: always reports core events
[   775.334] (**) Option "Device" "/dev/input/event8"
[   775.334] (**) Option "_source" "server/udev"
[   775.336] (II) input device 'USB2.0 UVC VGA WebCam', /dev/input/event8 is tagged by udev as: Keyboard
[   775.336] (II) input device 'USB2.0 UVC VGA WebCam', /dev/input/event8 is a keyboard
[   775.368] (**) Option "config_info" "udev:/sys/devices/pci0000:00/0000:00:1d.7/usb1/1-6/1-6:1.0/input/input9/event8"
[   775.368] (II) XINPUT: Adding extended input device "USB2.0 UVC VGA WebCam" (type: KEYBOARD, id 11)
[   775.368] (**) Option "xkb_model" "pc105"
[   775.368] (**) Option "xkb_layout" "de"
[   775.371] (II) input device 'USB2.0 UVC VGA WebCam', /dev/input/event8 is tagged by udev as: Keyboard
[   775.371] (II) input device 'USB2.0 UVC VGA WebCam', /dev/input/event8 is a keyboard
[   775.374] (II) config/udev: Adding input device AT Translated Set 2 keyboard (/dev/input/event4)
[   775.374] (**) AT Translated Set 2 keyboard: Applying InputClass "libinput keyboard catchall"
[   775.374] (II) Using input driver 'libinput' for 'AT Translated Set 2 keyboard'
[   775.374] (**) AT Translated Set 2 keyboard: always reports core events

I have no idea why Xorg is even handling USB/Input devices (isn't it a display server ?), but the main question is:
How can I stop Ubuntu/Xorg from trying to use my poor Webcam as a keyboard and start using it as an actual Webcam?


Solution 1:

A udev rule can be set to prevent a USB device from loading a driver, which should have the intended effect of disabling part of a device while leaving other functions operational.

Here's how you can do it:

  1. Open Terminal (if it's not already open)

  2. Determine the manufacturer and device ID via lsusb (for PCI devices, you can use lspci):

    sudo lsusb
    

    You will likely see an output similar to this:

    ...
    Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
    Bus 001 Device 002: ID 8087:8008 Intel Corp. 
    Bus 001 Device 003: ID 04f2:b448 TOSHIBA Web Camera - HD: TOSHIB
    ...
    

    Note the manufacturer ID (eg. 04f2) and product ID (eg. b448). These will be important later.

  3. Determine the driver(s) that the device requires via udevadm:

    udevadm info -a /dev/input/by-id/*
    

    Note: You will need to sift through the input devices to find your camera. Alternatively, if you look at the contents of /dev/input/by-id, you may spot your camera. Then you can issue a more specific command, like udevadm info -a /dev/input/by-id/*Camera*.

    You will likely see a great deal of information that starts like this:

    looking at parent device '/devices/pci0000:00/0000:00:14.0/usb3':
         KERNELS=="usb3"
         SUBSYSTEMS=="usb"
         DRIVERS=="usb"
    

    You want to pay attention to DRIVERS for the USB device that is your camera. There will be a line that may say uvcvideo and another that'll say something like libinput, which is incorrect.

  4. Create a udev rule file:

    sudo {text editor of choice} /etc/udev/rules.d/90-blacklist-webcam-keyboard.rules
    

    Note: Be sure to replace {text editor of choice} with your text editor of choice. I used to put vi in there, as that's what a neckbeard like me uses. However, a lot of those posts would get edited to replace vi with gedit or some other newfangled thing. TLDR; use what works for you.

    In that file, record the driver, manufacturer ID, and product ID in a format like this:

    # Not a keyboard!
    SUBSYSTEM=="usb", DRIVER=="libinput", ATTRS{idVendor}=="04f2", ATTRS{idProduct}=="b448", ATTR{authorized}="0"
    
  5. Reboot.

    Note: If the camera were a USB device that could be disconnected and reconnected, you could simply reload the udev rules with a sudo udevadm control --reload-rules and re-connect the device. However, as it's built-in, a reboot is the simplest option without getting into complicated hardware API commands.

  6. Test your camera.

If everything works as expected, your camera will now be seen only as a camera. There may be a line in the syslog that says the keyboard is not authorised, but that will be that.