diff --git a/sys/dev/usb/input/uhid.c b/sys/dev/usb/input/uhid.c index f0a9bd4b8f6b..1a7f44ef30dc 100644 --- a/sys/dev/usb/input/uhid.c +++ b/sys/dev/usb/input/uhid.c @@ -124,6 +124,7 @@ struct uhid_softc { static const uint8_t uhid_xb360gp_report_descr[] = {UHID_XB360GP_REPORT_DESCR()}; static const uint8_t uhid_graphire_report_descr[] = {UHID_GRAPHIRE_REPORT_DESCR()}; static const uint8_t uhid_graphire3_4x5_report_descr[] = {UHID_GRAPHIRE3_4X5_REPORT_DESCR()}; +static const uint8_t uhid_touchdigi_v04_report_descr[] = {UHID_TOUCHDIGI_V04_REPORT_DESCR()}; /* prototypes */ @@ -802,6 +803,11 @@ uhid_attach(device_t dev) sc->sc_repdesc_size = sizeof(uhid_xb360gp_report_descr); sc->sc_repdesc_ptr = __DECONST(void *, &uhid_xb360gp_report_descr); sc->sc_flags |= UHID_FLAG_STATIC_DESC; + } else if (uaa->info.idVendor == USB_VENDOR_SYNAPTICS && + uaa->info.idProduct == USB_PRODUCT_SYNAPTICS_TOUCHDIGI_V04) { + sc->sc_repdesc_size = sizeof(uhid_touchdigi_v04_report_descr); + sc->sc_repdesc_ptr = __DECONST(void *, &uhid_touchdigi_v04_report_descr); + sc->sc_flags |= UHID_FLAG_STATIC_DESC; } if (sc->sc_repdesc_ptr == NULL) { diff --git a/sys/dev/usb/input/usb_rdesc.h b/sys/dev/usb/input/usb_rdesc.h index 889381e82c15..982eef4f0009 100644 --- a/sys/dev/usb/input/usb_rdesc.h +++ b/sys/dev/usb/input/usb_rdesc.h @@ -304,3 +304,283 @@ 0x81, 0x01, /* Input (Constant), */\ 0xC0, /* End Collection, */\ 0xC0 /* End Collection */ + +/* Fixed report descriptor for Synaptics Touch Digitizer V04 */ +#define UHID_TOUCHDIGI_V04_REPORT_DESCR(...) \ + 0x05, 0x01, /* Usage Page (Generic Desktop Ctrls) */\ + 0x09, 0x02, /* Usage (Mouse) */\ + 0xA1, 0x01, /* Collection (Application) */\ + 0x85, 0x02, /* Report ID (2) */\ + 0x09, 0x01, /* Usage (Pointer) */\ + 0xA1, 0x00, /* Collection (Physical) */\ + 0x05, 0x09, /* Usage Page (Button) */\ + 0x19, 0x01, /* Usage Minimum (0x01) */\ + 0x29, 0x02, /* Usage Maximum (0x02) */\ + 0x15, 0x00, /* Logical Minimum (0) */\ + 0x25, 0x01, /* Logical Maximum (1) */\ + 0x75, 0x01, /* Report Size (1) */\ + 0x95, 0x02, /* Report Count (2) */\ + 0x81, 0x02, /* Input (Data,Var,Abs) */\ + 0x95, 0x06, /* Report Count (6) */\ + 0x81, 0x03, /* Input (Const,Var,Abs) */\ + 0x05, 0x01, /* Usage Page (Generic Desktop Ctrls) */\ + 0x09, 0x30, /* Usage (X) */\ + 0x09, 0x31, /* Usage (Y) */\ + 0x15, 0x81, /* Logical Minimum (-127) */\ + 0x25, 0x7F, /* Logical Maximum (127) */\ + 0x75, 0x08, /* Report Size (8) */\ + 0x95, 0x02, /* Report Count (2) */\ + 0x81, 0x06, /* Input (Data,Var,Rel) */\ + 0xC0, /* End Collection */\ + 0xC0, /* End Collection */\ + 0x05, 0x0D, /* Usage Page (Digitizer) */\ + 0x09, 0x04, /* Usage (Touch Screen) */\ + 0xA1, 0x01, /* Collection (Application) */\ + 0x85, 0x01, /* Report ID (1) */\ + 0x09, 0x22, /* Usage (Finger) */\ + 0xA1, 0x02, /* Collection (Logical) */\ + 0x09, 0x42, /* Usage (Tip Switch) */\ + 0x15, 0x00, /* Logical Minimum (0) */\ + 0x25, 0x01, /* Logical Maximum (1) */\ + 0x75, 0x01, /* Report Size (1) */\ + 0x95, 0x01, /* Report Count (1) */\ + 0x81, 0x02, /* Input (Data,Var,Abs) */\ + 0x95, 0x07, /* Report Count (7) */\ + 0x81, 0x03, /* Input (Const,Var,Abs) */\ + 0x75, 0x08, /* Report Size (8) */\ + 0x09, 0x51, /* Usage (0x51) */\ + 0x15, 0x01, /* Logical Minimum (1) */\ + 0x26, 0xFF, 0x00, /* Logical Maximum (255) */\ + 0x95, 0x01, /* Report Count (1) */\ + 0x81, 0x42, /* Input (Data,Var,Abs) */\ + 0x05, 0x01, /* Usage Page (Generic Desktop Ctrls) */\ + 0x15, 0x00, /* Logical Minimum (0) */\ + 0x26, 0xE2, 0x0A, /* Logical Maximum (2786) */\ + 0x75, 0x10, /* Report Size (16) */\ + 0x55, 0x0E, /* Unit Exponent (-2) */\ + 0x65, 0x11, /* Unit (System: SI Linear, Length: Centimeter) */\ + 0x09, 0x30, /* Usage (X) */\ + 0x35, 0x0F, /* Physical Minimum (15) */\ + 0x46, 0xD3, 0x0A, /* Physical Maximum (2771) */\ + 0x81, 0x02, /* Input (Data,Var,Abs) */\ + 0x09, 0x31, /* Usage (Y) */\ + 0x15, 0x00, /* Logical Minimum (0) */\ + 0x26, 0x2B, 0x06, /* Logical Maximum (1579) */\ + 0x35, 0x0F, /* Physical Minimum (15) */\ + 0x46, 0x1C, 0x06, /* Physical Maximum (1564) */\ + 0x81, 0x02, /* Input (Data,Var,Abs) */\ + 0xC0, /* End Collection */\ + 0x05, 0x0D, /* Usage Page (Digitizer) */\ + 0x09, 0x22, /* Usage (Finger) */\ + 0xA1, 0x02, /* Collection (Logical) */\ + 0x09, 0x42, /* Usage (Tip Switch) */\ + 0x15, 0x00, /* Logical Minimum (0) */\ + 0x25, 0x01, /* Logical Maximum (1) */\ + 0x75, 0x01, /* Report Size (1) */\ + 0x95, 0x01, /* Report Count (1) */\ + 0x81, 0x02, /* Input (Data,Var,Abs) */\ + 0x95, 0x07, /* Report Count (7) */\ + 0x81, 0x03, /* Input (Const,Var,Abs) */\ + 0x75, 0x08, /* Report Size (8) */\ + 0x09, 0x51, /* Usage (0x51) */\ + 0x15, 0x01, /* Logical Minimum (1) */\ + 0x26, 0xFF, 0x00, /* Logical Maximum (255) */\ + 0x95, 0x01, /* Report Count (1) */\ + 0x81, 0x42, /* Input (Data,Var,Abs) */\ + 0x05, 0x01, /* Usage Page (Generic Desktop Ctrls) */\ + 0x15, 0x00, /* Logical Minimum (0) */\ + 0x26, 0xE2, 0x0A, /* Logical Maximum (2786) */\ + 0x75, 0x10, /* Report Size (16) */\ + 0x55, 0x0E, /* Unit Exponent (-2) */\ + 0x65, 0x11, /* Unit (System: SI Linear, Length: Centimeter) */\ + 0x09, 0x30, /* Usage (X) */\ + 0x35, 0x0F, /* Physical Minimum (15) */\ + 0x46, 0xD3, 0x0A, /* Physical Maximum (2771) */\ + 0x81, 0x02, /* Input (Data,Var,Abs) */\ + 0x09, 0x31, /* Usage (Y) */\ + 0x15, 0x00, /* Logical Minimum (0) */\ + 0x26, 0x2B, 0x06, /* Logical Maximum (1579) */\ + 0x35, 0x0F, /* Physical Minimum (15) */\ + 0x46, 0x1C, 0x06, /* Physical Maximum (1564) */\ + 0x81, 0x02, /* Input (Data,Var,Abs) */\ + 0xC0, /* End Collection */\ + 0x05, 0x0D, /* Usage Page (Digitizer) */\ + 0x09, 0x22, /* Usage (Finger) */\ + 0xA1, 0x02, /* Collection (Logical) */\ + 0x09, 0x42, /* Usage (Tip Switch) */\ + 0x15, 0x00, /* Logical Minimum (0) */\ + 0x25, 0x01, /* Logical Maximum (1) */\ + 0x75, 0x01, /* Report Size (1) */\ + 0x95, 0x01, /* Report Count (1) */\ + 0x81, 0x02, /* Input (Data,Var,Abs) */\ + 0x95, 0x07, /* Report Count (7) */\ + 0x81, 0x03, /* Input (Const,Var,Abs) */\ + 0x75, 0x08, /* Report Size (8) */\ + 0x09, 0x51, /* Usage (0x51) */\ + 0x15, 0x01, /* Logical Minimum (1) */\ + 0x26, 0xFF, 0x00, /* Logical Maximum (255) */\ + 0x95, 0x01, /* Report Count (1) */\ + 0x81, 0x42, /* Input (Data,Var,Abs) */\ + 0x05, 0x01, /* Usage Page (Generic Desktop Ctrls) */\ + 0x15, 0x00, /* Logical Minimum (0) */\ + 0x26, 0xE2, 0x0A, /* Logical Maximum (2786) */\ + 0x75, 0x10, /* Report Size (16) */\ + 0x55, 0x0E, /* Unit Exponent (-2) */\ + 0x65, 0x11, /* Unit (System: SI Linear, Length: Centimeter) */\ + 0x09, 0x30, /* Usage (X) */\ + 0x35, 0x0F, /* Physical Minimum (15) */\ + 0x46, 0xD3, 0x0A, /* Physical Maximum (2771) */\ + 0x81, 0x02, /* Input (Data,Var,Abs) */\ + 0x09, 0x31, /* Usage (Y) */\ + 0x15, 0x00, /* Logical Minimum (0) */\ + 0x26, 0x2B, 0x06, /* Logical Maximum (1579) */\ + 0x35, 0x0F, /* Physical Minimum (15) */\ + 0x46, 0x1C, 0x06, /* Physical Maximum (1564) */\ + 0x81, 0x02, /* Input (Data,Var,Abs) */\ + 0xC0, /* End Collection */\ + 0x05, 0x0D, /* Usage Page (Digitizer) */\ + 0x09, 0x22, /* Usage (Finger) */\ + 0xA1, 0x02, /* Collection (Logical) */\ + 0x09, 0x42, /* Usage (Tip Switch) */\ + 0x15, 0x00, /* Logical Minimum (0) */\ + 0x25, 0x01, /* Logical Maximum (1) */\ + 0x75, 0x01, /* Report Size (1) */\ + 0x95, 0x01, /* Report Count (1) */\ + 0x81, 0x02, /* Input (Data,Var,Abs) */\ + 0x95, 0x07, /* Report Count (7) */\ + 0x81, 0x03, /* Input (Const,Var,Abs) */\ + 0x75, 0x08, /* Report Size (8) */\ + 0x09, 0x51, /* Usage (0x51) */\ + 0x15, 0x01, /* Logical Minimum (1) */\ + 0x26, 0xFF, 0x00, /* Logical Maximum (255) */\ + 0x95, 0x01, /* Report Count (1) */\ + 0x81, 0x42, /* Input (Data,Var,Abs) */\ + 0x05, 0x01, /* Usage Page (Generic Desktop Ctrls) */\ + 0x15, 0x00, /* Logical Minimum (0) */\ + 0x26, 0xE2, 0x0A, /* Logical Maximum (2786) */\ + 0x75, 0x10, /* Report Size (16) */\ + 0x55, 0x0E, /* Unit Exponent (-2) */\ + 0x65, 0x11, /* Unit (System: SI Linear, Length: Centimeter) */\ + 0x09, 0x30, /* Usage (X) */\ + 0x35, 0x0F, /* Physical Minimum (15) */\ + 0x46, 0xD3, 0x0A, /* Physical Maximum (2771) */\ + 0x81, 0x02, /* Input (Data,Var,Abs) */\ + 0x09, 0x31, /* Usage (Y) */\ + 0x15, 0x00, /* Logical Minimum (0) */\ + 0x26, 0x2B, 0x06, /* Logical Maximum (1579) */\ + 0x35, 0x0F, /* Physical Minimum (15) */\ + 0x46, 0x1C, 0x06, /* Physical Maximum (1564) */\ + 0x81, 0x02, /* Input (Data,Var,Abs) */\ + 0xC0, /* End Collection */\ + 0x05, 0x0D, /* Usage Page (Digitizer) */\ + 0x09, 0x22, /* Usage (Finger) */\ + 0xA1, 0x02, /* Collection (Logical) */\ + 0x09, 0x42, /* Usage (Tip Switch) */\ + 0x15, 0x00, /* Logical Minimum (0) */\ + 0x25, 0x01, /* Logical Maximum (1) */\ + 0x75, 0x01, /* Report Size (1) */\ + 0x95, 0x01, /* Report Count (1) */\ + 0x81, 0x02, /* Input (Data,Var,Abs) */\ + 0x95, 0x07, /* Report Count (7) */\ + 0x81, 0x03, /* Input (Const,Var,Abs) */\ + 0x75, 0x08, /* Report Size (8) */\ + 0x09, 0x51, /* Usage (0x51) */\ + 0x15, 0x01, /* Logical Minimum (1) */\ + 0x26, 0xFF, 0x00, /* Logical Maximum (255) */\ + 0x95, 0x01, /* Report Count (1) */\ + 0x81, 0x42, /* Input (Data,Var,Abs) */\ + 0x05, 0x01, /* Usage Page (Generic Desktop Ctrls) */\ + 0x15, 0x00, /* Logical Minimum (0) */\ + 0x26, 0xE2, 0x0A, /* Logical Maximum (2786) */\ + 0x75, 0x10, /* Report Size (16) */\ + 0x55, 0x0E, /* Unit Exponent (-2) */\ + 0x65, 0x11, /* Unit (System: SI Linear, Length: Centimeter) */\ + 0x09, 0x30, /* Usage (X) */\ + 0x35, 0x0F, /* Physical Minimum (15) */\ + 0x46, 0xD3, 0x0A, /* Physical Maximum (2771) */\ + 0x81, 0x02, /* Input (Data,Var,Abs) */\ + 0x09, 0x31, /* Usage (Y) */\ + 0x15, 0x00, /* Logical Minimum (0) */\ + 0x26, 0x2B, 0x06, /* Logical Maximum (1579) */\ + 0x35, 0x0F, /* Physical Minimum (15) */\ + 0x46, 0x1C, 0x06, /* Physical Maximum (1564) */\ + 0x81, 0x02, /* Input (Data,Var,Abs) */\ + 0xC0, /* End Collection */\ + 0x05, 0x0D, /* Usage Page (Digitizer) */\ + 0x05, 0x0D, /* Usage Page (Digitizer) */\ + 0x55, 0x0C, /* Unit Exponent (-4) */\ + 0x66, 0x01, 0x10, /* Unit (System: SI Linear, Time: Seconds) */\ + 0x47, 0xFF, 0xFF, 0x00, 0x00, /* Physical Maximum (65534) */\ + 0x27, 0xFF, 0xFF, 0x00, 0x00, /* Logical Maximum (65534) */\ + 0x75, 0x10, /* Report Size (16) */\ + 0x95, 0x01, /* Report Count (1) */\ + 0x09, 0x56, /* Usage (0x56) */\ + 0x81, 0x02, /* Input (Data,Var,Abs) */\ + 0x09, 0x54, /* Usage (0x54) */\ + 0x95, 0x01, /* Report Count (1) */\ + 0x75, 0x08, /* Report Size (8) */\ + 0x15, 0x00, /* Logical Minimum (0) */\ + 0x25, 0x0F, /* Logical Maximum (15) */\ + 0x81, 0x02, /* Input (Data,Var,Abs) */\ + 0x85, 0x08, /* Report ID (8) */\ + 0x09, 0x55, /* Usage (0x55) */\ + 0xB1, 0x02, /* Feature (Data,Var,Abs) */\ + 0x85, 0x07, /* Report ID (7) */\ + 0x06, 0x00, 0xFF, /* Usage Page (Vendor Defined 0xFF00) */\ + 0x09, 0xC5, /* Usage (0xC5) */\ + 0x15, 0x00, /* Logical Minimum (0) */\ + 0x26, 0xFF, 0x00, /* Logical Maximum (255) */\ + 0x26, 0xFF, 0x00, /* Logical Maximum (255) */\ + 0x75, 0x08, /* Report Size (8) */\ + 0x96, 0x00, 0x01, /* Report Count (256) */\ + 0xB1, 0x02, /* Feature (Data,Var,Abs) */\ + 0xC0, /* End Collection */\ + 0x06, 0x00, 0xFF, /* Usage Page (Vendor Defined 0xFF00) */\ + 0x09, 0x01, /* Usage (0x01) */\ + 0xA1, 0x01, /* Collection (Application) */\ + 0x85, 0x09, /* Report ID (9) */\ + 0x09, 0x02, /* Usage (0x02) */\ + 0x15, 0x00, /* Logical Minimum (0) */\ + 0x26, 0xFF, 0x00, /* Logical Maximum (255) */\ + 0x26, 0xFF, 0x00, /* Logical Maximum (255) */\ + 0x75, 0x08, /* Report Size (8) */\ + 0x95, 0x3F, /* Report Count (63) */\ + 0x91, 0x02, /* Output (Data,Var,Abs) */\ + 0x85, 0x0A, /* Report ID (10) */\ + 0x09, 0x03, /* Usage (0x03) */\ + 0x15, 0x00, /* Logical Minimum (0) */\ + 0x26, 0xFF, 0x00, /* Logical Maximum (255) */\ + 0x75, 0x08, /* Report Size (8) */\ + 0x95, 0x05, /* Report Count (5) */\ + 0x91, 0x02, /* Output (Data,Var,Abs) */\ + 0x85, 0x0B, /* Report ID (11) */\ + 0x09, 0x04, /* Usage (0x04) */\ + 0x15, 0x00, /* Logical Minimum (0) */\ + 0x26, 0xFF, 0x00, /* Logical Maximum (255) */\ + 0x75, 0x08, /* Report Size (8) */\ + 0x95, 0x3D, /* Report Count (61) */\ + 0x81, 0x02, /* Input (Data,Var,Abs) */\ + 0x85, 0x0C, /* Report ID (12) */\ + 0x09, 0x05, /* Usage (0x05) */\ + 0x15, 0x00, /* Logical Minimum (0) */\ + 0x26, 0xFF, 0x00, /* Logical Maximum (255) */\ + 0x75, 0x08, /* Report Size (8) */\ + 0x95, 0x01, /* Report Count (1) */\ + 0x81, 0x02, /* Input (Data,Var,Abs) */\ + 0x85, 0xDB, /* Report ID (-37) */\ + 0x09, 0x06, /* Usage (0x06) */\ + 0x15, 0x00, /* Logical Minimum (0) */\ + 0x26, 0xFF, 0x00, /* Logical Maximum (255) */\ + 0x35, 0x00, /* Physical Minimum (0) */\ + 0x46, 0xFF, 0x00, /* Physical Maximum (255) */\ + 0x75, 0x08, /* Report Size (8) */\ + 0x95, 0x3D, /* Report Count (61) */\ + 0x81, 0x02, /* Input (Data,Var,Abs) */\ + 0x85, 0x0F, /* Report ID (15) */\ + 0x09, 0x06, /* Usage (0x06) */\ + 0x15, 0x00, /* Logical Minimum (0) */\ + 0x26, 0xFF, 0x00, /* Logical Maximum (255) */\ + 0x75, 0x08, /* Report Size (8) */\ + 0x95, 0x03, /* Report Count (3) */\ + 0xB1, 0x02, /* Feature (Data,Var,Abs) */\ + 0xC0 /* End Collection */ diff --git a/sys/dev/usb/input/wmt.c b/sys/dev/usb/input/wmt.c index d9816bcf965b..74158cb423ae 100644 --- a/sys/dev/usb/input/wmt.c +++ b/sys/dev/usb/input/wmt.c @@ -51,6 +51,7 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include #include @@ -217,6 +218,9 @@ struct wmt_softc for ((usage) = 0; (usage) < WMT_N_USAGES; ++(usage)) \ if (USAGE_SUPPORTED((caps), (usage))) +static const uint8_t uhid_touchdigi_v04_report_descr[] = + { UHID_TOUCHDIGI_V04_REPORT_DESCR() }; + static bool wmt_hid_parse(struct wmt_softc *, const void *, uint16_t); static void wmt_cont_max_parse(struct wmt_softc *, const void *, uint16_t); @@ -262,6 +266,7 @@ wmt_probe(device_t dev) struct usb_attach_arg *uaa = device_get_ivars(dev); void *d_ptr; uint16_t d_len; + bool d_static = false; int err; if (uaa->usb_mode != USB_MODE_HOST) @@ -273,17 +278,26 @@ wmt_probe(device_t dev) if (usb_test_quirk(uaa, UQ_WMT_IGNORE)) return (ENXIO); - err = usbd_req_get_hid_desc(uaa->device, NULL, - &d_ptr, &d_len, M_TEMP, uaa->info.bIfaceIndex); - if (err) - return (ENXIO); + if (uaa->info.idVendor == USB_VENDOR_SYNAPTICS && + uaa->info.idProduct == USB_PRODUCT_SYNAPTICS_TOUCHDIGI_V04) { + d_len = sizeof(uhid_touchdigi_v04_report_descr); + d_ptr = __DECONST(void *, &uhid_touchdigi_v04_report_descr); + d_static = true; + } else { + err = usbd_req_get_hid_desc(uaa->device, NULL, + &d_ptr, &d_len, M_TEMP, uaa->info.bIfaceIndex); + if (err) + return (ENXIO); + } if (wmt_hid_parse(NULL, d_ptr, d_len)) err = BUS_PROBE_DEFAULT; else err = ENXIO; - free(d_ptr, M_TEMP); + if (!d_static) + free(d_ptr, M_TEMP); + return (err); } @@ -296,21 +310,30 @@ wmt_attach(device_t dev) uint16_t d_len; size_t i; int err; - bool hid_ok; + bool hid_ok, d_static = false; device_set_usb_desc(dev); sc->dev = dev; /* Get HID descriptor */ - err = usbd_req_get_hid_desc(uaa->device, NULL, - &d_ptr, &d_len, M_TEMP, uaa->info.bIfaceIndex); - if (err) { - DPRINTF("usbd_req_get_hid_desc error=%s\n", usbd_errstr(err)); - return (ENXIO); + if (uaa->info.idVendor == USB_VENDOR_SYNAPTICS && + uaa->info.idProduct == USB_PRODUCT_SYNAPTICS_TOUCHDIGI_V04) { + d_len = sizeof(uhid_touchdigi_v04_report_descr); + d_ptr = __DECONST(void *, &uhid_touchdigi_v04_report_descr); + d_static = true; + } else { + err = usbd_req_get_hid_desc(uaa->device, NULL, + &d_ptr, &d_len, M_TEMP, uaa->info.bIfaceIndex); + if (err) { + DPRINTF("usbd_req_get_hid_desc error=%s\n", + usbd_errstr(err)); + return (ENXIO); + } } hid_ok = wmt_hid_parse(sc, d_ptr, d_len); - free(d_ptr, M_TEMP); + if (!d_static) + free(d_ptr, M_TEMP); if (!hid_ok) { DPRINTF("multi-touch HID descriptor not found\n"); return (ENXIO); diff --git a/sys/dev/usb/usbdevs b/sys/dev/usb/usbdevs index 2edc49e4c7cf..75ae80371167 100644 --- a/sys/dev/usb/usbdevs +++ b/sys/dev/usb/usbdevs @@ -4549,6 +4549,9 @@ product SUPERTOP FLASHDRIVE 0x121c extrememory Snippy product SYNTECH CPT8001C 0x0001 CPT-8001C Barcode scanner product SYNTECH CYPHERLAB100 0x1000 CipherLab USB Barcode Scanner +/* Synaptics products */ +product SYNAPTICS TOUCHDIGI_V04 0x7244 Touch Digitizer V04 + /* Teclast products */ product TECLAST TLC300 0x3203 USB Media Player