summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorhselasky <hselasky@FreeBSD.org>2015-11-10 09:27:52 +0000
committerhselasky <hselasky@FreeBSD.org>2015-11-10 09:27:52 +0000
commit26984a406d8bdd5e3cd7f243124a59aa93b05c07 (patch)
tree281363c6223e07cb52bc32932843d3bbb9935fb8
parent883271972d24bf72cdbd2455dd1bb09349fe2b80 (diff)
downloadFreeBSD-src-26984a406d8bdd5e3cd7f243124a59aa93b05c07.zip
FreeBSD-src-26984a406d8bdd5e3cd7f243124a59aa93b05c07.tar.gz
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
-rw-r--r--sys/dev/usb/input/wsp.c383
-rw-r--r--sys/dev/usb/usbdevs4
2 files changed, 281 insertions, 106 deletions
diff --git a/sys/dev/usb/input/wsp.c b/sys/dev/usb/input/wsp.c
index 6d7255e..1858c12 100644
--- a/sys/dev/usb/input/wsp.c
+++ b/sys/dev/usb/input/wsp.c
@@ -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, pressure_tap_threshold, CTLFLAG_RWTUN,
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_config[WSP_N_TRANSFER] = {
};
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, interface_mode mode)
*/
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, usb_error_t error)
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, usb_error_t error)
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, usb_error_t error)
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, usb_error_t error)
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, usb_error_t error)
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, usb_error_t error)
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, usb_error_t error)
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, usb_error_t error)
* 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, usb_error_t error)
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, usb_error_t error)
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, usb_error_t error)
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;
diff --git a/sys/dev/usb/usbdevs b/sys/dev/usb/usbdevs
index 083aa00..83d41e6 100644
--- a/sys/dev/usb/usbdevs
+++ b/sys/dev/usb/usbdevs
@@ -1131,6 +1131,10 @@ product APPLE WELLSPRING7A_JIS 0x025b Apple Internal Keyboard/Trackpad
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
OpenPOWER on IntegriCloud