> Date: Sat, 30 May 2020 12:38:12 -0500
> From: joshua stein <[email protected]>
> 
> 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 <[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",
> 
> 

Reply via email to