svn commit: r261510 - in stable/9: etc sys/conf sys/dev/usb sys/dev/usb/input sys/modules/usb sys/modules/usb/wsp
Hans Petter Selasky
hselasky at FreeBSD.org
Wed Feb 5 08:43:00 UTC 2014
Author: hselasky
Date: Wed Feb 5 08:42:59 2014
New Revision: 261510
URL: http://svnweb.freebsd.org/changeset/base/261510
Log:
MFC r261260, r261262, r261315 and r261343:
Add support for trackpads found in Apple MacBook products. While at it
add some missing devd entries.
Added:
stable/9/sys/dev/usb/input/wsp.c
- copied, changed from r261260, head/sys/dev/usb/input/wsp.c
stable/9/sys/modules/usb/wsp/
- copied from r261260, head/sys/modules/usb/wsp/
Modified:
stable/9/etc/devd.conf
stable/9/sys/conf/NOTES
stable/9/sys/conf/files
stable/9/sys/dev/usb/usbdevs
stable/9/sys/modules/usb/Makefile
Directory Properties:
stable/9/etc/ (props changed)
stable/9/sys/ (props changed)
stable/9/sys/conf/ (props changed)
stable/9/sys/dev/ (props changed)
stable/9/sys/modules/ (props changed)
Modified: stable/9/etc/devd.conf
==============================================================================
--- stable/9/etc/devd.conf Wed Feb 5 08:40:02 2014 (r261509)
+++ stable/9/etc/devd.conf Wed Feb 5 08:42:59 2014 (r261510)
@@ -119,6 +119,15 @@ notify 100 {
match "system" "DEVFS";
match "subsystem" "CDEV";
match "type" "CREATE";
+ match "cdev" "atp[0-9]+";
+
+ action "/etc/rc.d/moused quietstart $cdev";
+};
+
+notify 100 {
+ match "system" "DEVFS";
+ match "subsystem" "CDEV";
+ match "type" "CREATE";
match "cdev" "ums[0-9]+";
action "/etc/rc.d/moused quietstart $cdev";
@@ -127,6 +136,15 @@ notify 100 {
notify 100 {
match "system" "DEVFS";
match "subsystem" "CDEV";
+ match "type" "CREATE";
+ match "cdev" "wsp[0-9]+";
+
+ action "/etc/rc.d/moused quietstart $cdev";
+};
+
+notify 100 {
+ match "system" "DEVFS";
+ match "subsystem" "CDEV";
match "type" "DESTROY";
match "cdev" "ums[0-9]+";
Modified: stable/9/sys/conf/NOTES
==============================================================================
--- stable/9/sys/conf/NOTES Wed Feb 5 08:40:02 2014 (r261509)
+++ stable/9/sys/conf/NOTES Wed Feb 5 08:42:59 2014 (r261510)
@@ -2667,6 +2667,9 @@ device umct
device umodem
# USB mouse
device ums
+# USB touchpad(s)
+device atp
+device wsp
# eGalax USB touch screen
device uep
# Diamond Rio 500 MP3 player
Modified: stable/9/sys/conf/files
==============================================================================
--- stable/9/sys/conf/files Wed Feb 5 08:40:02 2014 (r261509)
+++ stable/9/sys/conf/files Wed Feb 5 08:42:59 2014 (r261510)
@@ -2089,6 +2089,7 @@ dev/usb/input/uep.c optional uep
dev/usb/input/uhid.c optional uhid
dev/usb/input/ukbd.c optional ukbd
dev/usb/input/ums.c optional ums
+dev/usb/input/wsp.c optional wsp
#
# USB quirks
#
Copied and modified: stable/9/sys/dev/usb/input/wsp.c (from r261260, head/sys/dev/usb/input/wsp.c)
==============================================================================
--- head/sys/dev/usb/input/wsp.c Wed Jan 29 10:42:01 2014 (r261260, copy source)
+++ stable/9/sys/dev/usb/input/wsp.c Wed Feb 5 08:42:59 2014 (r261510)
@@ -123,6 +123,25 @@ SYSCTL_INT(_hw_usb_wsp, OID_AUTO, scr_ho
#define WSP_IFACE_INDEX 1
+/*
+ * Some tables, structures, definitions and initialisation values for
+ * the touchpad protocol has been copied from Linux's
+ * "drivers/input/mouse/bcm5974.c" which has the following copyright
+ * holders under GPLv2. All device specific code in this driver has
+ * been written from scratch. The decoding algorithm is based on
+ * output from usbdump.
+ *
+ * Copyright (C) 2008 Henrik Rydberg (rydberg at euromail.se)
+ * Copyright (C) 2008 Scott Shawcroft (scott.shawcroft at gmail.com)
+ * Copyright (C) 2001-2004 Greg Kroah-Hartman (greg at kroah.com)
+ * Copyright (C) 2005 Johannes Berg (johannes at sipsolutions.net)
+ * Copyright (C) 2005 Stelian Pop (stelian at popies.net)
+ * Copyright (C) 2005 Frank Arnold (frank at scirocco-5v-turbo.de)
+ * Copyright (C) 2005 Peter Osterlund (petero2 at telia.com)
+ * Copyright (C) 2005 Michael Hanselmann (linux-kernel at hansmi.ch)
+ * Copyright (C) 2006 Nicolas Boichat (nicolas at boichat.ch)
+ */
+
/* button data structure */
struct bt_data {
uint8_t unknown1; /* constant */
@@ -569,15 +588,11 @@ static const STRUCT_USB_HOST_ID wsp_devs
enum {
WSP_INTR_DT,
- WSP_RESET,
WSP_N_TRANSFER,
};
struct wsp_softc {
- device_t sc_dev;
struct usb_device *sc_usb_device;
-#define MODE_LENGTH 8
- uint8_t sc_mode_bytes[MODE_LENGTH]; /* device mode */
struct mtx sc_mutex; /* for synchronization */
struct usb_xfer *sc_xfer[WSP_N_TRANSFER];
struct usb_fifo_sc sc_fifo;
@@ -609,7 +624,8 @@ struct wsp_softc {
int dz_count;
#define WSP_DZ_MAX_COUNT 32
int dt_sum; /* T-axis cumulative movement */
-
+
+ uint8_t o_ntouch; /* old touch finger status */
uint8_t finger; /* 0 or 1 *, check which finger moving */
uint16_t intr_count;
#define WSP_TAP_THRESHOLD 3
@@ -648,8 +664,6 @@ static struct usb_fifo_methods wsp_fifo_
};
/* device initialization and shutdown */
-static usb_error_t wsp_req_get_report(struct usb_device *udev, void *data);
-static int wsp_set_device_mode(device_t dev, interface_mode mode);
static int wsp_enable(struct wsp_softc *sc);
static void wsp_disable(struct wsp_softc *sc);
@@ -662,7 +676,6 @@ static device_probe_t wsp_probe;
static device_attach_t wsp_attach;
static device_detach_t wsp_detach;
static usb_callback_t wsp_intr_callback;
-static usb_callback_t wsp_reset_callback;
static struct usb_config wsp_config[WSP_N_TRANSFER] = {
[WSP_INTR_DT] = {
@@ -676,87 +689,36 @@ static struct usb_config wsp_config[WSP_
.bufsize = 0, /* use wMaxPacketSize */
.callback = &wsp_intr_callback,
},
- [WSP_RESET] = {
- .type = UE_CONTROL,
- .endpoint = 0, /* Control pipe */
- .direction = UE_DIR_ANY,
- .bufsize = sizeof(struct usb_device_request) + MODE_LENGTH,
- .callback = &wsp_reset_callback,
- .interval = 0, /* no pre-delay */
- },
};
-usb_error_t
-wsp_req_get_report(struct usb_device *udev, void *data)
-{
- struct usb_device_request req;
-
- req.bmRequestType = UT_READ_CLASS_INTERFACE;
- req.bRequest = UR_GET_REPORT;
- USETW2(req.wValue, (uint8_t)0x03 /* type */ , (uint8_t)0x00 /* id */ );
- USETW(req.wIndex, 0);
- USETW(req.wLength, MODE_LENGTH);
-
- return (usbd_do_request(udev, NULL /* mutex */ , &req, data));
-}
-
-static int
-wsp_set_device_mode(device_t dev, interface_mode mode)
+static usb_error_t
+wsp_set_device_mode(struct wsp_softc *sc, interface_mode mode)
{
- struct wsp_softc *sc;
- usb_device_request_t req;
+ uint8_t mode_bytes[8];
usb_error_t err;
- if ((mode != RAW_SENSOR_MODE) && (mode != HID_MODE))
- return (ENXIO);
+ err = usbd_req_get_report(sc->sc_usb_device, NULL,
+ mode_bytes, sizeof(mode_bytes), 0,
+ 0x03, 0x00);
- sc = device_get_softc(dev);
-
- sc->sc_mode_bytes[0] = mode;
- req.bmRequestType = UT_WRITE_CLASS_INTERFACE;
- req.bRequest = UR_SET_REPORT;
- USETW2(req.wValue, (uint8_t)0x03 /* type */ , (uint8_t)0x00 /* id */ );
- USETW(req.wIndex, 0);
- USETW(req.wLength, MODE_LENGTH);
- err = usbd_do_request(sc->sc_usb_device, NULL, &req, sc->sc_mode_bytes);
- if (err != USB_ERR_NORMAL_COMPLETION)
- return (ENXIO);
-
- return (0);
-}
-
-static void
-wsp_reset_callback(struct usb_xfer *xfer, usb_error_t error)
-{
- usb_device_request_t req;
- struct usb_page_cache *pc;
- struct wsp_softc *sc = usbd_xfer_softc(xfer);
+ if (err != USB_ERR_NORMAL_COMPLETION) {
+ DPRINTF("Failed to read device mode (%d)\n", err);
+ return (err);
+ }
- switch (USB_GET_STATE(xfer)) {
- case USB_ST_SETUP:
- sc->sc_mode_bytes[0] = RAW_SENSOR_MODE;
- req.bmRequestType = UT_WRITE_CLASS_INTERFACE;
- req.bRequest = UR_SET_REPORT;
- USETW2(req.wValue,
- (uint8_t)0x03 /* type */ , (uint8_t)0x00 /* id */ );
- USETW(req.wIndex, 0);
- USETW(req.wLength, MODE_LENGTH);
+ /*
+ * XXX Need to wait at least 250ms for hardware to get
+ * ready. The device mode handling appears to be handled
+ * asynchronously and we should not issue these commands too
+ * quickly.
+ */
+ pause("WHW", hz / 4);
- pc = usbd_xfer_get_frame(xfer, 0);
- usbd_copy_in(pc, 0, &req, sizeof(req));
- pc = usbd_xfer_get_frame(xfer, 1);
- usbd_copy_in(pc, 0, sc->sc_mode_bytes, MODE_LENGTH);
-
- usbd_xfer_set_frame_len(xfer, 0, sizeof(req));
- usbd_xfer_set_frame_len(xfer, 1, MODE_LENGTH);
- usbd_xfer_set_frames(xfer, 2);
- usbd_transfer_submit(xfer);
- break;
+ mode_bytes[0] = mode;
- case USB_ST_TRANSFERRED:
- default:
- break;
- }
+ return (usbd_req_set_report(sc->sc_usb_device, NULL,
+ mode_bytes, sizeof(mode_bytes), 0,
+ 0x03, 0x00));
}
static int
@@ -820,27 +782,35 @@ wsp_attach(device_t dev)
DPRINTFN(WSP_LLEVEL_INFO, "sc=%p\n", sc);
- sc->sc_dev = dev;
sc->sc_usb_device = uaa->device;
/*
- * By default the touchpad behaves like an HID device, sending
+ * By default the touchpad behaves like a HID device, sending
* packets with reportID = 8. Such reports contain only
* limited information. They encode movement deltas and button
* events, but do not include data from the pressure
* sensors. The device input mode can be switched from HID
* reports to raw sensor data using vendor-specific USB
- * control commands; but first the mode must be read.
+ * control commands:
*/
- err = wsp_req_get_report(sc->sc_usb_device, sc->sc_mode_bytes);
+
+ /*
+ * During re-enumeration of the device we need to force the
+ * 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);
if (err != USB_ERR_NORMAL_COMPLETION) {
- DPRINTF("failed to read device mode (%d)\n", err);
+ DPRINTF("Failed to set mode to HID MODE (%d)\n", err);
return (ENXIO);
}
- if (wsp_set_device_mode(dev, RAW_SENSOR_MODE) != 0) {
- DPRINTF("failed to set mode to 'RAW_SENSOR' (%d)\n", err);
+
+ err = wsp_set_device_mode(sc, RAW_SENSOR_MODE);
+ if (err != USB_ERR_NORMAL_COMPLETION) {
+ DPRINTF("failed to set mode to RAW MODE (%d)\n", err);
return (ENXIO);
}
+
mtx_init(&sc->sc_mutex, "wspmtx", NULL, MTX_DEF | MTX_RECURSE);
/* get device specific configuration */
@@ -891,7 +861,7 @@ wsp_detach(device_t dev)
{
struct wsp_softc *sc = device_get_softc(dev);
- wsp_set_device_mode(dev, HID_MODE);
+ (void) wsp_set_device_mode(sc, HID_MODE);
mtx_lock(&sc->sc_mutex);
if (sc->sc_state & WSP_ENABLED)
@@ -921,7 +891,6 @@ wsp_intr_callback(struct usb_xfer *xfer,
int dx = 0;
int dy = 0;
int dz = 0;
- int n = 0;
int len;
int i;
@@ -986,13 +955,9 @@ wsp_intr_callback(struct usb_xfer *xfer,
f[i].tool_major, f[i].tool_minor, f[i].orientation,
f[i].touch_major, f[i].touch_minor, f[i].multi);
- if (f[i].touch_major < tun.pressure_untouch_threshold)
- continue;
-
- sc->pos_x[n] = f[i].abs_x;
- sc->pos_y[n] = params->y.min + params->y.max - f[i].abs_y;
- sc->index[n] = &f[i];
- n++;
+ sc->pos_x[i] = f[i].abs_x;
+ sc->pos_y[i] = params->y.min + params->y.max - f[i].abs_y;
+ sc->index[i] = &f[i];
}
sc->sc_status.flags &= ~MOUSE_POSCHANGED;
@@ -1007,8 +972,8 @@ wsp_intr_callback(struct usb_xfer *xfer,
if (h->q2 == 4)
sc->intr_count++;
- if (sc->ntaps < n) {
- switch (n) {
+ if (sc->ntaps < ntouch) {
+ switch (ntouch) {
case 1:
if (f[0].touch_major > tun.pressure_tap_threshold)
sc->ntaps = 1;
@@ -1028,7 +993,7 @@ wsp_intr_callback(struct usb_xfer *xfer,
break;
}
}
- if (n == 2) {
+ if (ntouch == 2) {
sc->distance = max(sc->distance, max(
abs(sc->pos_x[0] - sc->pos_x[1]),
abs(sc->pos_y[0] - sc->pos_y[1])));
@@ -1100,15 +1065,34 @@ wsp_intr_callback(struct usb_xfer *xfer,
if (sc->sc_touch == WSP_SECOND_TOUCH)
sc->sc_touch = WSP_TOUCHING;
- if (n != 0 &&
+ if (ntouch != 0 &&
h->q2 == 4 &&
f[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;
- if (n == 2 && sc->sc_status.button != 0) {
+
+ /* 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 if ntouch changed */
+ if (sc->o_ntouch != ntouch) {
+ dx = 0;
+ dy = 0;
+ }
+
+ if (ntouch == 2 && sc->sc_status.button != 0) {
dx = sc->pos_x[sc->finger] - sc->pre_pos_x;
dy = sc->pos_y[sc->finger] - sc->pre_pos_y;
- if (f[0].origin == 0 || f[1].origin == 0) {
+
+ /*
+ * Ignore movement of switch finger or
+ * movement from ibt=0 to ibt=1
+ */
+ if (f[0].origin == 0 || f[1].origin == 0 ||
+ sc->sc_status.obutton != sc->sc_status.button) {
dx = 0;
dy = 0;
sc->finger = 0;
@@ -1142,7 +1126,7 @@ wsp_intr_callback(struct usb_xfer *xfer,
sc->dx_sum += dx;
sc->dy_sum += dy;
- if (n == 2 && sc->sc_status.button == 0) {
+ if (ntouch == 2 && sc->sc_status.button == 0) {
if (sc->scr_mode == WSP_SCR_NONE &&
abs(sc->dx_sum) + abs(sc->dy_sum) > 50)
sc->scr_mode = abs(sc->dx_sum) >
@@ -1184,10 +1168,12 @@ wsp_intr_callback(struct usb_xfer *xfer,
sc->pre_pos_x = sc->pos_x[0];
sc->pre_pos_y = sc->pos_y[0];
- if (n == 2 && sc->sc_status.button != 0) {
+ if (ntouch == 2 && sc->sc_status.button != 0) {
sc->pre_pos_x = sc->pos_x[sc->finger];
sc->pre_pos_y = sc->pos_y[sc->finger];
}
+ sc->o_ntouch = ntouch;
+
case USB_ST_SETUP:
tr_setup:
/* check if we can put more data into the FIFO */
Modified: stable/9/sys/dev/usb/usbdevs
==============================================================================
--- stable/9/sys/dev/usb/usbdevs Wed Feb 5 08:40:02 2014 (r261509)
+++ stable/9/sys/dev/usb/usbdevs Wed Feb 5 08:42:59 2014 (r261510)
@@ -1077,12 +1077,54 @@ product APPLE DUMMY 0x0000 Dummy produc
product APPLE IMAC_KBD 0x0201 USB iMac Keyboard
product APPLE KBD 0x0202 USB Keyboard M2452
product APPLE EXT_KBD 0x020c Apple Extended USB Keyboard
-product APPLE KBD_TP_ANSI 0x0223 Apple Internal Keyboard/Trackpad (Wellspring/ANSI)
-product APPLE KBD_TP_ISO 0x0224 Apple Internal Keyboard/Trackpad (Wellspring/ISO)
-product APPLE KBD_TP_JIS 0x0225 Apple Internal Keyboard/Trackpad (Wellspring/JIS)
-product APPLE KBD_TP_ANSI2 0x0230 Apple Internal Keyboard/Trackpad (Wellspring2/ANSI)
-product APPLE KBD_TP_ISO2 0x0231 Apple Internal Keyboard/Trackpad (Wellspring2/ISO)
-product APPLE KBD_TP_JIS2 0x0232 Apple Internal Keyboard/Trackpad (Wellspring2/JIS)
+/* MacbookAir, aka wellspring */
+product APPLE WELLSPRING_ANSI 0x0223 Apple Internal Keyboard/Trackpad
+product APPLE WELLSPRING_ISO 0x0224 Apple Internal Keyboard/Trackpad
+product APPLE WELLSPRING_JIS 0x0225 Apple Internal Keyboard/Trackpad
+/* MacbookProPenryn, aka wellspring2 */
+product APPLE WELLSPRING2_ANSI 0x0230 Apple Internal Keyboard/Trackpad
+product APPLE WELLSPRING2_ISO 0x0231 Apple Internal Keyboard/Trackpad
+product APPLE WELLSPRING2_JIS 0x0232 Apple Internal Keyboard/Trackpad
+/* Macbook5,1 (unibody), aka wellspring3 */
+product APPLE WELLSPRING3_ANSI 0x0236 Apple Internal Keyboard/Trackpad
+product APPLE WELLSPRING3_ISO 0x0237 Apple Internal Keyboard/Trackpad
+product APPLE WELLSPRING3_JIS 0x0238 Apple Internal Keyboard/Trackpad
+/* MacbookAir3,2 (unibody), aka wellspring4 */
+product APPLE WELLSPRING4_ANSI 0x023f Apple Internal Keyboard/Trackpad
+product APPLE WELLSPRING4_ISO 0x0240 Apple Internal Keyboard/Trackpad
+product APPLE WELLSPRING4_JIS 0x0241 Apple Internal Keyboard/Trackpad
+/* MacbookAir3,1 (unibody), aka wellspring4 */
+product APPLE WELLSPRING4A_ANSI 0x0242 Apple Internal Keyboard/Trackpad
+product APPLE WELLSPRING4A_ISO 0x0243 Apple Internal Keyboard/Trackpad
+product APPLE WELLSPRING4A_JIS 0x0244 Apple Internal Keyboard/Trackpad
+/* Macbook8 (unibody, March 2011) */
+product APPLE WELLSPRING5_ANSI 0x0245 Apple Internal Keyboard/Trackpad
+product APPLE WELLSPRING5_ISO 0x0246 Apple Internal Keyboard/Trackpad
+product APPLE WELLSPRING5_JIS 0x0247 Apple Internal Keyboard/Trackpad
+/* MacbookAir4,1 (unibody, July 2011) */
+product APPLE WELLSPRING6A_ANSI 0x0249 Apple Internal Keyboard/Trackpad
+product APPLE WELLSPRING6A_ISO 0x024a Apple Internal Keyboard/Trackpad
+product APPLE WELLSPRING6A_JIS 0x024b Apple Internal Keyboard/Trackpad
+/* MacbookAir4,2 (unibody, July 2011) */
+product APPLE WELLSPRING6_ANSI 0x024c Apple Internal Keyboard/Trackpad
+product APPLE WELLSPRING6_ISO 0x024d Apple Internal Keyboard/Trackpad
+product APPLE WELLSPRING6_JIS 0x024e Apple Internal Keyboard/Trackpad
+/* Macbook8,2 (unibody) */
+product APPLE WELLSPRING5A_ANSI 0x0252 Apple Internal Keyboard/Trackpad
+product APPLE WELLSPRING5A_ISO 0x0253 Apple Internal Keyboard/Trackpad
+product APPLE WELLSPRING5A_JIS 0x0254 Apple Internal Keyboard/Trackpad
+/* MacbookPro10,1 (unibody, June 2012) */
+product APPLE WELLSPRING7_ANSI 0x0262 Apple Internal Keyboard/Trackpad
+product APPLE WELLSPRING7_ISO 0x0263 Apple Internal Keyboard/Trackpad
+product APPLE WELLSPRING7_JIS 0x0264 Apple Internal Keyboard/Trackpad
+/* MacbookPro10,2 (unibody, October 2012) */
+product APPLE WELLSPRING7A_ANSI 0x0259 Apple Internal Keyboard/Trackpad
+product APPLE WELLSPRING7A_ISO 0x025a Apple Internal Keyboard/Trackpad
+product APPLE WELLSPRING7A_JIS 0x025b Apple Internal Keyboard/Trackpad
+/* MacbookAir6,2 (unibody, June 2013) */
+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
product APPLE MOUSE 0x0301 Mouse M4848
product APPLE OPTMOUSE 0x0302 Optical mouse
product APPLE MIGHTYMOUSE 0x0304 Mighty Mouse
Modified: stable/9/sys/modules/usb/Makefile
==============================================================================
--- stable/9/sys/modules/usb/Makefile Wed Feb 5 08:40:02 2014 (r261509)
+++ stable/9/sys/modules/usb/Makefile Wed Feb 5 08:42:59 2014 (r261510)
@@ -33,7 +33,7 @@
SUBDIR = usb
SUBDIR += ehci musb ohci uhci xhci uss820dci ${_at91dci} ${_atmegadci} ${_avr32dci}
SUBDIR += ${_rum} run ${_uath} upgt usie ural ${_zyd} ${_urtw}
-SUBDIR += atp uhid ukbd ums udbp ufm uep
+SUBDIR += atp uhid ukbd ums udbp ufm uep wsp
SUBDIR += ucom u3g uark ubsa ubser uchcom ucycom ufoma uftdi ugensa uipaq ulpt \
umct umcs umodem umoscom uplcom uslcom uvisor uvscom
SUBDIR += uether aue axe cdce cue ${_kue} mos rue udav uhso ipheth
More information about the svn-src-stable-9
mailing list