tech-kern archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

touchpanel support for ums(4)



The following diff adds support for touchpanels to the ums(4) driver.
Touchpanels report the position in absolute coordinates and not as relative
deltas.  The following assumptions are made to keep the changes small:

- If either the X or Y axis reports absolute values, the other axis does, too
- The Z and W axis are never absolute

This makes touchscreens work that report themselves as USB HID devices, e.g.
the touchscreen built into the EeeTOP line of ASUS desktops while not changing
the behaviour of normal USB mice.

Index: sys/dev/usb/ums.c
===================================================================
RCS file: /cvsroot/src/sys/dev/usb/ums.c,v
retrieving revision 1.76
diff -u -p -r1.76 ums.c
--- sys/dev/usb/ums.c   12 Nov 2009 19:58:27 -0000      1.76
+++ sys/dev/usb/ums.c   26 Nov 2009 15:22:53 -0000
@@ -95,6 +95,7 @@ struct ums_softc {
 #define UMS_SPUR_BUT_UP        0x02    /* spurious button up events */
 #define UMS_REVZ       0x04    /* Z-axis is reversed */
 #define UMS_W          0x08    /* w direction/tilt available */
+#define UMS_ABS                0x10    /* absolute position, touchpanel */
 
        int nbuttons;
 
@@ -105,7 +106,6 @@ struct ums_softc {
 };
 
 #define MOUSE_FLAGS_MASK (HIO_CONST|HIO_RELATIVE)
-#define MOUSE_FLAGS (HIO_RELATIVE)
 
 Static void ums_intr(struct uhidev *addr, void *ibuf, u_int len);
 
@@ -180,7 +180,13 @@ ums_attach(device_t parent, device_t sel
                       USBDEVNAME(sc->sc_hdev.sc_dev));
                USB_ATTACH_ERROR_RETURN;
        }
-       if ((flags & MOUSE_FLAGS_MASK) != MOUSE_FLAGS) {
+       switch (flags & MOUSE_FLAGS_MASK) {
+       case 0:
+               sc->flags |= UMS_ABS;
+               break;
+       case HIO_RELATIVE:
+               break;
+       default:
                aprint_error("\n%s: X report 0x%04x not supported\n",
                       USBDEVNAME(sc->sc_hdev.sc_dev), flags);
                USB_ATTACH_ERROR_RETURN;
@@ -192,7 +198,13 @@ ums_attach(device_t parent, device_t sel
                       USBDEVNAME(sc->sc_hdev.sc_dev));
                USB_ATTACH_ERROR_RETURN;
        }
-       if ((flags & MOUSE_FLAGS_MASK) != MOUSE_FLAGS) {
+       switch (flags & MOUSE_FLAGS_MASK) {
+       case 0:
+               sc->flags |= UMS_ABS;
+               break;
+       case HIO_RELATIVE:
+               break;
+       default:
                aprint_error("\n%s: Y report 0x%04x not supported\n",
                       USBDEVNAME(sc->sc_hdev.sc_dev), flags);
                USB_ATTACH_ERROR_RETURN;
@@ -209,7 +221,7 @@ ums_attach(device_t parent, device_t sel
 
        zloc = &sc->sc_loc_z;
        if (hl) {
-               if ((flags & MOUSE_FLAGS_MASK) != MOUSE_FLAGS) {
+               if ((flags & MOUSE_FLAGS_MASK) != HIO_RELATIVE) {
                        aprint_verbose("\n%s: Wheel report 0x%04x not "
                            "supported\n", USBDEVNAME(sc->sc_hdev.sc_dev),
                            flags);
@@ -247,7 +259,7 @@ ums_attach(device_t parent, device_t sel
        }
 
        if (hl) {
-               if ((flags & MOUSE_FLAGS_MASK) != MOUSE_FLAGS) {
+               if ((flags & MOUSE_FLAGS_MASK) != HIO_RELATIVE) {
                        aprint_verbose("\n%s: Z report 0x%04x not supported\n",
                               USBDEVNAME(sc->sc_hdev.sc_dev), flags);
                        zloc->size = 0; /* Bad Z coord, ignore it */
@@ -362,15 +374,21 @@ ums_intr(struct uhidev *addr, void *ibuf
        struct ums_softc *sc = (struct ums_softc *)addr;
        int dx, dy, dz, dw;
        u_int32_t buttons = 0;
-       int i;
-       int s;
+       int i, flags, s;
 
        DPRINTFN(5,("ums_intr: len=%d\n", len));
 
+       flags = WSMOUSE_INPUT_DELTA;    /* equals 0 */
+
        dx =  hid_get_data(ibuf, &sc->sc_loc_x);
-       dy = -hid_get_data(ibuf, &sc->sc_loc_y);
+       if (sc->flags & UMS_ABS) {
+               flags |= (WSMOUSE_INPUT_ABSOLUTE_X | WSMOUSE_INPUT_ABSOLUTE_Y);
+               dy = hid_get_data(ibuf, &sc->sc_loc_y);
+       } else
+               dy = -hid_get_data(ibuf, &sc->sc_loc_y);
        dz =  hid_get_data(ibuf, &sc->sc_loc_z);
        dw =  hid_get_data(ibuf, &sc->sc_loc_w);
+
        if (sc->flags & UMS_REVZ)
                dz = -dz;
        for (i = 0; i < sc->nbuttons; i++)
@@ -384,10 +402,8 @@ ums_intr(struct uhidev *addr, void *ibuf
                sc->sc_buttons = buttons;
                if (sc->sc_wsmousedev != NULL) {
                        s = spltty();
-                       wsmouse_input(sc->sc_wsmousedev,
-                                       buttons,
-                                       dx, dy, dz, dw,
-                                       WSMOUSE_INPUT_DELTA);
+                       wsmouse_input(sc->sc_wsmousedev, buttons, dx, dy, dz,
+                           dw, flags);
                        splx(s);
                }
        }
@@ -434,9 +450,14 @@ ums_ioctl(void *v, u_long cmd, void *dat
     struct lwp * p)
 
 {
+       struct ums_softc *sc = v;
+
        switch (cmd) {
        case WSMOUSEIO_GTYPE:
-               *(u_int *)data = WSMOUSE_TYPE_USB;
+               if (sc->flags & UMS_ABS)
+                       *(u_int *)data = WSMOUSE_TYPE_TPANEL;
+               else
+                       *(u_int *)data = WSMOUSE_TYPE_USB;
                return (0);
        }
 
-- 
Marc Balmer, Micro Systems, Wiesendamm 2a, Postfach, CH-4019 Basel, Switzerland
http://www.msys.ch/     http://www.vnode.ch/   "In God we trust, in C we code."


Home | Main Index | Thread Index | Old Index