svn commit: r261262 - head/sys/dev/usb/input
Hans Petter Selasky
hselasky at FreeBSD.org
Wed Jan 29 12:34:06 UTC 2014
Author: hselasky
Date: Wed Jan 29 12:34:05 2014
New Revision: 261262
URL: http://svnweb.freebsd.org/changeset/base/261262
Log:
- Remove some dead code.
- Use system provided functions for HID report requests.
- Nice the mode setting, because the USB hardware does appear to
handle the commands right away.
MFC after: 1 week
Modified:
head/sys/dev/usb/input/wsp.c
Modified: head/sys/dev/usb/input/wsp.c
==============================================================================
--- head/sys/dev/usb/input/wsp.c Wed Jan 29 11:39:58 2014 (r261261)
+++ head/sys/dev/usb/input/wsp.c Wed Jan 29 12:34:05 2014 (r261262)
@@ -569,15 +569,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;
@@ -648,8 +644,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 +656,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 +669,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)
+static usb_error_t
+wsp_set_device_mode(struct wsp_softc *sc, interface_mode mode)
{
- 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)
-{
- 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);
-
- sc = device_get_softc(dev);
+ err = usbd_req_get_report(sc->sc_usb_device, NULL,
+ mode_bytes, sizeof(mode_bytes), 0,
+ 0x03, 0x00);
- 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 +762,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 +841,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)
More information about the svn-src-all
mailing list