umstc: Microsoft Surface Type Cover driver

classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

umstc: Microsoft Surface Type Cover driver

joshua stein
This makes the volume and screen brightness keys work, but more
importantly it keeps the USB data/interrupt pipes open at all times
because otherwise the Type Cover resets itself (or at least detaches
and reattaches) when these buttons are pressed.


diff --git share/man/man4/Makefile share/man/man4/Makefile
index 258399f2e7a..3c15cc14285 100644
--- share/man/man4/Makefile
+++ share/man/man4/Makefile
@@ -84,8 +84,8 @@ MAN= aac.4 abcrtc.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 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 \
+ ums.4 umsm.4 umstc.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 uxrcom.4 \
diff --git share/man/man4/umstc.4 share/man/man4/umstc.4
new file mode 100644
index 00000000000..da557c59d1d
--- /dev/null
+++ share/man/man4/umstc.4
@@ -0,0 +1,44 @@
+.\" $OpenBSD$
+.\"
+.\" Copyright (c) 2020 joshua stein <[hidden email]>
+.\"
+.\" 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 UMSTC 4
+.Os
+.Sh NAME
+.Nm umstc
+.Nd Microsoft Surface Type Cover driver
+.Sh SYNOPSIS
+.Cd "umstc* at uhidev?"
+.Sh DESCRIPTION
+The
+.Nm
+driver responds to some special keys on the Microsoft Type Cover
+keyboard, such as volume and screen brightness keys.
+.Sh SEE ALSO
+.Xr uhidev 4 ,
+.Xr usb 4 ,
+.Xr sysctl 8
+.Sh HISTORY
+The
+.Nm
+driver first appeared in
+.Ox 6.8 .
+.Sh AUTHORS
+.An -nosplit
+The
+.Nm
+driver was written by
+.An joshua stein Aq Mt [hidden email] .
diff --git sys/arch/amd64/conf/GENERIC sys/arch/amd64/conf/GENERIC
index b77a3b4ead5..624f73bb7cc 100644
--- sys/arch/amd64/conf/GENERIC
+++ sys/arch/amd64/conf/GENERIC
@@ -284,6 +284,7 @@ ucom* at uslhcom?
 uhid* at uhidev? # USB generic HID support
 fido* at uhidev? # FIDO/U2F security key support
 upd* at uhidev? # USB Power Devices sensors
+umstc* at uhidev? # Microsoft Surface Type Cover
 aue* at uhub? # ADMtek AN986 Pegasus Ethernet
 atu* at uhub? # Atmel AT76c50x based 802.11b
 axe* at uhub? # ASIX Electronics AX88172 USB Ethernet
diff --git sys/dev/hid/hid.h sys/dev/hid/hid.h
index 17de4065e0c..c528ab9551b 100644
--- sys/dev/hid/hid.h
+++ sys/dev/hid/hid.h
@@ -396,6 +396,11 @@ int hid_is_collection(const void *, int, uint8_t, int32_t);
 #define HUL_KANA 0x0005
 
 /* Usages, Consumer */
+#define HUC_CONTROL 0x0001
+#define HUC_PLAY_PAUSE 0x00cd
+#define HUC_MUTE 0x00e2
+#define HUC_VOL_INC 0x00e9
+#define HUC_VOL_DEC 0x00ea
 #define HUC_AC_PAN 0x0238
 
 /* Usages, FIDO */
diff --git sys/dev/usb/files.usb sys/dev/usb/files.usb
index c3597c54775..fc5ff46ce76 100644
--- sys/dev/usb/files.usb
+++ sys/dev/usb/files.usb
@@ -473,3 +473,8 @@ file dev/usb/uwacom.c uwacom
 
 attach bwfm at uhub with bwfm_usb: firmload
 file dev/usb/if_bwfm_usb.c bwfm_usb
+
+# Microsoft Surface Type Cover
+device umstc: hid
+attach umstc at uhidbus
+file dev/usb/umstc.c umstc
diff --git sys/dev/usb/umstc.c sys/dev/usb/umstc.c
new file mode 100644
index 00000000000..df995181bf6
--- /dev/null
+++ sys/dev/usb/umstc.c
@@ -0,0 +1,172 @@
+/* $OpenBSD$ */
+
+/*
+ * Copyright (c) 2020 joshua stein <[hidden email]>
+ *
+ * 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.
+ */
+
+/*
+ * Microsoft Surface Type Cover driver to respond to F1-F7 keys, but also to
+ * keep the USB HID pipes open or else the Type Cover will detach and reattach
+ * each time one of these buttons is pressed.
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/device.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/wsdisplayvar.h>
+
+#include "audio.h"
+#include "wsdisplay.h"
+
+struct umstc_softc {
+ struct uhidev sc_hdev;
+};
+
+void umstc_intr(struct uhidev *addr, void *ibuf, u_int len);
+int umstc_match(struct device *, void *, void *);
+void umstc_attach(struct device *, struct device *, void *);
+int umstc_detach(struct device *, int flags);
+
+extern int wskbd_set_mixervolume(long, long);
+
+struct cfdriver umstc_cd = {
+ NULL, "umstc", DV_DULL
+};
+
+const struct cfattach umstc_ca = {
+ sizeof(struct umstc_softc),
+ umstc_match,
+ umstc_attach,
+ umstc_detach,
+};
+
+static const struct usb_devno umstc_devs[] = {
+ { USB_VENDOR_MICROSOFT, USB_PRODUCT_MICROSOFT_TYPECOVER },
+ { USB_VENDOR_MICROSOFT, USB_PRODUCT_MICROSOFT_TYPECOVER2 },
+};
+
+int
+umstc_match(struct device *parent, void *match, void *aux)
+{
+ struct uhidev_attach_arg *uha = (struct uhidev_attach_arg *)aux;
+ int size;
+ void *desc;
+
+ if (!usb_lookup(umstc_devs, uha->uaa->vendor, uha->uaa->product))
+ return UMATCH_NONE;
+
+ uhidev_get_report_desc(uha->parent, &desc, &size);
+
+ if (hid_is_collection(desc, size, uha->reportid,
+    HID_USAGE2(HUP_CONSUMER, HUC_CONTROL)))
+ return UMATCH_IFACECLASS;
+
+ return UMATCH_NONE;
+}
+
+void
+umstc_attach(struct device *parent, struct device *self, void *aux)
+{
+ struct umstc_softc *sc = (struct umstc_softc *)self;
+ struct uhidev_attach_arg *uha = (struct uhidev_attach_arg *)aux;
+ struct usb_attach_arg *uaa = uha->uaa;
+ int size, repid;
+ void *desc;
+
+ sc->sc_hdev.sc_intr = umstc_intr;
+ sc->sc_hdev.sc_parent = uha->parent;
+ sc->sc_hdev.sc_udev = uaa->device;
+ sc->sc_hdev.sc_report_id = uha->reportid;
+
+ uhidev_get_report_desc(uha->parent, &desc, &size);
+ repid = uha->reportid;
+ sc->sc_hdev.sc_isize = hid_report_size(desc, size, hid_input, repid);
+ sc->sc_hdev.sc_osize = hid_report_size(desc, size, hid_output, repid);
+ sc->sc_hdev.sc_fsize = hid_report_size(desc, size, hid_feature, repid);
+
+ uhidev_open(&sc->sc_hdev);
+
+ printf("\n");
+}
+
+int
+umstc_detach(struct device *self, int flags)
+{
+ struct umstc_softc *sc = (struct umstc_softc *)self;
+
+ uhidev_close(&sc->sc_hdev);
+
+ return 0;
+}
+
+void
+umstc_intr(struct uhidev *addr, void *buf, u_int len)
+{
+ struct umstc_softc *sc = (struct umstc_softc *)addr;
+ int i;
+
+ if (!len)
+ return;
+
+ switch (((unsigned char *)buf)[0]) {
+ case HUC_PLAY_PAUSE:
+ /*
+ * It would be nice to pass this through to userland but we'd
+ * need to attach a wskbd
+ */
+ break;
+ case HUC_MUTE:
+#if NAUDIO > 0
+ wskbd_set_mixervolume(0, 1);
+#endif
+ break;
+ case HUC_VOL_INC:
+#if NAUDIO > 0
+ wskbd_set_mixervolume(1, 1);
+#endif
+ break;
+ case HUC_VOL_DEC:
+#if NAUDIO > 0
+ wskbd_set_mixervolume(-1, 1);
+#endif
+ break;
+ case 0x70: /* brightness down */
+#if NWSDISPLAY > 0
+ wsdisplay_brightness_step(NULL, -1);
+#endif
+ break;
+ case 0x6f: /* brightness up */
+#if NWSDISPLAY > 0
+ wsdisplay_brightness_step(NULL, 1);
+#endif
+ break;
+ case 0:
+ break;
+ default:
+ printf("%s: unhandled key ", sc->sc_hdev.sc_dev.dv_xname);
+ for (i = 0; i < len; i++)
+ printf(" 0x%02x", ((unsigned char *)buf)[i]);
+ printf("\n");
+ }
+}
diff --git sys/dev/usb/usbdevs sys/dev/usb/usbdevs
index 007ad1a659d..6eefafc85a3 100644
--- sys/dev/usb/usbdevs
+++ sys/dev/usb/usbdevs
@@ -3023,6 +3023,8 @@ product MICROSOFT XBOX360 0x0292 XBOX 360 WLAN
 product MICROSOFT WLMOBILEMOUSE3500 0x0745  Wireless Mobile Mouse 3500
 product MICROSOFT LIFECAM 0x074a Microsoft LifeCam
 product MICROSOFT WLARCMOUSE 0x074f Wireless Arc Mouse (Model 1350)
+product MICROSOFT TYPECOVER 0x096f Surface Go Type Cover
+product MICROSOFT TYPECOVER2 0x09b5 Surface Go Type Cover
 
 /* Microtech products */
 product MICROTECH SCSIDB25 0x0004 SCSI-DB25
diff --git sys/dev/usb/usbdevs.h sys/dev/usb/usbdevs.h
index 8cad9fa072e..1cb4932b9de 100644
--- sys/dev/usb/usbdevs.h
+++ sys/dev/usb/usbdevs.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: usbdevs.h,v 1.726 2020/05/26 06:03:39 jsg Exp $ */
+/* $OpenBSD$ */
 
 /*
  * THIS FILE IS AUTOMATICALLY GENERATED.  DO NOT EDIT.
@@ -3030,6 +3030,8 @@
 #define USB_PRODUCT_MICROSOFT_WLMOBILEMOUSE3500 0x0745 /* Wireless Mobile Mouse 3500 */
 #define USB_PRODUCT_MICROSOFT_LIFECAM 0x074a /* Microsoft LifeCam */
 #define USB_PRODUCT_MICROSOFT_WLARCMOUSE 0x074f /* Wireless Arc Mouse (Model 1350) */
+#define USB_PRODUCT_MICROSOFT_TYPECOVER 0x096f /* Surface Go Type Cover */
+#define USB_PRODUCT_MICROSOFT_TYPECOVER2 0x09b5 /* Surface Go Type Cover */
 
 /* Microtech products */
 #define USB_PRODUCT_MICROTECH_SCSIDB25 0x0004 /* SCSI-DB25 */
diff --git sys/dev/usb/usbdevs_data.h sys/dev/usb/usbdevs_data.h
index d3b9b83161f..9a2512f3e24 100644
--- sys/dev/usb/usbdevs_data.h
+++ sys/dev/usb/usbdevs_data.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: usbdevs_data.h,v 1.720 2020/05/26 06:03:39 jsg Exp $ */
+/* $OpenBSD$ */
 
 /*
  * THIS FILE IS AUTOMATICALLY GENERATED.  DO NOT EDIT.
@@ -7305,6 +7305,14 @@ const struct usb_known_product usb_known_products[] = {
     USB_VENDOR_MICROSOFT, USB_PRODUCT_MICROSOFT_WLARCMOUSE,
     "Wireless Arc Mouse (Model 1350)",
  },
+ {
+    USB_VENDOR_MICROSOFT, USB_PRODUCT_MICROSOFT_TYPECOVER,
+    "Surface Go Type Cover",
+ },
+ {
+    USB_VENDOR_MICROSOFT, USB_PRODUCT_MICROSOFT_TYPECOVER2,
+    "Surface Go Type Cover",
+ },
  {
     USB_VENDOR_MICROTECH, USB_PRODUCT_MICROTECH_SCSIDB25,
     "SCSI-DB25",

Reply | Threaded
Open this post in threaded view
|

Re: umstc: Microsoft Surface Type Cover driver

Mark Kettenis
> Date: Sat, 30 May 2020 12:38:12 -0500
> From: joshua stein <[hidden email]>
>
> This makes the volume and screen brightness keys work, but more
> importantly it keeps the USB data/interrupt pipes open at all times
> because otherwise the Type Cover resets itself (or at least detaches
> and reattaches) when these buttons are pressed.

I have no real objection to this going in.  I do wonder though whether
it makes sense to add a more general driver that attaches to all USB
HID devices that provide a HUP_CONSUMER, HUC_CONTROL collection.  And
attaching it as a wskbd(4) isn't such as strange idea.


> diff --git share/man/man4/Makefile share/man/man4/Makefile
> index 258399f2e7a..3c15cc14285 100644
> --- share/man/man4/Makefile
> +++ share/man/man4/Makefile
> @@ -84,8 +84,8 @@ MAN= aac.4 abcrtc.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 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 \
> + ums.4 umsm.4 umstc.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 uxrcom.4 \
> diff --git share/man/man4/umstc.4 share/man/man4/umstc.4
> new file mode 100644
> index 00000000000..da557c59d1d
> --- /dev/null
> +++ share/man/man4/umstc.4
> @@ -0,0 +1,44 @@
> +.\" $OpenBSD$
> +.\"
> +.\" Copyright (c) 2020 joshua stein <[hidden email]>
> +.\"
> +.\" 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 UMSTC 4
> +.Os
> +.Sh NAME
> +.Nm umstc
> +.Nd Microsoft Surface Type Cover driver
> +.Sh SYNOPSIS
> +.Cd "umstc* at uhidev?"
> +.Sh DESCRIPTION
> +The
> +.Nm
> +driver responds to some special keys on the Microsoft Type Cover
> +keyboard, such as volume and screen brightness keys.
> +.Sh SEE ALSO
> +.Xr uhidev 4 ,
> +.Xr usb 4 ,
> +.Xr sysctl 8
> +.Sh HISTORY
> +The
> +.Nm
> +driver first appeared in
> +.Ox 6.8 .
> +.Sh AUTHORS
> +.An -nosplit
> +The
> +.Nm
> +driver was written by
> +.An joshua stein Aq Mt [hidden email] .
> diff --git sys/arch/amd64/conf/GENERIC sys/arch/amd64/conf/GENERIC
> index b77a3b4ead5..624f73bb7cc 100644
> --- sys/arch/amd64/conf/GENERIC
> +++ sys/arch/amd64/conf/GENERIC
> @@ -284,6 +284,7 @@ ucom* at uslhcom?
>  uhid* at uhidev? # USB generic HID support
>  fido* at uhidev? # FIDO/U2F security key support
>  upd* at uhidev? # USB Power Devices sensors
> +umstc* at uhidev? # Microsoft Surface Type Cover
>  aue* at uhub? # ADMtek AN986 Pegasus Ethernet
>  atu* at uhub? # Atmel AT76c50x based 802.11b
>  axe* at uhub? # ASIX Electronics AX88172 USB Ethernet
> diff --git sys/dev/hid/hid.h sys/dev/hid/hid.h
> index 17de4065e0c..c528ab9551b 100644
> --- sys/dev/hid/hid.h
> +++ sys/dev/hid/hid.h
> @@ -396,6 +396,11 @@ int hid_is_collection(const void *, int, uint8_t, int32_t);
>  #define HUL_KANA 0x0005
>  
>  /* Usages, Consumer */
> +#define HUC_CONTROL 0x0001
> +#define HUC_PLAY_PAUSE 0x00cd
> +#define HUC_MUTE 0x00e2
> +#define HUC_VOL_INC 0x00e9
> +#define HUC_VOL_DEC 0x00ea
>  #define HUC_AC_PAN 0x0238
>  
>  /* Usages, FIDO */
> diff --git sys/dev/usb/files.usb sys/dev/usb/files.usb
> index c3597c54775..fc5ff46ce76 100644
> --- sys/dev/usb/files.usb
> +++ sys/dev/usb/files.usb
> @@ -473,3 +473,8 @@ file dev/usb/uwacom.c uwacom
>  
>  attach bwfm at uhub with bwfm_usb: firmload
>  file dev/usb/if_bwfm_usb.c bwfm_usb
> +
> +# Microsoft Surface Type Cover
> +device umstc: hid
> +attach umstc at uhidbus
> +file dev/usb/umstc.c umstc
> diff --git sys/dev/usb/umstc.c sys/dev/usb/umstc.c
> new file mode 100644
> index 00000000000..df995181bf6
> --- /dev/null
> +++ sys/dev/usb/umstc.c
> @@ -0,0 +1,172 @@
> +/* $OpenBSD$ */
> +
> +/*
> + * Copyright (c) 2020 joshua stein <[hidden email]>
> + *
> + * 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.
> + */
> +
> +/*
> + * Microsoft Surface Type Cover driver to respond to F1-F7 keys, but also to
> + * keep the USB HID pipes open or else the Type Cover will detach and reattach
> + * each time one of these buttons is pressed.
> + */
> +
> +#include <sys/param.h>
> +#include <sys/systm.h>
> +#include <sys/kernel.h>
> +#include <sys/device.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/wsdisplayvar.h>
> +
> +#include "audio.h"
> +#include "wsdisplay.h"
> +
> +struct umstc_softc {
> + struct uhidev sc_hdev;
> +};
> +
> +void umstc_intr(struct uhidev *addr, void *ibuf, u_int len);
> +int umstc_match(struct device *, void *, void *);
> +void umstc_attach(struct device *, struct device *, void *);
> +int umstc_detach(struct device *, int flags);
> +
> +extern int wskbd_set_mixervolume(long, long);
> +
> +struct cfdriver umstc_cd = {
> + NULL, "umstc", DV_DULL
> +};
> +
> +const struct cfattach umstc_ca = {
> + sizeof(struct umstc_softc),
> + umstc_match,
> + umstc_attach,
> + umstc_detach,
> +};
> +
> +static const struct usb_devno umstc_devs[] = {
> + { USB_VENDOR_MICROSOFT, USB_PRODUCT_MICROSOFT_TYPECOVER },
> + { USB_VENDOR_MICROSOFT, USB_PRODUCT_MICROSOFT_TYPECOVER2 },
> +};
> +
> +int
> +umstc_match(struct device *parent, void *match, void *aux)
> +{
> + struct uhidev_attach_arg *uha = (struct uhidev_attach_arg *)aux;
> + int size;
> + void *desc;
> +
> + if (!usb_lookup(umstc_devs, uha->uaa->vendor, uha->uaa->product))
> + return UMATCH_NONE;
> +
> + uhidev_get_report_desc(uha->parent, &desc, &size);
> +
> + if (hid_is_collection(desc, size, uha->reportid,
> +    HID_USAGE2(HUP_CONSUMER, HUC_CONTROL)))
> + return UMATCH_IFACECLASS;
> +
> + return UMATCH_NONE;
> +}
> +
> +void
> +umstc_attach(struct device *parent, struct device *self, void *aux)
> +{
> + struct umstc_softc *sc = (struct umstc_softc *)self;
> + struct uhidev_attach_arg *uha = (struct uhidev_attach_arg *)aux;
> + struct usb_attach_arg *uaa = uha->uaa;
> + int size, repid;
> + void *desc;
> +
> + sc->sc_hdev.sc_intr = umstc_intr;
> + sc->sc_hdev.sc_parent = uha->parent;
> + sc->sc_hdev.sc_udev = uaa->device;
> + sc->sc_hdev.sc_report_id = uha->reportid;
> +
> + uhidev_get_report_desc(uha->parent, &desc, &size);
> + repid = uha->reportid;
> + sc->sc_hdev.sc_isize = hid_report_size(desc, size, hid_input, repid);
> + sc->sc_hdev.sc_osize = hid_report_size(desc, size, hid_output, repid);
> + sc->sc_hdev.sc_fsize = hid_report_size(desc, size, hid_feature, repid);
> +
> + uhidev_open(&sc->sc_hdev);
> +
> + printf("\n");
> +}
> +
> +int
> +umstc_detach(struct device *self, int flags)
> +{
> + struct umstc_softc *sc = (struct umstc_softc *)self;
> +
> + uhidev_close(&sc->sc_hdev);
> +
> + return 0;
> +}
> +
> +void
> +umstc_intr(struct uhidev *addr, void *buf, u_int len)
> +{
> + struct umstc_softc *sc = (struct umstc_softc *)addr;
> + int i;
> +
> + if (!len)
> + return;
> +
> + switch (((unsigned char *)buf)[0]) {
> + case HUC_PLAY_PAUSE:
> + /*
> + * It would be nice to pass this through to userland but we'd
> + * need to attach a wskbd
> + */
> + break;
> + case HUC_MUTE:
> +#if NAUDIO > 0
> + wskbd_set_mixervolume(0, 1);
> +#endif
> + break;
> + case HUC_VOL_INC:
> +#if NAUDIO > 0
> + wskbd_set_mixervolume(1, 1);
> +#endif
> + break;
> + case HUC_VOL_DEC:
> +#if NAUDIO > 0
> + wskbd_set_mixervolume(-1, 1);
> +#endif
> + break;
> + case 0x70: /* brightness down */
> +#if NWSDISPLAY > 0
> + wsdisplay_brightness_step(NULL, -1);
> +#endif
> + break;
> + case 0x6f: /* brightness up */
> +#if NWSDISPLAY > 0
> + wsdisplay_brightness_step(NULL, 1);
> +#endif
> + break;
> + case 0:
> + break;
> + default:
> + printf("%s: unhandled key ", sc->sc_hdev.sc_dev.dv_xname);
> + for (i = 0; i < len; i++)
> + printf(" 0x%02x", ((unsigned char *)buf)[i]);
> + printf("\n");
> + }
> +}
> diff --git sys/dev/usb/usbdevs sys/dev/usb/usbdevs
> index 007ad1a659d..6eefafc85a3 100644
> --- sys/dev/usb/usbdevs
> +++ sys/dev/usb/usbdevs
> @@ -3023,6 +3023,8 @@ product MICROSOFT XBOX360 0x0292 XBOX 360 WLAN
>  product MICROSOFT WLMOBILEMOUSE3500 0x0745  Wireless Mobile Mouse 3500
>  product MICROSOFT LIFECAM 0x074a Microsoft LifeCam
>  product MICROSOFT WLARCMOUSE 0x074f Wireless Arc Mouse (Model 1350)
> +product MICROSOFT TYPECOVER 0x096f Surface Go Type Cover
> +product MICROSOFT TYPECOVER2 0x09b5 Surface Go Type Cover
>  
>  /* Microtech products */
>  product MICROTECH SCSIDB25 0x0004 SCSI-DB25
> diff --git sys/dev/usb/usbdevs.h sys/dev/usb/usbdevs.h
> index 8cad9fa072e..1cb4932b9de 100644
> --- sys/dev/usb/usbdevs.h
> +++ sys/dev/usb/usbdevs.h
> @@ -1,4 +1,4 @@
> -/* $OpenBSD: usbdevs.h,v 1.726 2020/05/26 06:03:39 jsg Exp $ */
> +/* $OpenBSD$ */
>  
>  /*
>   * THIS FILE IS AUTOMATICALLY GENERATED.  DO NOT EDIT.
> @@ -3030,6 +3030,8 @@
>  #define USB_PRODUCT_MICROSOFT_WLMOBILEMOUSE3500 0x0745 /* Wireless Mobile Mouse 3500 */
>  #define USB_PRODUCT_MICROSOFT_LIFECAM 0x074a /* Microsoft LifeCam */
>  #define USB_PRODUCT_MICROSOFT_WLARCMOUSE 0x074f /* Wireless Arc Mouse (Model 1350) */
> +#define USB_PRODUCT_MICROSOFT_TYPECOVER 0x096f /* Surface Go Type Cover */
> +#define USB_PRODUCT_MICROSOFT_TYPECOVER2 0x09b5 /* Surface Go Type Cover */
>  
>  /* Microtech products */
>  #define USB_PRODUCT_MICROTECH_SCSIDB25 0x0004 /* SCSI-DB25 */
> diff --git sys/dev/usb/usbdevs_data.h sys/dev/usb/usbdevs_data.h
> index d3b9b83161f..9a2512f3e24 100644
> --- sys/dev/usb/usbdevs_data.h
> +++ sys/dev/usb/usbdevs_data.h
> @@ -1,4 +1,4 @@
> -/* $OpenBSD: usbdevs_data.h,v 1.720 2020/05/26 06:03:39 jsg Exp $ */
> +/* $OpenBSD$ */
>  
>  /*
>   * THIS FILE IS AUTOMATICALLY GENERATED.  DO NOT EDIT.
> @@ -7305,6 +7305,14 @@ const struct usb_known_product usb_known_products[] = {
>      USB_VENDOR_MICROSOFT, USB_PRODUCT_MICROSOFT_WLARCMOUSE,
>      "Wireless Arc Mouse (Model 1350)",
>   },
> + {
> +    USB_VENDOR_MICROSOFT, USB_PRODUCT_MICROSOFT_TYPECOVER,
> +    "Surface Go Type Cover",
> + },
> + {
> +    USB_VENDOR_MICROSOFT, USB_PRODUCT_MICROSOFT_TYPECOVER2,
> +    "Surface Go Type Cover",
> + },
>   {
>      USB_VENDOR_MICROTECH, USB_PRODUCT_MICROTECH_SCSIDB25,
>      "SCSI-DB25",
>
>