Diagnosing Problems with Your Tablet and/or Drivers

Before we spend much time outlaying what can go wrong, and where to look at, and how to fix it, ad infinitum, an architectural drawing is in order:

As you can see, your tablet is not controlled by the Aiptek Kernel driver. It actually communicates with the USB Bus System, through either the UHCI or the OHCI hub drivers, and as well through the HID (Human Interface Device) code. Events are delivered through an asychronous callback method in the Aiptek driver, which leverages it's knowledge of the HyperPen tablet protocol to determine what Linux Event Systems they correspond to.

A single message from the tablet delivers several pieces of information at once: at maximum, a single report may create up to 8 separate Linux Input Events (one for X coordinate, another for Y coordinate, pressure, the buttons...) The consumer of the Linux Input Events reads one-to-many events at a time, and passes it's information in a format the client understands.

The kernel driver, then, basically acts as a translator between the two event systems. While the HID system is fairly generalized and self-describing, there are several instances where the driver makes use of vendor- and model-specific knowledge to determine what to do with certain events. Also, the kernel driver abstracts knowledge of how to program the tablet, and provides a programmatic interface that the GUI Front-End component uses to obtain status reports and order tablet reconfiguration (yes, the procfs interface.)

What Can Go Wrong?

In wonderful FAQ fashion:

  1. My tablet is not blinking; I'm getting no events.
  2. Explained in the next question.

  3. I am getting goofy messages out of /var/log/messages, and no events!
  4. Let us start at the USB Bus level. We've seen several UHCI and OHCI hub controllers go out of sync with the tablet. When this occurs, we see messages like "usb-uhci.c: interrupt, status 3, frame# 919" in /var/log/messages. What does that mean? That may mean the tablet is not able to deliver macrokey reports; that may also mean that the tablet is reporting utter garbage (e.g., the maximum X and Y coordinates is "5";) it may mean that no reports are being delivered to the Aiptek driver at all.

    (Sometimes, the tablet itself may become frozen, but it is not a given that the UHCI or OHCI code would notice and be able to complain about that.)

    We do what we can to help you out by keeping a counter of received reports. Yes, we use an unsigned long. Yes, it will eventually wrap back around to 0. No, that is not a bug. The purpose of the counter is to it move as you drag the Stylus across the drawing area. We are not issuing prizes for achieving the highest event-count on a tablet.. :-)

    Sometimes, the best thing to do is try to reboot your tablet. This is not the same thing as plugging and unplugging the tablet (that is another can of worms!) Simply issue a command to the procfs file interface. While it is nice to issue a meaningful command, it just so happens that the parser will give up if it sees a stream it does not understand, and the driver will reprogram the tablet to the current state. (E.g., echo reboot=now > /proc/driver/usb/aiptek, while not a supported command per se, effectively does what you told it to -- reboot the tablet.)

  5. I am getting events being reported by the Aiptek Kernel driver, but XFree86 (or gpm) doesn't seem to react to them.
  6. First of all, remember that the Kernel driver delivers events to the Linux Input Event system. What you do not know is which /dev/input/eventx device entry the events are being presented at. XFree86 currently is informed of its event device name statically, through the XF86Config-4 file; is that file setting right?

    (The Kernel Driver attempts to help out by telling you what it has been told is the event filename, but it too can be fooled. Do you see lots of mousex files? joyx files? That is not a good sign. Rebooting is a good solution.)

    Hopefully, changing the XF86Config-4 file to point to the "right" eventx file is enough.

  7. I am getting events, but it is like they're from a Mouse or something. Then I try to look at the procfs file, but it is not there (sometimes.)
  8. It is HotPlug time! Well, at least, it's HID-time! Sometimes it's USBMgr time...

    First, what does HotPlug and USBMgr do? These utilities dynamically load and unload device drivers for hot pluggable hardware. USB devices, by definition, are hot pluggable. Now, to "know" which driver to load when new hardware is recognized, the software goes through a list of known vendor/product ids, and then as a fallback, relies on HID to query the device.

    Let us first deal with HID: there is no query structure that says, "what are you?" Instead, there are queries such as, "what are you capable of?" Well, tablets are capable of delivering relative X & Y coordinate reports, while reporting on one-to-many buttons. But, that is a mouse!

    Tablets are also capable of reporting on hatswitches, whose analog settings tell it something (the macro keys.) But, that is a joystick!

    It does not necessarily matter that the device is capable of other things, such as absolute coordinates and pressure readings -- but those can be attributes that are also appropriate for a  touchscreen...

    So, the point is, HotPlug and USBMgr can get confused, load a mouse driver, and assign that mouse driver to your tablet. How would you know? Browse your /proc/bus/usb/devices: you should see something like,

    T:  Bus=02 Lev=01 Prnt=01 Port=01 Cnt=01 Dev#=  4 Spd=1.5 MxCh= 0
    D: Ver= 1.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS= 8 #Cfgs= 1
    P: Vendor=08ca ProdID=0020 Rev= 1.00
    S: Manufacturer=AIPTEK
    S: Product=APT-6000U
    C:* #Ifs= 1 Cfg#= 1 Atr=a0 MxPwr= 50mA
    I: If#= 0 Alt= 0 #EPs= 1 Cls=03(HID) Sub=01 Prot=02 Driver=aiptek

    Look at the "Driver=xxx" line above. What driver has been assigned to the tablet? If it is not aiptek, you are in trouble, and thus an explanation for your troubles.

    Now, back to the VendorID/ProductID lookup process. If you look at /lib/modules/xx.yy.zz, you will see the file, modules.usbmap. This file is autogenerated during your kernel build, and lists all USB vendor and product IDs found in device drivers' source code while building the kernel. Here is a line out of my file:

    aiptek               0x0003      0x08ca   0x0010 [snip] 

    Reading this left-to-right, it says that there is a driver named aiptek, which supports a HID device, supports products with a VendorID of 08ca (Aiptek) and has a ProductID of 0x0010. That is good, but there are several ProductIDs which are Aiptek tablets. Ones that we know of are, 0x0001, 0x0010, 0x0020, 0x0021, 0x0022, 0x0023, and 0x0024. If you have them, they will be listed, one per line, as shown (but snipped) in the box above.

    But, what if you discovered a new one? Tell us!  We keep a bug tracker on our project page; please avail yourself of it. How would you know? Look at the "P" line in /proc/bus/usb/devices. Is that a new ProductID? A new VendorID?

    So, you have them all the tablet IDs. Or do you? There's also a static table of known "not-quite-HID" devices embedded in the Linux kernel. (This is what allows events to pass through to the aiptek driver, as opposed to the generic HID driver.) Specifically, it is kept in the file,  ./linux-src-xx.yy.zz/driver/usb/hid-core.c (or driver/usb/input/hid-core.c in 2.5.x.) You will be looking for USB_VENDOR_ID_AIPTEK, and obviously, if your tablet's ProductID is not listed in that table, you will have to fix that and rebuild the kernel.

    How did this happen? Well, I am resorting to guessing, but would have to think that you have the Kernel device driver built by one source tree, running on a kernel built from another source tree. It is bad news, it should not happen, it is why I merge the device driver into the mainstream kernel source tree (so it would not happen,) but...  I can not vouch for how you or your distribution maintainers (maybe also you) roll your kernels and ship new device driver packages.

    Is there more? Oh, yes! In /etc/hotplug, you will find the files, usb.distmap, usb.handmap, usb.usermap, and usb.usermap.local.  They follow the same format as modules.usbmap,  and contain basically the same information (they are just IDs the HotPlug authors have seen in their travels.) Make sure nobody is telling HotPlug to load hidmouse or usbmouse given your VendorID/ProductID!

    Fortunately, USBMgr has been deprecated in favor of HotPlug. Not that this infers it has lesser quality; only that we have less debugging tips to write up. Upgrade first. Then come back here if problems persist.

    Even after fixiing all the files so the VendorID and ProductID are happy, do yourself a favor: boot your machine with the tablet plugged in. Then there's less moving parts to get confused.

  9. My client is expecting Relative coordinates: I programmed the tablet for Relative coordinates, yet I am getting no events.
  10. Time to look at the "diagnostic=" line in /proc/driver/usb/aiptek. Is the tablet still sending Absolute coordinate reports after you told it not to? Are you using the Mouse device after telling the driver you only want to use the Stylus device? (And did you know that we throw out events from the offending device? Yes, there was a reason we put that option in -- so the bad, unwanted events from the other device will be ignored.

    Do something about the "pilot errors"! Maybe the pilot needs a nap.

  11. What tools do you use?
  12. We use evtest, written by Vojtech Pavlik and xinput-1.2, by Frederic Lepied. Evtest reads events from the Linux Input Event system and displays them to the console. Xinput allows us to run X-centric tests (motion, attributes, etc.) We put a copy of evtest into our CVS tree; xinput can be found here: ftp://ftp.x.org/contrib/utilities.

    Get your copies now, while they're still hot!