Ubuntu Drivers – How to Write a Driver for an Unsupported Touch Pad in a Laptop

driversUbuntu

I found an old laptop in my garage (Lenovo IdeaPad U260) and after replacing the motherboard and CPU and installing Ubuntu 18.04.3 LTS, it works almost as good as new. The only problem is that the touchpad doesn't work, and from my understanding, it isn't recognized. Here's output from lspci:

00:00.0 Host bridge: Intel Corporation Core Processor DRAM Controller (rev 02)
00:02.0 VGA compatible controller: Intel Corporation Core Processor Integrated Graphics Controller (rev 02)
00:16.0 Communication controller: Intel Corporation 5 Series/3400 Series Chipset HECI Controller (rev 06)
00:1a.0 USB controller: Intel Corporation 5 Series/3400 Series Chipset USB2 Enhanced Host Controller (rev 05)
00:1b.0 Audio device: Intel Corporation 5 Series/3400 Series Chipset High Definition Audio (rev 05)
00:1c.0 PCI bridge: Intel Corporation 5 Series/3400 Series Chipset PCI Express Root Port 1 (rev 05)
00:1c.1 PCI bridge: Intel Corporation 5 Series/3400 Series Chipset PCI Express Root Port 2 (rev 05)
00:1c.2 PCI bridge: Intel Corporation 5 Series/3400 Series Chipset PCI Express Root Port 3 (rev 05)
00:1d.0 USB controller: Intel Corporation 5 Series/3400 Series Chipset USB2 Enhanced Host Controller (rev 05)
00:1e.0 PCI bridge: Intel Corporation 82801 Mobile PCI Bridge (rev a5)
00:1f.0 ISA bridge: Intel Corporation QS57 Chipset LPC Interface Controller (rev 05)
00:1f.2 SATA controller: Intel Corporation 5 Series/3400 Series Chipset 6 port SATA AHCI Controller (rev 05)
00:1f.3 SMBus: Intel Corporation 5 Series/3400 Series Chipset SMBus Controller (rev 05)
00:1f.6 Signal processing controller: Intel Corporation 5 Series/3400 Series Chipset Thermal Subsystem (rev 05)
02:00.0 Network controller: Intel Corporation Centrino Wireless-N 1000 [Condor Peak]
03:00.0 Ethernet controller: Qualcomm Atheros AR8151 v1.0 Gigabit Ethernet (rev c0)
ff:00.0 Host bridge: Intel Corporation Core Processor QuickPath Architecture Generic Non-core Registers (rev 05)
ff:00.1 Host bridge: Intel Corporation Core Processor QuickPath Architecture System Address Decoder (rev 05)
ff:02.0 Host bridge: Intel Corporation Core Processor QPI Link 0 (rev 05)
ff:02.1 Host bridge: Intel Corporation 1st Generation Core i3/5/7 Processor QPI Physical 0 (rev 05)
ff:02.2 Host bridge: Intel Corporation 1st Generation Core i3/5/7 Processor Reserved (rev 05)
ff:02.3 Host bridge: Intel Corporation 1st Generation Core i3/5/7 Processor Reserved (rev 05)

As well as the output from cat /proc/bus/input/devices:

I: Bus=0019 Vendor=0000 Product=0001 Version=0000
N: Name="Power Button"
P: Phys=PNP0C0C/button/input0
S: Sysfs=/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:0f/PNP0C0C:00/input/input0
U: Uniq=
H: Handlers=kbd event0 
B: PROP=0
B: EV=3
B: KEY=10000000000000 0

I: Bus=0019 Vendor=0000 Product=0003 Version=0000
N: Name="Sleep Button"
P: Phys=PNP0C0E/button/input0
S: Sysfs=/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:0f/PNP0C0E:00/input/input1
U: Uniq=
H: Handlers=kbd event1 
B: PROP=0
B: EV=3
B: KEY=4000 0 0

I: Bus=0019 Vendor=0000 Product=0005 Version=0000
N: Name="Lid Switch"
P: Phys=PNP0C0D/button/input0
S: Sysfs=/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:0f/PNP0C0D:00/input/input2
U: Uniq=
H: Handlers=event2 
B: PROP=0
B: EV=21
B: SW=1

I: Bus=0019 Vendor=0000 Product=0001 Version=0000
N: Name="Power Button"
P: Phys=LNXPWRBN/button/input0
S: Sysfs=/devices/LNXSYSTM:00/LNXPWRBN:00/input/input3
U: Uniq=
H: Handlers=kbd event3 
B: PROP=0
B: EV=3
B: KEY=10000000000000 0

I: Bus=0011 Vendor=0001 Product=0001 Version=ab41
N: Name="AT Translated Set 2 keyboard"
P: Phys=isa0060/serio0/input0
S: Sysfs=/devices/platform/i8042/serio0/input/input4
U: Uniq=
H: Handlers=sysrq kbd event4 leds 
B: PROP=0
B: EV=120013
B: KEY=402000000 3803078f800d001 feffffdfffefffff fffffffffffffffe
B: MSC=10
B: LED=7

I: Bus=0019 Vendor=0000 Product=0000 Version=0000
N: Name="Ideapad extra buttons"
P: Phys=ideapad/input0
S: Sysfs=/devices/pci0000:00/0000:00:1f.0/PNP0C09:00/VPC2004:00/input/input11
U: Uniq=
H: Handlers=rfkill kbd event7 
B: PROP=0
B: EV=13
B: KEY=81000800100c03 4400000000300000 0 2
B: MSC=10

I: Bus=0003 Vendor=5986 Product=0195 Version=1423
N: Name="Lenovo EasyCamera: Lenovo EasyC"
P: Phys=usb-0000:00:1d.0-1.3/button
S: Sysfs=/devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.3/2-1.3:1.0/input/input12
U: Uniq=
H: Handlers=kbd event8 
B: PROP=0
B: EV=3
B: KEY=100000 0 0 0

I: Bus=0019 Vendor=0000 Product=0006 Version=0000
N: Name="Video Bus"
P: Phys=LNXVIDEO/video/input0
S: Sysfs=/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/LNXVIDEO:00/input/input13
U: Uniq=
H: Handlers=kbd event9 
B: PROP=0
B: EV=3
B: KEY=3e000b00000000 0 0 0

I: Bus=0000 Vendor=0000 Product=0000 Version=0000
N: Name="HDA Intel Mic"
P: Phys=ALSA
S: Sysfs=/devices/pci0000:00/0000:00:1b.0/sound/card0/input14
U: Uniq=
H: Handlers=event10 
B: PROP=0
B: EV=21
B: SW=10

I: Bus=0000 Vendor=0000 Product=0000 Version=0000
N: Name="HDA Intel Headphone"
P: Phys=ALSA
S: Sysfs=/devices/pci0000:00/0000:00:1b.0/sound/card0/input15
U: Uniq=
H: Handlers=event11 
B: PROP=0
B: EV=21
B: SW=4

I: Bus=0003 Vendor=046d Product=c52f Version=0111
N: Name="Logitech USB Receiver"
P: Phys=usb-0000:00:1a.0-1.2/input0
S: Sysfs=/devices/pci0000:00/0000:00:1a.0/usb1/1-1/1-1.2/1-1.2:1.0/0003:046D:C52F.000B/input/input36
U: Uniq=
H: Handlers=mouse0 event5 
B: PROP=0
B: EV=17
B: KEY=ffff0000 0 0 0 0
B: REL=1943
B: MSC=10

I: Bus=0003 Vendor=046d Product=c52f Version=0111
N: Name="Logitech USB Receiver Consumer Control"
P: Phys=usb-0000:00:1a.0-1.2/input1
S: Sysfs=/devices/pci0000:00/0000:00:1a.0/usb1/1-1/1-1.2/1-1.2:1.1/0003:046D:C52F.000C/input/input37
U: Uniq=
H: Handlers=kbd event6 
B: PROP=0
B: EV=1f
B: KEY=300ff 0 0 483ffff17aff32d bf54444600000000 1 130ff38b17c000 677bfad9415fed 9ed68000004400 10000002
B: REL=1040
B: ABS=100000000
B: MSC=10

So, nothing about the touch pad is in there, so from what I understand, I'd have to wait for an update to the kernel that happens to support it. (Correct me if I'm wrong anywhere so far.)

My question would then be: is there a way that I can write my own driver for it? I imagine the answer is somehow "yes", as those that regularly contribute to the Linux codebase pump out drivers all the time. If it is yes, then my follow up questions would be:

  • How difficult of a task is this, for someone who has plenty of C and C-like language development experience, and some embedded development experience, but not any experience developing something like this?
  • What kind of proper documentation/information would I need from Lenovo's side of things?
  • Can anyone suggest links to follow to help with the development process? Even if a driver for this touch pad exists already, I'd like to figure it out myself as well, for learning purposes and the sake of curiosity.
  • To my understanding, this is developing a driver and not necessarily
    modifying Linux / the kernel, so should this theoretically be
    compatible with any distro of Linux OS? Or are there certain
    practices I should take to make it compatible with target OS's?

Hopefully those aren't too many question marks to be annoying. Thanks in advance to anyone that helps out!!!

EDIT

Output of lsusb:

Bus 002 Device 004: ID 5986:0195 Acer, Inc 
Bus 002 Device 003: ID 046d:c52f Logitech, Inc. Unifying Receiver
Bus 002 Device 002: ID 8087:0020 Intel Corp. Integrated Rate Matching Hub
Bus 002 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 001 Device 003: ID 0489:e00d Foxconn / Hon Hai Broadcom Bluetooth 2.1 Device
Bus 001 Device 002: ID 8087:0020 Intel Corp. Integrated Rate Matching Hub
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

Nothing here looks like the touch pad either 🙁

Best Answer

is there a way that I can write my own driver for it?

Yes, of course. Many drivers get written that way.

How difficult of a task is this, for someone who has plenty of C and C-like language development experience, and some embedded development experience, but not any experience developing something like this?

Should be manageable, though you'll have to work your way through how the kernel and the relevant subsystems work. Reading code from existing touchpad drivers should help.

What kind of proper documentation/information would I need from Lenovo's side of things?

Register-level documentation of the touchpad. Which is the hard part, because you are probably not going to get any information from Lenovo.

The alternative is reverse engineering, e.g. an existing Windows driver. This can be very time consuming.

Can anyone suggest links to follow to help with the development process?

Google for something like "linux kernel module tutorial beginner", and variations.

To my understanding, this is developing a driver and not necessarily modifying Linux / the kernel, so should this theoretically be compatible with any distro of Linux OS?

You'll be writing a kernel module ("driver") for a specific Linux kernel version. So this will be compatible with all versions of Linux that have the same API you are using, but we'll have to be changed if the API changes (or won't work for past kernels with a different API).

So, nothing about the touch pad is in there,

The touchpad likely won't be a PCI device. It might connect via USB, via some internal serial port, or even via I2C/SMBUS. Or it might use some proprietary communication method via the EC. You may or may not find hints in the BIOS ACPI tables.

As touchpad connection interfaces are so different, they are one of the most difficult devices to write drivers for, unless you have proper documentation.

Related Question