Re: Apple's Mighty Mouse (patch)

From: Rui Paulo <rpaulo_at_fnop.net>
Date: Thu, 15 Mar 2007 15:44:53 +0000
Rui Paulo wrote:
> Hi,
> 
> The attached patch makes the wheel work correctly with in Apple's Mighty 
> Mouse.

Even better: I synchronized the NetBSD version of ums.c with FreeBSD's. 
  (only regarding to the Z/W axis).
FreeBSD doesn't have mouse(4) support for the W axis but that should be 
easy to add.

The patch is attached.

Thanks in advance.
-- 
Rui Paulo | PGP: F0E4 C7C7 1653 79B7 78DC  DD73 64FA B2C6 CF45 1F84

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
_at__at_ -104,7 +104,7 _at__at_ 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 */
_at__at_ -116,6 +116,7 _at__at_ 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 */
 
_at__at_ -209,7 +210,7 _at__at_ 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;
_at__at_ -266,14 +267,44 _at__at_ 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;
_at__at_ -424,7 +455,7 _at__at_ 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;
 
_at__at_ -474,6 +505,9 _at__at_ 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
_at__at_ -482,16 +516,17 _at__at_ 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
_at__at_ -688,6 +688,7 _at__at_ 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
_at__at_ -1491,6 +1492,7 _at__at_ 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
Received on Thu Mar 15 2007 - 14:45:00 UTC

This archive was generated by hypermail 2.4.0 : Wed May 19 2021 - 11:39:06 UTC