usb/110349: Support for USB mouses with W axis and inverted Z axis

Rui Paulo rpaulo at fnop.net
Thu Mar 15 18:50:04 UTC 2007


>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
rpaulo at macbook.local:/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:


More information about the freebsd-usb mailing list