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 <[email protected]>
+.\"
+.\" 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 [email protected] .
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 <[email protected]>
+ *
+ * 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",