On Sat, Aug 25, 2018 at 01:41:40PM -0500, joshua stein wrote: > For USB-connected Windows Precision Touchpad devices, just like > imt(4) is for i2c. > > Also renames HIDMT_INPUT_MODE_MT to HIDMT_INPUT_MODE_MT_TOUCHPAD > since there is a different value for touchscreens (not yet used). >
ok for the man stuff, but please keep the description in the Nd line and the entry in usb(4) exactly the same. jmc > > Index: sys/arch/amd64/conf/GENERIC > =================================================================== > RCS file: /cvs/src/sys/arch/amd64/conf/GENERIC,v > retrieving revision 1.460 > diff -u -p -u -p -r1.460 GENERIC > --- sys/arch/amd64/conf/GENERIC 22 Aug 2018 15:38:46 -0000 1.460 > +++ sys/arch/amd64/conf/GENERIC 25 Aug 2018 18:39:09 -0000 > @@ -257,6 +257,8 @@ wsmouse* at ubcmtp? mux 0 > uhidev* at uhub? # Human Interface Devices > ums* at uhidev? # USB mouse > wsmouse* at ums? mux 0 > +umt* at uhidev? # Multitouch touchpad > +wsmouse* at umt? mux 0 > uts* at uhub? # USB touchscreen > wsmouse* at uts? mux 0 > uwacom* at uhidev? # USB Wacom tablet > Index: share/man/man4/Makefile > =================================================================== > RCS file: /cvs/src/share/man/man4/Makefile,v > retrieving revision 1.690 > diff -u -p -u -p -r1.690 Makefile > --- share/man/man4/Makefile 19 Aug 2018 11:42:33 -0000 1.690 > +++ share/man/man4/Makefile 25 Aug 2018 18:39:09 -0000 > @@ -75,8 +75,8 @@ MAN= aac.4 ac97.4 acphy.4 acrtc.4 \ > uftdi.4 ugen.4 ugl.4 ugold.4 uguru.4 uhci.4 uhid.4 uhidev.4 uipaq.4 \ > uk.4 ukbd.4 \ > ukphy.4 ulpt.4 umass.4 umb.4 umbg.4 umcs.4 umct.4 umidi.4 umodem.4 \ > - ums.4 umsm.4 unix.4 uonerng.4 uow.4 uoaklux.4 uoakrh.4 uoakv.4 upd.4 \ > - upgt.4 upl.4 uplcom.4 ural.4 ure.4 url.4 urlphy.4 \ > + ums.4 umsm.4 umt.4 unix.4 uonerng.4 uow.4 uoaklux.4 uoakrh.4 uoakv.4 \ > + upd.4 upgt.4 upl.4 uplcom.4 ural.4 ure.4 url.4 urlphy.4 \ > urndis.4 urng.4 urtw.4 urtwn.4 usb.4 uscom.4 uslcom.4 usps.4 \ > uthum.4 uticom.4 utpms.4 utwitch.4 utrh.4 uts.4 utvfu.4 uvideo.4 \ > uvisor.4 uvscom.4 uwacom.4 \ > Index: share/man/man4/uhidev.4 > =================================================================== > RCS file: /cvs/src/share/man/man4/uhidev.4,v > retrieving revision 1.9 > diff -u -p -u -p -r1.9 uhidev.4 > --- share/man/man4/uhidev.4 12 Sep 2016 08:12:06 -0000 1.9 > +++ share/man/man4/uhidev.4 25 Aug 2018 18:39:09 -0000 > @@ -42,6 +42,7 @@ > .Cd "uhid* at uhidev?" > .Cd "ukbd* at uhidev?" > .Cd "ums* at uhidev?" > +.Cd "umt* at uhidev?" > .Cd "uoaklux* at uhidev?" > .Cd "uoakrh* at uhidev?" > .Cd "uoakv* at uhidev?" > @@ -73,6 +74,7 @@ only dispatches data to them based on th > .Xr uhid 4 , > .Xr ukbd 4 , > .Xr ums 4 , > +.Xr umt 4 , > .Xr uoaklux 4 , > .Xr uoakrh 4 , > .Xr uoakv 4 , > Index: share/man/man4/umt.4 > =================================================================== > RCS file: share/man/man4/umt.4 > diff -N share/man/man4/umt.4 > --- /dev/null 1 Jan 1970 00:00:00 -0000 > +++ share/man/man4/umt.4 25 Aug 2018 18:39:10 -0000 > @@ -0,0 +1,47 @@ > +.\" $OpenBSD$ > +.\" > +.\" Copyright (c) 2016-2018 joshua stein <j...@openbsd.org> > +.\" > +.\" Permission to use, copy, modify, and distribute this software for any > +.\" purpose with or without fee is hereby granted, provided that the above > +.\" copyright notice and this permission notice appear in all copies. > +.\" > +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES > +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF > +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR > +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES > +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN > +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF > +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. > +.\" > +.Dd $Mdocdate$ > +.Dt UMT 4 > +.Os > +.Sh NAME > +.Nm umt > +.Nd USB HID multitouch touchpad support > +.Sh SYNOPSIS > +.Cd "umt* at uhidev?" > +.Cd "wsmouse* at umt? mux 0" > +.Sh DESCRIPTION > +The > +.Nm > +driver provides support for USB HID touchpads conforming to the > +Windows Precision Touchpad standard. > +Access to these devices is through the > +.Xr wscons 4 > +driver. > +.Sh SEE ALSO > +.Xr uhidev 4 , > +.Xr ums 4 , > +.Xr wsmouse 4 > +.Sh HISTORY > +The > +.Nm > +device driver first appeared in > +.Ox 6.4 . > +.Sh AUTHORS > +The > +.Nm > +driver was written by > +.An joshua stein Aq Mt j...@openbsd.org . > Index: share/man/man4/usb.4 > =================================================================== > RCS file: /cvs/src/share/man/man4/usb.4,v > retrieving revision 1.188 > diff -u -p -u -p -r1.188 usb.4 > --- share/man/man4/usb.4 3 Aug 2018 01:50:14 -0000 1.188 > +++ share/man/man4/usb.4 25 Aug 2018 18:39:10 -0000 > @@ -248,6 +248,8 @@ Base driver for all Human Interface Devi > USB keyboards that follow the boot protocol > .It Xr ums 4 > USB HID mouse, touchscreen and digitiser devices > +.It Xr umt 4 > +USB HID touchpad devices > .It Xr uoaklux 4 > Toradex OAK USB illuminance sensor > .It Xr uoakrh 4 > Index: sys/dev/hid/hidmt.c > =================================================================== > RCS file: /cvs/src/sys/dev/hid/hidmt.c,v > retrieving revision 1.8 > diff -u -p -u -p -r1.8 hidmt.c > --- sys/dev/hid/hidmt.c 25 Aug 2018 18:32:05 -0000 1.8 > +++ sys/dev/hid/hidmt.c 25 Aug 2018 18:39:10 -0000 > @@ -221,7 +221,7 @@ hidmt_setup(struct device *self, struct > return 1; > } > > - if (hidmt_set_input_mode(mt, HIDMT_INPUT_MODE_MT)) { > + if (hidmt_set_input_mode(mt, HIDMT_INPUT_MODE_MT_TOUCHPAD)) { > printf("\n%s: switch to multitouch mode failed\n", > self->dv_xname); > return 1; > Index: sys/dev/hid/hidmtvar.h > =================================================================== > RCS file: /cvs/src/sys/dev/hid/hidmtvar.h,v > retrieving revision 1.6 > diff -u -p -u -p -r1.6 hidmtvar.h > --- sys/dev/hid/hidmtvar.h 25 Aug 2018 18:32:05 -0000 1.6 > +++ sys/dev/hid/hidmtvar.h 25 Aug 2018 18:39:10 -0000 > @@ -67,7 +67,8 @@ struct hidmt { > }; > > int hidmt_set_input_mode(struct hidmt *, uint16_t); > -#define HIDMT_INPUT_MODE_MT 0x3 > +#define HIDMT_INPUT_MODE_MT_TOUCHSCREEN 0x2 > +#define HIDMT_INPUT_MODE_MT_TOUCHPAD 0x3 > > void hidmt_attach(struct hidmt *, const struct wsmouse_accessops *); > int hidmt_detach(struct hidmt *, int); > Index: sys/dev/i2c/imt.c > =================================================================== > RCS file: /cvs/src/sys/dev/i2c/imt.c,v > retrieving revision 1.3 > diff -u -p -u -p -r1.3 imt.c > --- sys/dev/i2c/imt.c 25 Aug 2018 18:32:05 -0000 1.3 > +++ sys/dev/i2c/imt.c 25 Aug 2018 18:39:10 -0000 > @@ -218,7 +218,7 @@ imt_enable(void *v) > > rv = ihidev_open(&sc->sc_hdev); > > - hidmt_set_input_mode(mt, HIDMT_INPUT_MODE_MT); > + hidmt_set_input_mode(mt, HIDMT_INPUT_MODE_MT_TOUCHPAD); > > return rv; > } > Index: sys/dev/usb/files.usb > =================================================================== > RCS file: /cvs/src/sys/dev/usb/files.usb,v > retrieving revision 1.135 > diff -u -p -u -p -r1.135 files.usb > --- sys/dev/usb/files.usb 3 Aug 2018 01:50:15 -0000 1.135 > +++ sys/dev/usb/files.usb 25 Aug 2018 18:39:10 -0000 > @@ -87,6 +87,11 @@ device ums: hid, hidms, wsmousedev > attach ums at uhidbus > file dev/usb/ums.c ums > > +# HID Multitouch Trackpad > +device umt: hid, hidmt, wsmousedev > +attach umt at uhidbus > +file dev/usb/umt.c umt > + > # USB Touchscreen > device uts: wsmousedev > attach uts at uhub > Index: sys/dev/usb/umt.c > =================================================================== > RCS file: sys/dev/usb/umt.c > diff -N sys/dev/usb/umt.c > --- /dev/null 1 Jan 1970 00:00:00 -0000 > +++ sys/dev/usb/umt.c 25 Aug 2018 18:39:11 -0000 > @@ -0,0 +1,253 @@ > +/* $OpenBSD$ */ > +/* > + * USB multitouch touchpad driver for devices conforming to > + * Windows Precision Touchpad standard > + * > + * > https://msdn.microsoft.com/en-us/library/windows/hardware/dn467314%28v=vs.85%29.aspx > + * > + * Copyright (c) 2016-2018 joshua stein <j...@openbsd.org> > + * > + * Permission to use, copy, modify, and distribute this software for any > + * purpose with or without fee is hereby granted, provided that the above > + * copyright notice and this permission notice appear in all copies. > + * > + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES > + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF > + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR > + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES > + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN > + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF > + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. > + */ > + > +#include <sys/param.h> > +#include <sys/systm.h> > +#include <sys/kernel.h> > +#include <sys/device.h> > +#include <sys/ioctl.h> > + > +#include <dev/usb/usb.h> > +#include <dev/usb/usbhid.h> > +#include <dev/usb/usbdi.h> > +#include <dev/usb/usbdevs.h> > +#include <dev/usb/uhidev.h> > + > +#include <dev/wscons/wsconsio.h> > +#include <dev/wscons/wsmousevar.h> > + > +#include <dev/hid/hid.h> > +#include <dev/hid/hidmtvar.h> > + > +struct umt_softc { > + struct uhidev sc_hdev; > + struct hidmt sc_mt; > + > + int sc_rep_input; > + int sc_rep_config; > + int sc_rep_cap; > +}; > + > +int umt_enable(void *); > +int umt_open(struct uhidev *); > +void umt_intr(struct uhidev *, void *, u_int); > +void umt_disable(void *); > +int umt_ioctl(void *, u_long, caddr_t, int, struct proc *); > + > +const struct wsmouse_accessops umt_accessops = { > + umt_enable, > + umt_ioctl, > + umt_disable, > +}; > + > +int umt_match(struct device *, void *, void *); > +int umt_find_winptp_reports(struct uhidev_softc *, void *, int, > + struct umt_softc *); > +void umt_attach(struct device *, struct device *, void *); > +int umt_hidev_get_report(struct device *, int, int, void *, int); > +int umt_hidev_set_report(struct device *, int, int, void *, int); > +int umt_detach(struct device *, int); > + > +struct cfdriver umt_cd = { > + NULL, "umt", DV_DULL > +}; > + > +const struct cfattach umt_ca = { > + sizeof(struct umt_softc), > + umt_match, > + umt_attach, > + umt_detach > +}; > + > +int > +umt_match(struct device *parent, void *match, void *aux) > +{ > + struct uhidev_attach_arg *uha = (struct uhidev_attach_arg *)aux; > + int size; > + void *desc; > + > + if (uha->reportid == UHIDEV_CLAIM_ALLREPORTID) { > + uhidev_get_report_desc(uha->parent, &desc, &size); > + if (umt_find_winptp_reports(uha->parent, desc, size, NULL)) > + return (UMATCH_DEVCLASS_DEVSUBCLASS); > + } > + > + return (UMATCH_NONE); > +} > + > +int > +umt_find_winptp_reports(struct uhidev_softc *parent, void *desc, int size, > + struct umt_softc *sc) > +{ > + int repid; > + int input = 0, conf = 0, cap = 0; > + > + if (sc != NULL) { > + sc->sc_rep_input = -1; > + sc->sc_rep_config = -1; > + sc->sc_rep_cap = -1; > + } > + > + for (repid = 0; repid < parent->sc_nrepid; repid++) { > + if (hid_report_size(desc, size, hid_input, repid) == 0 && > + hid_report_size(desc, size, hid_output, repid) == 0 && > + hid_report_size(desc, size, hid_feature, repid) == 0) > + continue; > + > + if (hid_is_collection(desc, size, repid, > + HID_USAGE2(HUP_DIGITIZERS, HUD_TOUCHPAD))) { > + input = 1; > + if (sc != NULL && sc->sc_rep_input == -1) > + sc->sc_rep_input = repid; > + } else if (hid_is_collection(desc, size, repid, > + HID_USAGE2(HUP_DIGITIZERS, HUD_CONFIG))) { > + conf = 1; > + if (sc != NULL && sc->sc_rep_config == -1) > + sc->sc_rep_config = repid; > + } > + > + /* capabilities report could be anywhere */ > + if (hid_locate(desc, size, HID_USAGE2(HUP_DIGITIZERS, > + HUD_CONTACT_MAX), repid, hid_feature, NULL, NULL)) { > + cap = 1; > + if (sc != NULL && sc->sc_rep_cap == -1) > + sc->sc_rep_cap = repid; > + } > + } > + > + return (conf && input && cap); > +} > + > +void > +umt_attach(struct device *parent, struct device *self, void *aux) > +{ > + struct umt_softc *sc = (struct umt_softc *)self; > + struct hidmt *mt = &sc->sc_mt; > + struct uhidev_attach_arg *uha = (struct uhidev_attach_arg *)aux; > + int size; > + void *desc; > + > + sc->sc_hdev.sc_intr = umt_intr; > + sc->sc_hdev.sc_parent = uha->parent; > + > + uhidev_get_report_desc(uha->parent, &desc, &size); > + umt_find_winptp_reports(uha->parent, desc, size, sc); > + > + memset(mt, 0, sizeof(sc->sc_mt)); > + > + /* assume everything has "natural scrolling" where Y axis is reversed */ > + mt->sc_flags = HIDMT_REVY; > + > + mt->hidev_report_type_conv = uhidev_report_type_conv; > + mt->hidev_get_report = umt_hidev_get_report; > + mt->hidev_set_report = umt_hidev_set_report; > + mt->sc_rep_input = sc->sc_rep_input; > + mt->sc_rep_config = sc->sc_rep_config; > + mt->sc_rep_cap = sc->sc_rep_cap; > + > + if (hidmt_setup(self, mt, desc, size) != 0) > + return; > + > + hidmt_attach(mt, &umt_accessops); > +} > + > +int > +umt_hidev_get_report(struct device *self, int type, int id, void *data, int > len) > +{ > + struct umt_softc *sc = (struct umt_softc *)self; > + int ret; > + > + ret = uhidev_get_report(sc->sc_hdev.sc_parent, type, id, data, len); > + return (ret < len); > +} > + > +int > +umt_hidev_set_report(struct device *self, int type, int id, void *data, int > len) > +{ > + struct umt_softc *sc = (struct umt_softc *)self; > + int ctype, ret; > + > + ret = uhidev_set_report(sc->sc_hdev.sc_parent, ctype, id, data, len); > + return (ret < len); > +} > + > +int > +umt_detach(struct device *self, int flags) > +{ > + struct umt_softc *sc = (struct umt_softc *)self; > + struct hidmt *mt = &sc->sc_mt; > + > + return hidmt_detach(mt, flags); > +} > + > +void > +umt_intr(struct uhidev *dev, void *buf, u_int len) > +{ > + struct umt_softc *sc = (struct umt_softc *)dev; > + struct hidmt *mt = &sc->sc_mt; > + > + if (!mt->sc_enabled) > + return; > + > + hidmt_input(mt, (uint8_t *)buf, len); > +} > + > +int > +umt_enable(void *v) > +{ > + struct umt_softc *sc = v; > + struct hidmt *mt = &sc->sc_mt; > + int rv; > + > + if ((rv = hidmt_enable(mt)) != 0) > + return rv; > + > + rv = uhidev_open(&sc->sc_hdev); > + > + hidmt_set_input_mode(mt, HIDMT_INPUT_MODE_MT_TOUCHPAD); > + > + return rv; > +} > + > +void > +umt_disable(void *v) > +{ > + struct umt_softc *sc = v; > + struct hidmt *mt = &sc->sc_mt; > + > + hidmt_disable(mt); > + uhidev_close(&sc->sc_hdev); > +} > + > +int > +umt_ioctl(void *v, u_long cmd, caddr_t data, int flag, struct proc *p) > +{ > + struct umt_softc *sc = v; > + struct hidmt *mt = &sc->sc_mt; > + int rc; > + > + rc = uhidev_ioctl(&sc->sc_hdev, cmd, data, flag, p); > + if (rc != -1) > + return rc; > + > + return hidmt_ioctl(mt, cmd, data, flag, p); > +} >