A couple of months ago I bought the Nanoleaf Pegboard Desk Dock, the latest and greatest in USB-hub-with-RGB-LEDs-and-hooks-for-gadgets technology. This invention unfortunately only supports the real gamer operating systems of Windows and macOS, which necessitated the development of a Linux driver.
Over the past few posts I’ve set up a Windows VM with USB passthrough, and attempted to reverse-engineer the official drivers, As I was doing that, I also thought I’d message the vendor and ask them if they could share any specifications or docs regarding their protocol. To my surprise, Nanoleaf tech support responded to me within 4 hours, with a full description of the protocol that’s used both by the Desk Dock as well as their RGB strips. The docs mostly confirmed what I had already discovered independently, but there were a couple of other minor features as well (like power and brightness management) that I did not know about, which was helpful.
Today, we’re going to take a crack at writing a driver based on the (reverse-engineered) protocol, while also keeping the official documentation at hand. One small problem, though: I’ve never written a Linux device driver before, nor interacted with any USB device as anything else but a user.
Skip to the good part? Lots of yapping ahead. If you just want to see the code, click here.
Starting from scratch
Most Linux distros ship with lsusb , a simple utility that will enumerate all USB devices connected to the system. Since I had no clue where to start from, I figured I might as well run this to see if the device appears in the listing.
$ lsusb
Well, good news, it’s definitely there. But, how can the kernel know that what I have plugged in is the “Nanoleaf Pegboard Desk Dock”? The kernel (presumably) has no knowledge of this device’s existence, yet the second I plug it in to my computer it receives power, turns on and gets identified by the kernel.
As it turns out, we actually already have a driver! It’s just a very stupid one. If we run lsusb in verbose mode and request the information just for this specific device, we will get a lot more details about it:
$ lsusb -d 37fa:8201 -v Bus 001 Device 091: ID 37fa:8201 JW25021301515 Nanoleaf Pegboard Desk Dock Negotiated speed: Full Speed (12Mbps) Device Descriptor: bLength 18 bDescriptorType 1 bcdUSB 1.10 bDeviceClass 0 [unknown] bDeviceSubClass 0 [unknown] bDeviceProtocol 0 bMaxPacketSize0 64 idVendor 0x37fa JW25021301515 idProduct 0x8201 Nanoleaf Pegboard Desk Dock bcdDevice 1.09 iManufacturer 1 JW25021301515 iProduct 2 Nanoleaf Pegboard Desk Dock iSerial 3
... continue reading