vBulletin Search Engine Optimization
| |||||||
| Register | FAQ | Members List | Calendar | Search | Today's Posts | Mark Forums Read |
| ||||
| The following diff adds support for the Microsoft wireless intellimouse and wireless desktop mouse; code is adapted from FreeBSD with changes (we report the fourth axis, `t' in FreeBSD and `w' in OpenBSD, quite differently). I don't have such a piece of hardware; if you do, please test and report whether this works correctly. And if you don't, please test anyway and report any regression. The diff should apply both to 4.2 (with harmless fuzz) and to -CURRENT. Thanks, Miod Index: ums.c ================================================== ================= RCS file: /cvs/src/sys/dev/usb/ums.c,v retrieving revision 1.26 diff -u -p -r1.26 ums.c --- ums.c 2007/09/17 01:40:38 1.26 +++ ums.c 2007/10/18 04:40:15 @@ -99,6 +99,9 @@ struct ums_softc { #define UMS_Z 0x01 /* z direction available */ #define UMS_SPUR_BUT_UP 0x02 /* spurious button up events */ #define UMS_REVZ 0x04 /* Z-axis is reversed */ +#define UMS_W 0x08 /* w direction available */ +#define UMS_REVW 0x10 /* W-axis is reversed */ +#define UMS_LEADINGBYTE 0x20 /* Unknown leading byte */ int nbuttons; @@ -166,7 +169,7 @@ ums_attach(struct device *parent, struct int size; void *desc; u_int32_t flags, quirks; - int i; + int i, wheel, twheel; struct hid_location loc_btn; sc->sc_hdev.sc_intr = ums_intr; @@ -178,6 +181,8 @@ ums_attach(struct device *parent, struct sc->flags |= UMS_REVZ; if (quirks & UQ_SPUR_BUT_UP) sc->flags |= UMS_SPUR_BUT_UP; + if (quirks & UQ_MS_LEADING_BYTE) + sc->flags |= UMS_LEADINGBYTE; uhidev_get_report_desc(uha->parent, &desc, &size); @@ -205,9 +210,22 @@ ums_attach(struct device *parent, struct return; } - /* Try the wheel as Z activator first */ - if (hid_locate(desc, size, HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_WHEEL), - uha->reportid, hid_input, &sc->sc_loc_z, &flags)) { + /* + * Try to guess the Z activator: check WHEEL, TWHEEL, and Z, + * in that order. + */ + + wheel = hid_locate(desc, size, + HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_WHEEL), + uha->reportid, hid_input, &sc->sc_loc_z, &flags); + if (wheel == 0) + twheel = hid_locate(desc, size, + HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_TWHEEL), + uha->reportid, hid_input, &sc->sc_loc_z, &flags); + else + twheel = 0; + + if (wheel || twheel) { if ((flags & MOUSE_FLAGS_MASK) != MOUSE_FLAGS) { DPRINTF(("\n%s: Wheel report 0x%04x not supported\n", sc->sc_hdev.sc_dev.dv_xname, flags)); @@ -230,6 +248,8 @@ ums_attach(struct device *parent, struct /* Bad Z coord, ignore it */ sc->sc_loc_w.size = 0; } + else + sc->flags |= UMS_W; } } else if (hid_locate(desc, size, HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_Z), @@ -243,6 +263,21 @@ ums_attach(struct device *parent, struct } } + /* + * The Microsoft Wireless Intellimouse 2.0 reports its wheel + * using 0x0048 (I've called it HUG_TWHEEL) and seems to expect + * us to know that the byte after the wheel is the tilt axis. + * There are no other HID axis descriptors other than X, Y and + * TWHEEL, so we report TWHEEL on the W axis. + */ + if (twheel) { + sc->sc_loc_w = sc->sc_loc_z; + sc->sc_loc_w.pos = sc->sc_loc_w.pos + 8; + sc->flags |= UMS_W | UMS_LEADINGBYTE; + /* Wheels need their axis reversed. */ + sc->flags ^= UMS_REVW; + } + /* figure out the number of buttons */ for (i = 1; i <= MAX_BUTTONS; i++) if (!hid_locate(desc, size, HID_USAGE2(HUP_BUTTON, i), @@ -250,10 +285,41 @@ ums_attach(struct device *parent, struct break; sc->nbuttons = i - 1; - printf(": %d button%s%s\n", - sc->nbuttons, sc->nbuttons == 1 ? "" : "s", - sc->flags & UMS_Z ? " and Z dir." : ""); + /* + * The Microsoft Wireless Notebook Optical Mouse seems to be in worse + * shape than the Wireless Intellimouse 2.0, as its X, Y, wheel, and + * all of its other button positions are all off. It also reports that + * it has two addional buttons and a tilt wheel. + */ + if (quirks & UQ_MS_BAD_CLASS) { + /* UMS_LEADINGBYTE cleared on purpose */ + sc->flags = UMS_Z | UMS_SPUR_BUT_UP; + sc->nbuttons = 3; + /* XXX change sc_hdev isize to 5? */ + /* 1st byte of descriptor report contains garbage */ + sc->sc_loc_x.pos = 16; + sc->sc_loc_y.pos = 24; + sc->sc_loc_z.pos = 32; + sc->sc_loc_btn[0].pos = 8; + sc->sc_loc_btn[1].pos = 9; + sc->sc_loc_btn[2].pos = 10; + } + printf(": %d button%s", + sc->nbuttons, sc->nbuttons <= 1 ? "" : "s"); + switch (sc->flags & (UMS_Z | UMS_W)) { + case UMS_Z: + printf(", Z dir"); + break; + case UMS_W: + printf(", W dir"); + break; + case UMS_Z | UMS_W: + printf(", Z and W dir"); + break; + } + printf("\n"); + for (i = 1; i <= sc->nbuttons; i++) hid_locate(desc, size, HID_USAGE2(HUP_BUTTON, i), uha->reportid, hid_input, @@ -315,9 +381,10 @@ ums_detach(struct device *self, int flag } void -ums_intr(struct uhidev *addr, void *ibuf, u_int len) +ums_intr(struct uhidev *addr, void *buf, u_int len) { struct ums_softc *sc = (struct ums_softc *)addr; + u_char *ibuf = (u_char *)buf; int dx, dy, dz, dw; u_int32_t buttons = 0; int i; @@ -325,12 +392,37 @@ ums_intr(struct uhidev *addr, void *ibuf DPRINTFN(5,("ums_intr: len=%d\n", len)); + /* + * The Microsoft Wireless Intellimouse 2.0 sends one extra leading + * byte of data compared to most USB mice. This byte frequently + * switches from 0x01 (usual state) to 0x02. It may be used to + * report non-standard events (such as battery life). However, + * at the same time, it generates a left click event on the + * button byte, where there shouldn't be any. We simply discard + * the packet in this case. + * + * This problem affects the MS Wireless Notebook Optical Mouse, too. + * However, the leading byte for this mouse is normally 0x11, and + * the phantom mouse click occurs when it's 0x14. + */ + if (sc->flags & UMS_LEADINGBYTE) { + if (*ibuf++ == 0x02) + return; + /* else + len--; */ + } else if (sc->flags & UMS_SPUR_BUT_UP) { + if (*ibuf == 0x14 || *ibuf == 0x15) + return; + } + 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_REVW) + dw = -dw; for (i = 0; i < sc->nbuttons; i++) if (hid_get_data(ibuf, &sc->sc_loc_btn[i])) buttons |= (1 << UMS_BUT(i)); Index: usb_quirks.c ================================================== ================= RCS file: /cvs/src/sys/dev/usb/usb_quirks.c,v retrieving revision 1.30 diff -u -p -r1.30 usb_quirks.c --- usb_quirks.c 2007/08/28 09:45:46 1.30 +++ usb_quirks.c 2007/10/18 04:40:15 @@ -136,6 +136,15 @@ const struct usbd_quirk_entry { { USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_F6C550AVR, ANY, { UQ_BAD_HID }}, { USB_VENDOR_MGE, USB_PRODUCT_MGE_UPS1, ANY, { UQ_BAD_HID }}, { USB_VENDOR_MGE, USB_PRODUCT_MGE_UPS2, ANY, { UQ_BAD_HID }}, + + /* MS keyboards do weird things */ + { USB_VENDOR_MICROSOFT, USB_PRODUCT_MICROSOFT_WLNOTEBOOK, + ANY, { UQ_MS_BAD_CLASS | UQ_MS_LEADING_BYTE }}, + { USB_VENDOR_MICROSOFT, USB_PRODUCT_MICROSOFT_WLNOTEBOOK2, + ANY, { UQ_MS_BAD_CLASS | UQ_MS_LEADING_BYTE }}, + { USB_VENDOR_MICROSOFT, USB_PRODUCT_MICROSOFT_WLINTELLIMOUSE, + ANY, { UQ_MS_LEADING_BYTE }}, + { 0, 0, 0, { 0 } } }; Index: usb_quirks.h ================================================== ================= RCS file: /cvs/src/sys/dev/usb/usb_quirks.h,v retrieving revision 1.10 diff -u -p -r1.10 usb_quirks.h --- usb_quirks.h 2006/05/14 12:00:04 1.10 +++ usb_quirks.h 2007/10/18 04:40:16 @@ -41,21 +41,40 @@ struct usbd_quirks { u_int32_t uq_flags; /* Device problems: */ -#define UQ_NO_SET_PROTO 0x0001 /* cannot handle SET PROTOCOL. */ -#define UQ_SWAP_UNICODE 0x0002 /* has some Unicode strings swapped. */ -#define UQ_MS_REVZ 0x0004 /* mouse has Z-axis reversed */ -#define UQ_NO_STRINGS 0x0008 /* string descriptors are broken. */ -#define UQ_BAD_ADC 0x0010 /* bad audio spec version number. */ -#define UQ_BUS_POWERED 0x0020 /* device is bus powered, despite claim */ -#define UQ_BAD_AUDIO 0x0040 /* device claims audio class, but isn't */ -#define UQ_SPUR_BUT_UP 0x0080 /* spurious mouse button up events */ -#define UQ_AU_NO_XU 0x0100 /* audio device has broken extension unit */ -#define UQ_POWER_CLAIM 0x0200 /* hub lies about power status */ -#define UQ_AU_NO_FRAC 0x0400 /* don't adjust for fractional samples */ -#define UQ_AU_INP_ASYNC 0x0800 /* input is async despite claim of adaptive */ -#define UQ_ASSUME_CM_OVER_DATA 0x1000 /* modem device breaks on cm over data */ -#define UQ_BROKEN_BIDIR 0x2000 /* printer has broken bidir mode */ -#define UQ_BAD_HID 0x4000 /* device claims uhid, but isn't */ + /* cannot handle SET PROTOCOL. */ +#define UQ_NO_SET_PROTO 0x00000001 + /* has some Unicode strings swapped. */ +#define UQ_SWAP_UNICODE 0x00000002 + /* mouse has Z-axis reversed */ +#define UQ_MS_REVZ 0x00000004 + /* string descriptors are broken. */ +#define UQ_NO_STRINGS 0x00000008 + /* bad audio spec version number. */ +#define UQ_BAD_ADC 0x00000010 + /* device is bus powered, despite claim */ +#define UQ_BUS_POWERED 0x00000020 + /* device claims audio class, but isn't */ +#define UQ_BAD_AUDIO 0x00000040 + /* spurious mouse button up events */ +#define UQ_SPUR_BUT_UP 0x00000080 + /* audio device has broken extension unit */ +#define UQ_AU_NO_XU 0x00000100 + /* hub lies about power status */ +#define UQ_POWER_CLAIM 0x00000200 + /* don't adjust for fractional samples */ +#define UQ_AU_NO_FRAC 0x00000400 + /* input is async despite claim of adaptive */ +#define UQ_AU_INP_ASYNC 0x00000800 + /* modem device breaks on cm over data */ +#define UQ_ASSUME_CM_OVER_DATA 0x00001000 + /* printer has broken bidir mode */ +#define UQ_BROKEN_BIDIR 0x00002000 + /* device claims uhid, but isn't */ +#define UQ_BAD_HID 0x00004000 + /* doesn't identify properly */ +#define UQ_MS_BAD_CLASS 0x00008000 + /* mouse sends an unknown leading byte. */ +#define UQ_MS_LEADING_BYTE 0x00010000 }; extern const struct usbd_quirks usbd_no_quirk; Index: usbdevs ================================================== ================= RCS file: /cvs/src/sys/dev/usb/usbdevs,v retrieving revision 1.302 diff -u -p -r1.302 usbdevs --- usbdevs 2007/10/14 08:29:17 1.302 +++ usbdevs 2007/10/18 04:40:18 @@ -1612,11 +1613,15 @@ product MICROSOFT INTELLIMOUSE 0x0009 In product MICROSOFT NATURALKBD 0x000b Natural product MICROSOFT DDS80 0x0014 Digital Sound System 80 product MICROSOFT SIDEWINDER 0x001a Sidewinder Precision Racing Wheel -product MICROSOFT TBEXPLORER 0x0024 Trackball Explorer +product MICROSOFT TBEXPLORER 0x0024 Trackball Explorer product MICROSOFT INTELLIEYE 0x0025 IntelliEye mouse product MICROSOFT INETPRO 0x002b Internet Keyboard Pro product MICROSOFT MN510 0x006e MN510 Wireless product MICROSOFT MN110 0x007a 10/100 Ethernet +product MICROSOFT WLINTELLIMOUSE 0x008c Wireless Optical IntelliMouse +product MICROSOFT WLNOTEBOOK 0x00b9 Wireless Optical Mouse (Model 1023) +product MICROSOFT WLNOTEBOOK2 0x00e1 Wireless Optical Mouse 3000 (Model 1056) +product MICROSOFT WLUSBMOUSE 0x00b9 Wireless USB Mouse product MICROSOFT XBOX360 0x0292 XBOX 360 WLAN /* Microtech products */ Index: usbdevs.h ================================================== ================= RCS file: /cvs/src/sys/dev/usb/usbdevs.h,v retrieving revision 1.311 diff -u -p -r1.311 usbdevs.h --- usbdevs.h 2007/10/14 08:30:49 1.311 +++ usbdevs.h 2007/10/18 04:40:21 @@ -1624,6 +1625,10 @@ #define USB_PRODUCT_MICROSOFT_INETPRO 0x002b /* Internet Keyboard Pro */ #define USB_PRODUCT_MICROSOFT_MN510 0x006e /* MN510 Wireless */ #define USB_PRODUCT_MICROSOFT_MN110 0x007a /* 10/100 Ethernet */ +#define USB_PRODUCT_MICROSOFT_WLINTELLIMOUSE 0x008c /* Wireless Optical IntelliMouse */ +#define USB_PRODUCT_MICROSOFT_WLNOTEBOOK 0x00b9 /* Wireless Optical Mouse (Model 1023) */ +#define USB_PRODUCT_MICROSOFT_WLNOTEBOOK2 0x00e1 /* Wireless Optical Mouse 3000 (Model 1056) */ +#define USB_PRODUCT_MICROSOFT_WLUSBMOUSE 0x00b9 /* Wireless USB Mouse */ #define USB_PRODUCT_MICROSOFT_XBOX360 0x0292 /* XBOX 360 WLAN */ /* Microtech products */ Index: usbdevs_data.h ================================================== ================= RCS file: /cvs/src/sys/dev/usb/usbdevs_data.h,v retrieving revision 1.308 diff -u -p -r1.308 usbdevs_data.h --- usbdevs_data.h 2007/10/14 08:30:49 1.308 +++ usbdevs_data.h 2007/10/18 04:40:24 @@ -2935,6 +2939,22 @@ const struct usb_known_product usb_known { USB_VENDOR_MICROSOFT, USB_PRODUCT_MICROSOFT_MN110, "10/100 Ethernet", + }, + { + USB_VENDOR_MICROSOFT, USB_PRODUCT_MICROSOFT_WLINTELLIMOUSE, + "Wireless Optical IntelliMouse", + }, + { + USB_VENDOR_MICROSOFT, USB_PRODUCT_MICROSOFT_WLNOTEBOOK, + "Wireless Optical Mouse (Model 1023)", + }, + { + USB_VENDOR_MICROSOFT, USB_PRODUCT_MICROSOFT_WLNOTEBOOK2, + "Wireless Optical Mouse 3000 (Model 1056)", + }, + { + USB_VENDOR_MICROSOFT, USB_PRODUCT_MICROSOFT_WLUSBMOUSE, + "Wireless USB Mouse", }, { USB_VENDOR_MICROSOFT, USB_PRODUCT_MICROSOFT_XBOX360, Index: usbhid.h ================================================== ================= RCS file: /cvs/src/sys/dev/usb/usbhid.h,v retrieving revision 1.10 diff -u -p -r1.10 usbhid.h --- usbhid.h 2007/09/01 17:06:26 1.10 +++ usbhid.h 2007/10/18 04:40:25 @@ -124,6 +124,7 @@ typedef struct usb_hid_descriptor { #define HUG_VBRY 0x0044 #define HUG_VBRZ 0x0045 #define HUG_VNO 0x0046 +#define HUG_TWHEEL 0x0048 #define HUG_SYSTEM_CONTROL 0x0080 #define HUG_SYSTEM_POWER_DOWN 0x0081 #define HUG_SYSTEM_SLEEP 0x0082 |