From owner-svn-src-head@freebsd.org Tue Nov 10 09:27:53 2015 Return-Path: Delivered-To: svn-src-head@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id EE3C9A2AE9F; Tue, 10 Nov 2015 09:27:53 +0000 (UTC) (envelope-from hselasky@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id B3F5E14AF; Tue, 10 Nov 2015 09:27:53 +0000 (UTC) (envelope-from hselasky@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id tAA9RqHj058102; Tue, 10 Nov 2015 09:27:52 GMT (envelope-from hselasky@FreeBSD.org) Received: (from hselasky@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id tAA9RqmV058100; Tue, 10 Nov 2015 09:27:52 GMT (envelope-from hselasky@FreeBSD.org) Message-Id: <201511100927.tAA9RqmV058100@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: hselasky set sender to hselasky@FreeBSD.org using -f From: Hans Petter Selasky Date: Tue, 10 Nov 2015 09:27:52 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r290639 - in head/sys/dev/usb: . input X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 10 Nov 2015 09:27:54 -0000 Author: hselasky Date: Tue Nov 10 09:27:52 2015 New Revision: 290639 URL: https://svnweb.freebsd.org/changeset/base/290639 Log: Update the wsp driver to support newer touch pads, like found in MacBookPro11,4 and MacBook12,1. This update adds support for the force touch parameter. PR: 204420 MFC after: 1 week Modified: head/sys/dev/usb/input/wsp.c head/sys/dev/usb/usbdevs Modified: head/sys/dev/usb/input/wsp.c ============================================================================== --- head/sys/dev/usb/input/wsp.c Tue Nov 10 08:39:07 2015 (r290638) +++ head/sys/dev/usb/input/wsp.c Tue Nov 10 09:27:52 2015 (r290639) @@ -94,8 +94,8 @@ static struct wsp_tuning { .z_factor = 5, .pressure_touch_threshold = 50, .pressure_untouch_threshold = 10, - .pressure_tap_threshold = 100, - .scr_hor_threshold = 10, + .pressure_tap_threshold = 120, + .scr_hor_threshold = 20, }; static void @@ -122,8 +122,6 @@ SYSCTL_INT(_hw_usb_wsp, OID_AUTO, pressu SYSCTL_INT(_hw_usb_wsp, OID_AUTO, scr_hor_threshold, CTLFLAG_RWTUN, &wsp_tuning.scr_hor_threshold, 0, "horizontal scrolling threshold"); -#define WSP_IFACE_INDEX 1 - /* * Some tables, structures, definitions and constant values for the * touchpad protocol has been copied from Linux's @@ -155,21 +153,30 @@ struct bt_data { enum tp_type { TYPE1, /* plain trackpad */ TYPE2, /* button integrated in trackpad */ - TYPE3 /* additional header fields since June 2013 */ + TYPE3, /* additional header fields since June 2013 */ + TYPE4 /* additional header field for pressure data */ }; /* trackpad finger data offsets, le16-aligned */ #define FINGER_TYPE1 (13 * 2) #define FINGER_TYPE2 (15 * 2) #define FINGER_TYPE3 (19 * 2) +#define FINGER_TYPE4 (23 * 2) /* trackpad button data offsets */ #define BUTTON_TYPE2 15 #define BUTTON_TYPE3 23 +#define BUTTON_TYPE4 31 /* list of device capability bits */ #define HAS_INTEGRATED_BUTTON 1 +/* trackpad finger data block size */ +#define FSIZE_TYPE1 (14 * 2) +#define FSIZE_TYPE2 (14 * 2) +#define FSIZE_TYPE3 (14 * 2) +#define FSIZE_TYPE4 (15 * 2) + /* trackpad finger header - little endian */ struct tp_header { uint8_t flag; @@ -197,9 +204,10 @@ struct tp_finger { int16_t orientation; /* 16384 when point, else 15 bit angle */ int16_t touch_major; /* touch area, major axis */ int16_t touch_minor; /* touch area, minor axis */ - int16_t unused[3]; /* zeros */ + int16_t unused[2]; /* zeros */ + int16_t pressure; /* pressure on forcetouch touchpad */ int16_t multi; /* one finger: varies, more fingers: - * constant */ + * constant */ } __packed; /* trackpad finger data size, empirically at least ten fingers */ @@ -207,7 +215,7 @@ struct tp_finger { #define SIZEOF_FINGER sizeof(struct tp_finger) #define SIZEOF_ALL_FINGERS (MAX_FINGERS * SIZEOF_FINGER) -#if (WSP_BUFFER_MAX < ((MAX_FINGERS * 14 * 2) + FINGER_TYPE3)) +#if (WSP_BUFFER_MAX < ((MAX_FINGERS * FSIZE_TYPE4) + FINGER_TYPE4)) #error "WSP_BUFFER_MAX is too small" #endif @@ -224,6 +232,7 @@ enum { WSP_FLAG_WELLSPRING7, WSP_FLAG_WELLSPRING7A, WSP_FLAG_WELLSPRING8, + WSP_FLAG_WELLSPRING9, WSP_FLAG_MAX, }; @@ -231,69 +240,213 @@ enum { struct wsp_dev_params { uint8_t caps; /* device capability bitmask */ uint8_t tp_type; /* type of trackpad interface */ + uint8_t tp_button; /* offset to button data */ uint8_t tp_offset; /* offset to trackpad finger data */ + uint8_t tp_fsize; /* bytes in single finger block */ + uint8_t tp_delta; /* offset from header to finger struct */ + uint8_t iface_index; + uint8_t um_size; /* usb control message length */ + uint8_t um_req_val; /* usb control message value */ + uint8_t um_req_idx; /* usb control message index */ + uint8_t um_switch_idx; /* usb control message mode switch index */ + uint8_t um_switch_on; /* usb control message mode switch on */ + uint8_t um_switch_off; /* usb control message mode switch off */ }; static const struct wsp_dev_params wsp_dev_params[WSP_FLAG_MAX] = { [WSP_FLAG_WELLSPRING1] = { .caps = 0, .tp_type = TYPE1, + .tp_button = 0, .tp_offset = FINGER_TYPE1, + .tp_fsize = FSIZE_TYPE1, + .tp_delta = 0, + .iface_index = 0, + .um_size = 8, + .um_req_val = 0x03, + .um_req_idx = 0x00, + .um_switch_idx = 0, + .um_switch_on = 0x01, + .um_switch_off = 0x08, }, [WSP_FLAG_WELLSPRING2] = { .caps = 0, .tp_type = TYPE1, + .tp_button = 0, .tp_offset = FINGER_TYPE1, + .tp_fsize = FSIZE_TYPE1, + .tp_delta = 0, + .iface_index = 0, + .um_size = 8, + .um_req_val = 0x03, + .um_req_idx = 0x00, + .um_switch_idx = 0, + .um_switch_on = 0x01, + .um_switch_off = 0x08, }, [WSP_FLAG_WELLSPRING3] = { .caps = HAS_INTEGRATED_BUTTON, .tp_type = TYPE2, + .tp_button = BUTTON_TYPE2, .tp_offset = FINGER_TYPE2, + .tp_fsize = FSIZE_TYPE2, + .tp_delta = 0, + .iface_index = 0, + .um_size = 8, + .um_req_val = 0x03, + .um_req_idx = 0x00, + .um_switch_idx = 0, + .um_switch_on = 0x01, + .um_switch_off = 0x08, }, [WSP_FLAG_WELLSPRING4] = { .caps = HAS_INTEGRATED_BUTTON, .tp_type = TYPE2, + .tp_button = BUTTON_TYPE2, .tp_offset = FINGER_TYPE2, + .tp_fsize = FSIZE_TYPE2, + .tp_delta = 0, + .iface_index = 0, + .um_size = 8, + .um_req_val = 0x03, + .um_req_idx = 0x00, + .um_switch_idx = 0, + .um_switch_on = 0x01, + .um_switch_off = 0x08, }, [WSP_FLAG_WELLSPRING4A] = { .caps = HAS_INTEGRATED_BUTTON, .tp_type = TYPE2, + .tp_button = BUTTON_TYPE2, .tp_offset = FINGER_TYPE2, + .tp_fsize = FSIZE_TYPE2, + .tp_delta = 0, + .iface_index = 0, + .um_size = 8, + .um_req_val = 0x03, + .um_req_idx = 0x00, + .um_switch_idx = 0, + .um_switch_on = 0x01, + .um_switch_off = 0x08, }, [WSP_FLAG_WELLSPRING5] = { .caps = HAS_INTEGRATED_BUTTON, .tp_type = TYPE2, + .tp_button = BUTTON_TYPE2, .tp_offset = FINGER_TYPE2, + .tp_fsize = FSIZE_TYPE2, + .tp_delta = 0, + .iface_index = 0, + .um_size = 8, + .um_req_val = 0x03, + .um_req_idx = 0x00, + .um_switch_idx = 0, + .um_switch_on = 0x01, + .um_switch_off = 0x08, }, [WSP_FLAG_WELLSPRING6] = { .caps = HAS_INTEGRATED_BUTTON, .tp_type = TYPE2, + .tp_button = BUTTON_TYPE2, .tp_offset = FINGER_TYPE2, + .tp_fsize = FSIZE_TYPE2, + .tp_delta = 0, + .iface_index = 0, + .um_size = 8, + .um_req_val = 0x03, + .um_req_idx = 0x00, + .um_switch_idx = 0, + .um_switch_on = 0x01, + .um_switch_off = 0x08, }, [WSP_FLAG_WELLSPRING5A] = { .caps = HAS_INTEGRATED_BUTTON, .tp_type = TYPE2, + .tp_button = BUTTON_TYPE2, .tp_offset = FINGER_TYPE2, + .tp_fsize = FSIZE_TYPE2, + .tp_delta = 0, + .iface_index = 0, + .um_size = 8, + .um_req_val = 0x03, + .um_req_idx = 0x00, + .um_switch_idx = 0, + .um_switch_on = 0x01, + .um_switch_off = 0x08, }, [WSP_FLAG_WELLSPRING6A] = { .caps = HAS_INTEGRATED_BUTTON, .tp_type = TYPE2, + .tp_button = BUTTON_TYPE2, .tp_offset = FINGER_TYPE2, + .tp_fsize = FSIZE_TYPE2, + .tp_delta = 0, + .um_size = 8, + .um_req_val = 0x03, + .um_req_idx = 0x00, + .um_switch_idx = 0, + .um_switch_on = 0x01, + .um_switch_off = 0x08, }, [WSP_FLAG_WELLSPRING7] = { .caps = HAS_INTEGRATED_BUTTON, .tp_type = TYPE2, + .tp_button = BUTTON_TYPE2, .tp_offset = FINGER_TYPE2, + .tp_fsize = FSIZE_TYPE2, + .tp_delta = 0, + .iface_index = 0, + .um_size = 8, + .um_req_val = 0x03, + .um_req_idx = 0x00, + .um_switch_idx = 0, + .um_switch_on = 0x01, + .um_switch_off = 0x08, }, [WSP_FLAG_WELLSPRING7A] = { .caps = HAS_INTEGRATED_BUTTON, .tp_type = TYPE2, + .tp_button = BUTTON_TYPE2, .tp_offset = FINGER_TYPE2, + .tp_fsize = FSIZE_TYPE2, + .tp_delta = 0, + .iface_index = 0, + .um_size = 8, + .um_req_val = 0x03, + .um_req_idx = 0x00, + .um_switch_idx = 0, + .um_switch_on = 0x01, + .um_switch_off = 0x08, }, [WSP_FLAG_WELLSPRING8] = { .caps = HAS_INTEGRATED_BUTTON, .tp_type = TYPE3, + .tp_button = BUTTON_TYPE3, .tp_offset = FINGER_TYPE3, + .tp_fsize = FSIZE_TYPE3, + .tp_delta = 0, + .iface_index = 0, + .um_size = 8, + .um_req_val = 0x03, + .um_req_idx = 0x00, + .um_switch_idx = 0, + .um_switch_on = 0x01, + .um_switch_off = 0x08, + }, + [WSP_FLAG_WELLSPRING9] = { + .caps = HAS_INTEGRATED_BUTTON, + .tp_type = TYPE4, + .tp_button = BUTTON_TYPE4, + .tp_offset = FINGER_TYPE4, + .tp_fsize = FSIZE_TYPE4, + .tp_delta = 2, + .iface_index = 2, + .um_size = 2, + .um_req_val = 0x03, + .um_req_idx = 0x02, + .um_switch_idx = 1, + .um_switch_on = 0x01, + .um_switch_off = 0x00, }, }; @@ -346,7 +499,7 @@ static const STRUCT_USB_HOST_ID wsp_devs WSP_DEV(APPLE, WELLSPRING5A_JIS, WSP_FLAG_WELLSPRING5A), /* MacbookPro10,1 (unibody, June 2012) */ - /* MacbookPro11,? (unibody, June 2013) */ + /* MacbookPro11,1-3 (unibody, June 2013) */ WSP_DEV(APPLE, WELLSPRING7_ANSI, WSP_FLAG_WELLSPRING7), WSP_DEV(APPLE, WELLSPRING7_ISO, WSP_FLAG_WELLSPRING7), WSP_DEV(APPLE, WELLSPRING7_JIS, WSP_FLAG_WELLSPRING7), @@ -360,6 +513,11 @@ static const STRUCT_USB_HOST_ID wsp_devs WSP_DEV(APPLE, WELLSPRING8_ANSI, WSP_FLAG_WELLSPRING8), WSP_DEV(APPLE, WELLSPRING8_ISO, WSP_FLAG_WELLSPRING8), WSP_DEV(APPLE, WELLSPRING8_JIS, WSP_FLAG_WELLSPRING8), + + /* MacbookPro12,1 MacbookPro11,4 */ + WSP_DEV(APPLE, WELLSPRING9_ANSI, WSP_FLAG_WELLSPRING9), + WSP_DEV(APPLE, WELLSPRING9_ISO, WSP_FLAG_WELLSPRING9), + WSP_DEV(APPLE, WELLSPRING9_JIS, WSP_FLAG_WELLSPRING9), }; #define WSP_FIFO_BUF_SIZE 8 /* bytes */ @@ -421,11 +579,6 @@ struct wsp_softc { uint8_t tp_data[WSP_BUFFER_MAX] __aligned(4); /* trackpad transferred data */ }; -typedef enum interface_mode { - RAW_SENSOR_MODE = 0x01, - HID_MODE = 0x08 -} interface_mode; - /* * function prototypes */ @@ -473,14 +626,19 @@ static const struct usb_config wsp_confi }; static usb_error_t -wsp_set_device_mode(struct wsp_softc *sc, interface_mode mode) +wsp_set_device_mode(struct wsp_softc *sc, uint8_t on) { + const struct wsp_dev_params *params = sc->sc_params; uint8_t mode_bytes[8]; usb_error_t err; + /* Type 3 does not require a mode switch */ + if (params->tp_type == TYPE3) + return 0; + err = usbd_req_get_report(sc->sc_usb_device, NULL, - mode_bytes, sizeof(mode_bytes), 0, - 0x03, 0x00); + mode_bytes, params->um_size, params->iface_index, + params->um_req_val, params->um_req_idx); if (err != USB_ERR_NORMAL_COMPLETION) { DPRINTF("Failed to read device mode (%d)\n", err); @@ -495,11 +653,12 @@ wsp_set_device_mode(struct wsp_softc *sc */ pause("WHW", hz / 4); - mode_bytes[0] = mode; + mode_bytes[params->um_switch_idx] = + on ? params->um_switch_on : params->um_switch_off; return (usbd_req_set_report(sc->sc_usb_device, NULL, - mode_bytes, sizeof(mode_bytes), 0, - 0x03, 0x00)); + mode_bytes, params->um_size, params->iface_index, + params->um_req_val, params->um_req_idx)); } static int @@ -524,17 +683,29 @@ static int wsp_probe(device_t self) { struct usb_attach_arg *uaa = device_get_ivars(self); + struct usb_interface_descriptor *id; + struct usb_interface *iface; + uint8_t i; if (uaa->usb_mode != USB_MODE_HOST) return (ENXIO); - if (uaa->info.bIfaceIndex != WSP_IFACE_INDEX) - return (ENXIO); - - if ((uaa->info.bInterfaceClass != UICLASS_HID) || - (uaa->info.bInterfaceProtocol != 0)) + /* figure out first interface matching */ + for (i = 1;; i++) { + iface = usbd_get_iface(uaa->device, i); + if (iface == NULL || i == 3) + return (ENXIO); + id = iface->idesc; + if ((id == NULL) || + (id->bInterfaceClass != UICLASS_HID) || + (id->bInterfaceProtocol != 0 && + id->bInterfaceProtocol != UIPROTO_MOUSE)) + continue; + break; + } + /* check if we are attaching to the first match */ + if (uaa->info.bIfaceIndex != i) return (ENXIO); - return (usbd_lookup_id_by_uaa(wsp_devs, sizeof(wsp_devs), uaa)); } @@ -569,6 +740,9 @@ wsp_attach(device_t dev) sc->sc_usb_device = uaa->device; + /* get device specific configuration */ + sc->sc_params = wsp_dev_params + USB_GET_DRIVER_INFO(uaa); + /* * By default the touchpad behaves like a HID device, sending * packets with reportID = 8. Such reports contain only @@ -584,13 +758,13 @@ wsp_attach(device_t dev) * device back into HID mode before switching it to RAW * mode. Else the device does not work like expected. */ - err = wsp_set_device_mode(sc, HID_MODE); + err = wsp_set_device_mode(sc, 0); if (err != USB_ERR_NORMAL_COMPLETION) { DPRINTF("Failed to set mode to HID MODE (%d)\n", err); return (ENXIO); } - err = wsp_set_device_mode(sc, RAW_SENSOR_MODE); + err = wsp_set_device_mode(sc, 1); if (err != USB_ERR_NORMAL_COMPLETION) { DPRINTF("failed to set mode to RAW MODE (%d)\n", err); return (ENXIO); @@ -598,9 +772,6 @@ wsp_attach(device_t dev) mtx_init(&sc->sc_mutex, "wspmtx", NULL, MTX_DEF | MTX_RECURSE); - /* get device specific configuration */ - sc->sc_params = wsp_dev_params + USB_GET_DRIVER_INFO(uaa); - err = usbd_transfer_setup(uaa->device, &uaa->info.bIfaceIndex, sc->sc_xfer, wsp_config, WSP_N_TRANSFER, sc, &sc->sc_mutex); @@ -642,7 +813,7 @@ wsp_detach(device_t dev) { struct wsp_softc *sc = device_get_softc(dev); - (void) wsp_set_device_mode(sc, HID_MODE); + (void) wsp_set_device_mode(sc, 0); mtx_lock(&sc->sc_mutex); if (sc->sc_state & WSP_ENABLED) @@ -692,6 +863,13 @@ wsp_intr_callback(struct usb_xfer *xfer, pc = usbd_xfer_get_frame(xfer, 0); usbd_copy_out(pc, 0, sc->tp_data, len); + if ((len < params->tp_offset + params->tp_fsize) || + ((len - params->tp_offset) % params->tp_fsize) != 0) { + DPRINTFN(WSP_LLEVEL_INFO, "Invalid length: %d, %x, %x\n", + len, sc->tp_data[0], sc->tp_data[1]); + goto tr_setup; + } + if (len < sc->tp_datalen) { /* make sure we don't process old data */ memset(sc->tp_data + len, 0, sc->tp_datalen - len); @@ -699,12 +877,9 @@ wsp_intr_callback(struct usb_xfer *xfer, h = (struct tp_header *)(sc->tp_data); - if (params->tp_type == TYPE2) { - ibt = sc->tp_data[BUTTON_TYPE2]; - ntouch = sc->tp_data[BUTTON_TYPE2 - 1]; - } else if (params->tp_type == TYPE3) { - ibt = sc->tp_data[BUTTON_TYPE3]; - ntouch = sc->tp_data[BUTTON_TYPE3 - 1]; + if (params->tp_type >= TYPE2) { + ibt = sc->tp_data[params->tp_button]; + ntouch = sc->tp_data[params->tp_button - 1]; } /* range check */ if (ntouch < 0) @@ -712,33 +887,33 @@ wsp_intr_callback(struct usb_xfer *xfer, else if (ntouch > MAX_FINGERS) ntouch = MAX_FINGERS; - f = (struct tp_finger *)(sc->tp_data + params->tp_offset); - for (i = 0; i != ntouch; i++) { + f = (struct tp_finger *)(sc->tp_data + params->tp_offset + params->tp_delta + i * params->tp_fsize); /* swap endianness, if any */ if (le16toh(0x1234) != 0x1234) { - f[i].origin = le16toh((uint16_t)f[i].origin); - f[i].abs_x = le16toh((uint16_t)f[i].abs_x); - f[i].abs_y = le16toh((uint16_t)f[i].abs_y); - f[i].rel_x = le16toh((uint16_t)f[i].rel_x); - f[i].rel_y = le16toh((uint16_t)f[i].rel_y); - f[i].tool_major = le16toh((uint16_t)f[i].tool_major); - f[i].tool_minor = le16toh((uint16_t)f[i].tool_minor); - f[i].orientation = le16toh((uint16_t)f[i].orientation); - f[i].touch_major = le16toh((uint16_t)f[i].touch_major); - f[i].touch_minor = le16toh((uint16_t)f[i].touch_minor); - f[i].multi = le16toh((uint16_t)f[i].multi); + f->origin = le16toh((uint16_t)f->origin); + f->abs_x = le16toh((uint16_t)f->abs_x); + f->abs_y = le16toh((uint16_t)f->abs_y); + f->rel_x = le16toh((uint16_t)f->rel_x); + f->rel_y = le16toh((uint16_t)f->rel_y); + f->tool_major = le16toh((uint16_t)f->tool_major); + f->tool_minor = le16toh((uint16_t)f->tool_minor); + f->orientation = le16toh((uint16_t)f->orientation); + f->touch_major = le16toh((uint16_t)f->touch_major); + f->touch_minor = le16toh((uint16_t)f->touch_minor); + f->pressure = le16toh((uint16_t)f->pressure); + f->multi = le16toh((uint16_t)f->multi); } - DPRINTFN(WSP_LLEVEL_INFO, "[%d]ibt=%d, taps=%d, u=%x, o=%4d, ax=%5d, ay=%5d, " - "rx=%5d, ry=%5d, tlmaj=%4d, tlmin=%4d, ot=%5d, tchmaj=%4d, tchmin=%4d, m=%4x\n", - i, ibt, ntouch, h->q2, - f[i].origin, f[i].abs_x, f[i].abs_y, f[i].rel_x, f[i].rel_y, - f[i].tool_major, f[i].tool_minor, f[i].orientation, - f[i].touch_major, f[i].touch_minor, f[i].multi); - - sc->pos_x[i] = f[i].abs_x; - sc->pos_y[i] = -f[i].abs_y; - sc->index[i] = &f[i]; + DPRINTFN(WSP_LLEVEL_INFO, + "[%d]ibt=%d, taps=%d, o=%4d, ax=%5d, ay=%5d, " + "rx=%5d, ry=%5d, tlmaj=%4d, tlmin=%4d, ot=%4x, " + "tchmaj=%4d, tchmin=%4d, presure=%4d, m=%4x\n", + i, ibt, ntouch, f->origin, f->abs_x, f->abs_y, + f->rel_x, f->rel_y, f->tool_major, f->tool_minor, f->orientation, + f->touch_major, f->touch_minor, f->pressure, f->multi); + sc->pos_x[i] = f->abs_x; + sc->pos_y[i] = -f->abs_y; + sc->index[i] = f; } sc->sc_status.flags &= ~MOUSE_POSCHANGED; @@ -750,24 +925,24 @@ wsp_intr_callback(struct usb_xfer *xfer, sc->sc_status.button |= MOUSE_BUTTON1DOWN; sc->ibtn = 1; } - if (h->q2 == 4) - sc->intr_count++; + sc->intr_count++; if (sc->ntaps < ntouch) { switch (ntouch) { case 1: - if (f[0].touch_major > tun.pressure_tap_threshold) + if (sc->index[0]->touch_major > tun.pressure_tap_threshold && + sc->index[0]->tool_major <= 1200) sc->ntaps = 1; break; case 2: - if (f[0].touch_major > tun.pressure_tap_threshold && - f[1].touch_major > tun.pressure_tap_threshold) + if (sc->index[0]->touch_major > tun.pressure_tap_threshold-30 && + sc->index[1]->touch_major > tun.pressure_tap_threshold-30) sc->ntaps = 2; break; case 3: - if (f[0].touch_major > tun.pressure_tap_threshold && - f[1].touch_major > tun.pressure_tap_threshold && - f[2].touch_major > tun.pressure_tap_threshold) + if (sc->index[0]->touch_major > tun.pressure_tap_threshold-40 && + sc->index[1]->touch_major > tun.pressure_tap_threshold-40 && + sc->index[2]->touch_major > tun.pressure_tap_threshold-40) sc->ntaps = 3; break; default: @@ -779,7 +954,7 @@ wsp_intr_callback(struct usb_xfer *xfer, abs(sc->pos_x[0] - sc->pos_x[1]), abs(sc->pos_y[0] - sc->pos_y[1]))); } - if (f[0].touch_major < tun.pressure_untouch_threshold && + if (sc->index[0]->touch_major < tun.pressure_untouch_threshold && sc->sc_status.button == 0) { sc->sc_touch = WSP_UNTOUCH; if (sc->intr_count < WSP_TAP_MAX_COUNT && @@ -840,10 +1015,10 @@ wsp_intr_callback(struct usb_xfer *xfer, sc->rdy = 0; sc->rdz = 0; sc->scr_mode = WSP_SCR_NONE; - } else if (f[0].touch_major >= tun.pressure_touch_threshold && + } else if (sc->index[0]->touch_major >= tun.pressure_touch_threshold && sc->sc_touch == WSP_UNTOUCH) { /* ignore first touch */ sc->sc_touch = WSP_FIRST_TOUCH; - } else if (f[0].touch_major >= tun.pressure_touch_threshold && + } else if (sc->index[0]->touch_major >= tun.pressure_touch_threshold && sc->sc_touch == WSP_FIRST_TOUCH) { /* ignore second touch */ sc->sc_touch = WSP_SECOND_TOUCH; DPRINTFN(WSP_LLEVEL_INFO, "Fist pre_x=%5d, pre_y=%5d\n", @@ -853,22 +1028,26 @@ wsp_intr_callback(struct usb_xfer *xfer, sc->sc_touch = WSP_TOUCHING; if (ntouch != 0 && - h->q2 == 4 && - f[0].touch_major >= tun.pressure_touch_threshold) { + sc->index[0]->touch_major >= tun.pressure_touch_threshold) { dx = sc->pos_x[0] - sc->pre_pos_x; dy = sc->pos_y[0] - sc->pre_pos_y; - /* Ignore movement from ibt=1 to ibt=0 */ - if (sc->sc_status.obutton != 0 && - sc->sc_status.button == 0) { - dx = 0; - dy = 0; - } + /* Ignore movement during button is releasing */ + if (sc->ibtn != 0 && sc->sc_status.button == 0) + dx = dy = 0; + /* Ignore movement if ntouch changed */ - if (sc->o_ntouch != ntouch) { - dx = 0; - dy = 0; - } + if (sc->o_ntouch != ntouch) + dx = dy = 0; + + /* Ignore unexpeted movment when typing */ + if (ntouch == 1 && sc->index[0]->tool_major > 1200) + dx = dy = 0; + + if (sc->ibtn != 0 && ntouch == 1 && + sc->intr_count < WSP_TAP_MAX_COUNT && + abs(sc->dx_sum) < 1 && abs(sc->dy_sum) < 1 ) + dx = dy = 0; if (ntouch == 2 && sc->sc_status.button != 0) { dx = sc->pos_x[sc->finger] - sc->pre_pos_x; @@ -878,26 +1057,23 @@ wsp_intr_callback(struct usb_xfer *xfer, * Ignore movement of switch finger or * movement from ibt=0 to ibt=1 */ - if (f[0].origin == 0 || f[1].origin == 0 || + if (sc->index[0]->origin == 0 || sc->index[1]->origin == 0 || sc->sc_status.obutton != sc->sc_status.button) { - dx = 0; - dy = 0; + dx = dy = 0; sc->finger = 0; } - if ((abs(f[0].rel_x) + abs(f[0].rel_y)) < - (abs(f[1].rel_x) + abs(f[1].rel_y)) && + if ((abs(sc->index[0]->rel_x) + abs(sc->index[0]->rel_y)) < + (abs(sc->index[1]->rel_x) + abs(sc->index[1]->rel_y)) && sc->finger == 0) { sc->sc_touch = WSP_SECOND_TOUCH; - dx = 0; - dy = 0; + dx = dy = 0; sc->finger = 1; } - if ((abs(f[0].rel_x) + abs(f[0].rel_y)) >= - (abs(f[1].rel_x) + abs(f[1].rel_y)) && + if ((abs(sc->index[0]->rel_x) + abs(sc->index[0]->rel_y)) >= + (abs(sc->index[1]->rel_x) + abs(sc->index[1]->rel_y)) && sc->finger == 1) { sc->sc_touch = WSP_SECOND_TOUCH; - dx = 0; - dy = 0; + dx = dy = 0; sc->finger = 0; } DPRINTFN(WSP_LLEVEL_INFO, "dx=%5d, dy=%5d, mov=%5d\n", @@ -926,8 +1102,7 @@ wsp_intr_callback(struct usb_xfer *xfer, if (sc->scr_mode == WSP_SCR_NONE && abs(sc->dx_sum) + abs(sc->dy_sum) > tun.scr_hor_threshold) sc->scr_mode = abs(sc->dx_sum) > - abs(sc->dy_sum) * 3 ? WSP_SCR_HOR : - WSP_SCR_VER; + abs(sc->dy_sum) * 2 ? WSP_SCR_HOR : WSP_SCR_VER; DPRINTFN(WSP_LLEVEL_INFO, "scr_mode=%5d, count=%d, dx_sum=%d, dy_sum=%d\n", sc->scr_mode, sc->intr_count, sc->dx_sum, sc->dy_sum); if (sc->scr_mode == WSP_SCR_HOR) @@ -935,8 +1110,7 @@ wsp_intr_callback(struct usb_xfer *xfer, else sc->dt_sum = 0; - dx = 0; - dy = 0; + dx = dy = 0; if (sc->dz_count == 0) dz = sc->dz_sum / tun.z_factor; if (sc->scr_mode == WSP_SCR_HOR || @@ -944,15 +1118,12 @@ wsp_intr_callback(struct usb_xfer *xfer, abs(sc->pos_y[0] - sc->pos_y[1]) > MAX_DISTANCE) dz = 0; } - if (ntouch == 3) { - dx = 0; - dy = 0; - dz = 0; - } + if (ntouch == 3) + dx = dy = dz = 0; if (sc->intr_count < WSP_TAP_MAX_COUNT && - abs(dx) < 3 && abs(dy) < 3 && abs(dz) < 3) { + abs(dx) < 3 && abs(dy) < 3 && abs(dz) < 3) dx = dy = dz = 0; - } else + else sc->intr_count = WSP_TAP_MAX_COUNT; if (dx || dy || dz) sc->sc_status.flags |= MOUSE_POSCHANGED; Modified: head/sys/dev/usb/usbdevs ============================================================================== --- head/sys/dev/usb/usbdevs Tue Nov 10 08:39:07 2015 (r290638) +++ head/sys/dev/usb/usbdevs Tue Nov 10 09:27:52 2015 (r290639) @@ -1131,6 +1131,10 @@ product APPLE WELLSPRING7A_JIS 0x025b Ap product APPLE WELLSPRING8_ANSI 0x0290 Apple Internal Keyboard/Trackpad product APPLE WELLSPRING8_ISO 0x0291 Apple Internal Keyboard/Trackpad product APPLE WELLSPRING8_JIS 0x0292 Apple Internal Keyboard/Trackpad +/* MacbookPro12,1 */ +product APPLE WELLSPRING9_ANSI 0x0272 Apple Internal Keyboard/Trackpad +product APPLE WELLSPRING9_ISO 0x0273 Apple Internal Keyboard/Trackpad +product APPLE WELLSPRING9_JIS 0x0274 Apple Internal Keyboard/Trackpad product APPLE MOUSE 0x0301 Mouse M4848 product APPLE OPTMOUSE 0x0302 Optical mouse product APPLE MIGHTYMOUSE 0x0304 Mighty Mouse