Some while ago, i bought a CH341-based adapter to interface serial ROM-chips. This was meant for flashing coreboot on some thinkpads. The ROM is either interfaced via SPI or I2C, showing up as raw usb device of some sort in the linux devtmpfs.

In addition to those interfaces, the adapter also had solder pads for a serial connection. Contrary to other USB-to-serial adapters, it did not cause a tty device node to show up on the connected computer.

The device is detected with dmesg:

[174562.858447] usb 2-1.1: new full-speed USB device number 8 using ehci-pci
[174562.956122] usb 2-1.1: New USB device found, idVendor=1a86, idProduct=5512, bcdDevice= 3.04
[174562.956132] usb 2-1.1: New USB device strings: Mfr=0, Product=0, SerialNumber=0

I quick search showed that linux already has an ch341 driver mainlined and shipped, yet for some reason it did not take care of the seemingly unknown usb device.

In the kernel driver code, at drivers/usb/serial/ch341.c, three usb-IDs are registered:

static const struct usb_device_id id_table[] = {
	{ USB_DEVICE(0x4348, 0x5523) },
	{ USB_DEVICE(0x1a86, 0x7523) },
	{ USB_DEVICE(0x1a86, 0x5523) },
	{ },
MODULE_DEVICE_TABLE(usb, id_table);

The ID of my device is not in there. My first reaction was to patch and recompile the kernel, which i was too lazy to. So it sat on my desk for some weeks.

Later i randomly discovered that the usb-ID to driver mapping on linux is changeable at runtime. Provided that the ch341 kernel module is already loaded, one can add arbitrary usb-IDs via the sysfs interface:

modprobe ch341
echo 1a86 5512 >/sys/bus/usb-serial/drivers/ch341-uart/new_id

The manual loading of the kernel module is necessary, due to the ID mismatch, the hotplug mechanism doesn’t trigger. I put the above code into the start() function of a fresh openrc service to have it configured on every boot. Users of poetteringware might setup an udev rule, but that is difficult to debug, so i didn’t try it.

The end result looks like this in dmesg:

[18013.206996] ch341 2-1.1:1.0: ch341-uart converter detected
[18013.208298] usb 2-1.1: ch341-uart converter now attached to ttyUSB0