>Number:         110349
>Category:       usb
>Synopsis:       Support for USB mouses with W axis and inverted Z axis
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    freebsd-usb
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Thu Mar 15 18:50:03 GMT 2007
>Closed-Date:
>Last-Modified:
>Originator:     Rui Paulo
>Release:        FreeBSD 7.0-CURRENT i386
>Organization:
N/A
>Environment:
System: FreeBSD macbook.local 7.0-CURRENT FreeBSD 7.0-CURRENT #15: Thu
Mar 15 01:26:27 WET 2007
[EMAIL PROTECTED]:/usr/obj/usr/src/sys/MACBOOK i386


        
>Description:

FreeBSD lacks the NetBSD changes in sys/dev/usb/ums.c that make USB mouses
with W axis (horizontal scroll) work (like the Apple Mighty mouse).
This patch also makes USB mouses with inverted Z Axis work.

Note that to make the W axis work, one has to make sysmouse understand it
and teach it too to X11.

>How-To-Repeat:

Plug a Apple Mighty Mouse. You'll notice that the horizontal scroll is
mapped to the
vertical scroll.

>Fix:

The following patch syncs ums.c with NetBSD (only the Z Axis differences were
done):

Index: ums.c
===================================================================
RCS file: /home/ncvs/src/sys/dev/usb/ums.c,v
retrieving revision 1.83
diff -u -p -r1.83 ums.c
--- ums.c       17 Jan 2007 03:50:45 -0000      1.83
+++ ums.c       15 Mar 2007 15:36:35 -0000
@@ -104,7 +104,7 @@ struct ums_softc {
        u_char *sc_ibuf;
        u_int8_t sc_iid;
        int sc_isize;
-       struct hid_location sc_loc_x, sc_loc_y, sc_loc_z, sc_loc_t;
+       struct hid_location sc_loc_x, sc_loc_y, sc_loc_z, sc_loc_t, sc_loc_w;
        struct hid_location *sc_loc_btn;

        usb_callout_t callout_handle;   /* for spurious button ups */
@@ -116,6 +116,7 @@ struct ums_softc {
 #define UMS_Z          0x01    /* z direction available */
 #define UMS_SPUR_BUT_UP        0x02    /* spurious button up events */
 #define UMS_T          0x04    /* aa direction available (tilt) */
+#define        UMS_REVZ        0x08    /* Z-axis is reversed */
        int nbuttons;
 #define MAX_BUTTONS    31      /* chosen because sc_buttons is int */

@@ -209,7 +210,7 @@ USB_ATTACH(ums)
        usbd_status err;
        char devinfo[1024];
        u_int32_t flags;
-       int i;
+       int i, wheel;
        struct hid_location loc_btn;

        sc->sc_disconnected = 1;
@@ -266,14 +267,44 @@ USB_ATTACH(ums)
                USB_ATTACH_ERROR_RETURN;
        }

-       /* try to guess the Z activator: first check Z, then WHEEL */
-       if (hid_locate(desc, size, HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_Z),
-                      hid_input, &sc->sc_loc_z, &flags) ||
-           hid_locate(desc, size, HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_WHEEL),
-                      hid_input, &sc->sc_loc_z, &flags) ||
-           hid_locate(desc, size, HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_TWHEEL),
-                      hid_input, &sc->sc_loc_z, &flags)) {
+       /* Try the wheel first as the Z activator since it's tradition. */
+       wheel = hid_locate(desc, size, HID_USAGE2(HUP_GENERIC_DESKTOP,
+                                                 HUG_WHEEL),
+                           hid_input, &sc->sc_loc_z, &flags);
+
+       if (wheel) {
+               if ((flags & MOUSE_FLAGS_MASK) != MOUSE_FLAGS) {
+                       printf("\n%s: Wheel report 0x%04x not supported\n",
+                              device_get_nameunit(sc->sc_dev), flags);
+                       sc->sc_loc_z.size = 0;  /* Bad Z coord, ignore it */
+               } else {
+                       sc->flags |= UMS_Z;
+                       if (!(uaa->vendor == USB_VENDOR_APPLE &&
+                           uaa->product == USB_PRODUCT_APPLE_OPTICALM)) {
+                               /* Some wheels need the Z axis reversed. */
+                               sc->flags |= UMS_REVZ;
+                       }
+
+               }
+               /*
+                * We might have both a wheel and Z direction, if so put
+                * put the Z on the W coordinate.
+                */
+               if (hid_locate(desc, size, HID_USAGE2(HUP_GENERIC_DESKTOP,
+                                                     HUG_Z),
+                               hid_input, &sc->sc_loc_w, &flags)) {
+                       if ((flags & MOUSE_FLAGS_MASK) != MOUSE_FLAGS) {
+                               printf("\n%s: Z report 0x%04x not supported\n",
+                                      device_get_nameunit(sc->sc_dev), flags);
+                               sc->sc_loc_w.size = 0;  /* Bad Z, ignore */
+                       }
+               }
+       } else if (hid_locate(desc, size, HID_USAGE2(HUP_GENERIC_DESKTOP,
+                                                    HUG_Z),
+                              hid_input, &sc->sc_loc_z, &flags)) {
                if ((flags & MOUSE_FLAGS_MASK) != MOUSE_FLAGS) {
+                       printf("\n%s: Z report 0x%04x not supported\n",
+                              device_get_nameunit(sc->sc_dev), flags);
                        sc->sc_loc_z.size = 0;  /* Bad Z coord, ignore it */
                } else {
                        sc->flags |= UMS_Z;
@@ -424,7 +455,7 @@ ums_intr(xfer, addr, status)
 {
        struct ums_softc *sc = addr;
        u_char *ibuf;
-       int dx, dy, dz, dt;
+       int dx, dy, dz, dw, dt;
        int buttons = 0;
        int i;

@@ -474,6 +505,9 @@ ums_intr(xfer, addr, status)
        dx =  hid_get_data(ibuf, &sc->sc_loc_x);
        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;
        if (sc->flags & UMS_T)
                dt = -hid_get_data(ibuf, &sc->sc_loc_t);
        else
@@ -482,16 +516,17 @@ ums_intr(xfer, addr, status)
                if (hid_get_data(ibuf, &sc->sc_loc_btn[i]))
                        buttons |= (1 << UMS_BUT(i));

-       if (dx || dy || dz || dt || (sc->flags & UMS_Z)
+       if (dx || dy || dz || dt || dw || (sc->flags & UMS_Z)
            || buttons != sc->status.button) {
-               DPRINTFN(5, ("ums_intr: x:%d y:%d z:%d t:%d buttons:0x%x\n",
-                       dx, dy, dz, dt, buttons));
+               DPRINTFN(5, ("ums_intr: x:%d y:%d z:%d w:%d t:%d 
buttons:0x%x\n",
+                       dx, dy, dz, dw, dt, buttons));

                sc->status.button = buttons;
                sc->status.dx += dx;
                sc->status.dy += dy;
                sc->status.dz += dz;
-               /* sc->status.dt += dt;*/ /* no way to export this yet */
+               /* sc->status.dt += dt; */ /* no way to export this yet */
+               /* sc->status.dw += dw; */ /* idem */
                
                /* Discard data in case of full buffer */
                if (sc->qcount == sizeof(sc->qbuf)) {
Index: usbdevs
===================================================================
RCS file: /home/ncvs/src/sys/dev/usb/usbdevs,v
retrieving revision 1.288
diff -u -p -r1.288 usbdevs
--- usbdevs     27 Feb 2007 22:27:53 -0000      1.288
+++ usbdevs     15 Mar 2007 15:36:36 -0000
@@ -688,6 +688,7 @@ product APPLE IPOD_07               0x1207  iPod '07'
 product APPLE IPOD_08          0x1208  iPod '08'
 product APPLE IPODVIDEO                0x1209  iPod Video
 product APPLE IPODNANO         0x120a  iPod Nano
+product        APPLE OPTICALM          0x0304  Apple Optical USB Mouse

 /* Arkmicro Technologies */
 product ARKMICRO ARK3116       0x0232  ARK3116 Serial
@@ -1491,6 +1492,7 @@ product PRIMAX COMFORT            0x4d01  Comfort
 product PRIMAX MOUSEINABOX     0x4d02  Mouse-in-a-Box
 product PRIMAX PCGAUMS1                0x4d04  Sony PCGA-UMS1

+
 /* Prolific products */
 product PROLIFIC PL2301                0x0000  PL2301 Host-Host interface
 product PROLIFIC PL2302                0x0001  PL2302 Host-Host interface
>Release-Note:
>Audit-Trail:
>Unformatted:
_______________________________________________
freebsd-usb@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-usb
To unsubscribe, send any mail to "[EMAIL PROTECTED]"

Reply via email to