NetBSD-Bugs archive

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

kern/46391: ums.c doesn't support digitizers or touchscreens



>Number:         46391
>Category:       kern
>Synopsis:       ums.c doesn't support digitizers or touchscreens
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    kern-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Mon Apr 30 14:05:00 +0000 2012
>Originator:     Nat Sloss
>Release:        NetBSD Current 6.99.5
>Organization:
>Environment:
NetBSD beast 6.99.5 NetBSD 6.99.5 (LOCKDEBUG) #41: Mon Apr 30 14:13:38 EST 2012 
 build@beast:/usr/src/sys/arch/i386/compile/obj/LOCKDEBUG i386

>Description:
Hi.

I have a laptop with a touchscreen that was supported by ums.c as a usb mouse.  
After upgrading my bios it now reports as a digitizer and was no longer 
supported by ums.c.  And instead of reporting buttons it now reports as tip, 
barrel and eraser switches.
>How-To-Repeat:
Attach a usb digitizer or touch screen and possibly only uhidev attaches.
>Fix:
To fix the problem I modified the match and attach routines of ums.c.

Note: The digitizer type is 0002 which was undefined but I think it means 
digitizer.  This patch is my own work and I submit it under the NetBSD license.

 --- ums.c.orig  2012-01-01 15:46:53.000000000 +1100
+++ ums.c       2012-04-30 22:10:39.000000000 +1000
@@ -118,6 +118,7 @@
        ums_ioctl,
        ums_disable,
 };
+static int is_digitizer = 0;

 int ums_match(device_t, cfdata_t, void *);
 void ums_attach(device_t, device_t, void *);
@@ -147,9 +148,15 @@
        if (!hid_is_collection(desc, size, uha->reportid,
                               HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_MOUSE)) &&
            !hid_is_collection(desc, size, uha->reportid,
-                              HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_POINTER)))
+                              HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_POINTER))
+           && !hid_is_collection(desc, size, uha->reportid,
+                                  HID_USAGE2(HUP_DIGITIZERS, 0x0002)))
                return (UMATCH_NONE);

+       if (hid_is_collection(desc, size, uha->reportid,
+                              HID_USAGE2(HUP_DIGITIZERS, 0x0002)))
+               is_digitizer = 1;
+
        return (UMATCH_IFACECLASS);
 }

@@ -165,6 +172,7 @@
        int i, hl;
        struct hid_location *zloc;
        struct hid_location loc_btn;
+       int tip_sw, tip_sw_sec, barrel_sw, eraser;

        aprint_naive("\n");

@@ -173,6 +181,11 @@
        sc->sc_hdev.sc_parent = uha->parent;
        sc->sc_hdev.sc_report_id = uha->reportid;

+       tip_sw = 0;
+       tip_sw_sec = 0;
+       barrel_sw = 0;
+       eraser = 0;
+
        quirks = usbd_get_quirks(uha->parent->sc_udev)->uq_flags;
        if (quirks & UQ_MS_REVZ)
                sc->flags |= UMS_REVZ;
@@ -302,17 +315,67 @@
                        break;
        sc->nbuttons = i - 1;

+       for (i = 1; i <= sc->nbuttons; i++)
+               hid_locate(desc, size, HID_USAGE2(HUP_BUTTON, i),
+                          uha->reportid, hid_input,
+                          &sc->sc_loc_btn[i-1], 0);
+
+       if (is_digitizer && sc->nbuttons < (MAX_BUTTONS - 4)) {
+               if (hid_locate(desc, size, HID_USAGE2(HUP_DIGITIZERS, 
+                   HUD_TIP_SWITCH),
+                       uha->reportid, hid_input, &loc_btn, 0))
+                       tip_sw = 1;
+
+               if (hid_locate(desc, size, HID_USAGE2(HUP_DIGITIZERS, 
+                   HUD_SEC_TIP_SWITCH),
+                       uha->reportid, hid_input, &loc_btn, 0))
+                       tip_sw_sec = 1;
+
+               if (hid_locate(desc, size, HID_USAGE2(HUP_DIGITIZERS, 
+                   HUD_BARREL_SWITCH),
+                       uha->reportid, hid_input, &loc_btn, 0))
+                       barrel_sw = 1;
+
+               if (hid_locate(desc, size, HID_USAGE2(HUP_DIGITIZERS, 
+                   HUD_ERASER),
+                       uha->reportid, hid_input, &loc_btn, 0))
+                       eraser = 1;
+
+               if (tip_sw) {
+                       sc->nbuttons++;
+                       hid_locate(desc, size, HID_USAGE2(HUP_DIGITIZERS, 
+                           HUD_TIP_SWITCH), uha->reportid, hid_input, 
+                           &sc->sc_loc_btn[sc->nbuttons-1], 0);
+               }
+
+               if (tip_sw_sec) {
+                       sc->nbuttons++;
+                       hid_locate(desc, size, HID_USAGE2(HUP_DIGITIZERS, 
+                           HUD_SEC_TIP_SWITCH), uha->reportid, hid_input, 
+                           &sc->sc_loc_btn[sc->nbuttons-1], 0);
+               }
+
+               if (barrel_sw) {
+                       sc->nbuttons++;
+                       hid_locate(desc, size, HID_USAGE2(HUP_DIGITIZERS, 
+                       HUD_BARREL_SWITCH), uha->reportid, hid_input, 
+                       &sc->sc_loc_btn[sc->nbuttons-1], 0);
+               }
+
+               if (eraser) {
+                       sc->nbuttons++;
+                       hid_locate(desc, size, HID_USAGE2(HUP_DIGITIZERS, 
+                       HUD_ERASER), uha->reportid, hid_input, 
+                       &sc->sc_loc_btn[sc->nbuttons-1], 0);
+               }
+       }
+
        aprint_normal(": %d button%s%s%s%s\n",
            sc->nbuttons, sc->nbuttons == 1 ? "" : "s",
            sc->flags & UMS_W ? ", W" : "",
            sc->flags & UMS_Z ? " and Z dir" : "",
            sc->flags & UMS_W ? "s" : "");

-       for (i = 1; i <= sc->nbuttons; i++)
-               hid_locate(desc, size, HID_USAGE2(HUP_BUTTON, i),
-                          uha->reportid, hid_input,
-                          &sc->sc_loc_btn[i-1], 0);
-
 #ifdef USB_DEBUG
        DPRINTF(("ums_attach: sc=%p\n", sc));
        DPRINTF(("ums_attach: X\t%d/%d\n",

I think it would also be possible to mach against digitizer touchscreens type 
0004.  But I didn't add it as I don't have the hardware to test.

I hope this helps.

Regards,

Nat.



Home | Main Index | Thread Index | Old Index