Module Name:    src
Committed By:   bouyer
Date:           Sun Dec 10 17:03:07 UTC 2017

Modified Files:
        src/sys/conf: files
        src/sys/dev/bluetooth: bthidev.c btkbd.c btmagic.c btms.c
        src/sys/dev/fdt: gpiokeys.c
        src/sys/dev/i2c: tcakp.c
        src/sys/dev/usb: files.usb uatp.c ucycom.c uhid.c uhidev.c ukbd.c ums.c
            usbhid.h uthum.c uts.c uyurex.c
Added Files:
        src/sys/dev/hid: files.hid hid.c hid.h hidkbdmap.c hidms.c hidms.h
Removed Files:
        src/sys/dev/usb: hid.c hid.h ukbdmap.c

Log Message:
Factor out bus-independant HID code so that it can be shared by USB, bluetooth
and i2c.
dev/usb/ukbdmap.c is renamed to dev/hid/hidkbdmap.c
dev/usb/hid.[ch] moved to dev/hid/
usage pages moved from dev/usb/usbhid.h moved to dev/hid/hid.h,
and updated with OpenBSD entries.
bus-independant code moved from dev/usb/ums.c to dev/hid/hidms.c
(the same should be done for keyboard and touchpad drivers)

Needed for the upcoming HID over I2C support, proposed on tech-kern@
on Dec, 1.


To generate a diff of this commit:
cvs rdiff -u -r1.1185 -r1.1186 src/sys/conf/files
cvs rdiff -u -r1.29 -r1.30 src/sys/dev/bluetooth/bthidev.c
cvs rdiff -u -r1.17 -r1.18 src/sys/dev/bluetooth/btkbd.c
cvs rdiff -u -r1.16 -r1.17 src/sys/dev/bluetooth/btmagic.c
cvs rdiff -u -r1.12 -r1.13 src/sys/dev/bluetooth/btms.c
cvs rdiff -u -r1.5 -r1.6 src/sys/dev/fdt/gpiokeys.c
cvs rdiff -u -r0 -r1.1 src/sys/dev/hid/files.hid src/sys/dev/hid/hid.c \
    src/sys/dev/hid/hid.h src/sys/dev/hid/hidkbdmap.c src/sys/dev/hid/hidms.c \
    src/sys/dev/hid/hidms.h
cvs rdiff -u -r1.4 -r1.5 src/sys/dev/i2c/tcakp.c
cvs rdiff -u -r1.147 -r1.148 src/sys/dev/usb/files.usb
cvs rdiff -u -r1.47 -r0 src/sys/dev/usb/hid.c
cvs rdiff -u -r1.14 -r0 src/sys/dev/usb/hid.h
cvs rdiff -u -r1.14 -r1.15 src/sys/dev/usb/uatp.c
cvs rdiff -u -r1.45 -r1.46 src/sys/dev/usb/ucycom.c
cvs rdiff -u -r1.100 -r1.101 src/sys/dev/usb/uhid.c
cvs rdiff -u -r1.72 -r1.73 src/sys/dev/usb/uhidev.c
cvs rdiff -u -r1.138 -r1.139 src/sys/dev/usb/ukbd.c
cvs rdiff -u -r1.31 -r0 src/sys/dev/usb/ukbdmap.c
cvs rdiff -u -r1.90 -r1.91 src/sys/dev/usb/ums.c
cvs rdiff -u -r1.16 -r1.17 src/sys/dev/usb/usbhid.h
cvs rdiff -u -r1.13 -r1.14 src/sys/dev/usb/uthum.c
cvs rdiff -u -r1.7 -r1.8 src/sys/dev/usb/uts.c
cvs rdiff -u -r1.12 -r1.13 src/sys/dev/usb/uyurex.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/conf/files
diff -u src/sys/conf/files:1.1185 src/sys/conf/files:1.1186
--- src/sys/conf/files:1.1185	Sat Nov 25 16:31:03 2017
+++ src/sys/conf/files	Sun Dec 10 17:03:07 2017
@@ -1,4 +1,4 @@
-#	$NetBSD: files,v 1.1185 2017/11/25 16:31:03 jmcneill Exp $
+#	$NetBSD: files,v 1.1186 2017/12/10 17:03:07 bouyer Exp $
 #	@(#)files.newconf	7.5 (Berkeley) 5/10/93
 
 version 	20171118
@@ -379,6 +379,9 @@ file	dev/ic/nslm7x.c			lm			needs-flag
 device	spdmem
 file	dev/ic/spdmem.c			spdmem
 
+# Generic HID support (used by USB, bluetooth and i2c)
+include "dev/hid/files.hid"
+
 # I2C device support
 include "dev/i2c/files.i2c"
 
@@ -1291,10 +1294,6 @@ file	dev/ic/sl811hs.c		slhci			needs-fla
 #
 include "external/bsd/dwc2/conf/files.dwc2"
 
-# USB HID processing (as used by bluetooth and usb code)
-define	hid
-file	dev/usb/hid.c			hid
-
 # SD Host controller
 device	sdhc: sdmmcbus
 file	dev/sdmmc/sdhc.c		sdhc			needs-flag

Index: src/sys/dev/bluetooth/bthidev.c
diff -u src/sys/dev/bluetooth/bthidev.c:1.29 src/sys/dev/bluetooth/bthidev.c:1.30
--- src/sys/dev/bluetooth/bthidev.c:1.29	Tue Aug  5 07:55:31 2014
+++ src/sys/dev/bluetooth/bthidev.c	Sun Dec 10 17:03:07 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: bthidev.c,v 1.29 2014/08/05 07:55:31 rtr Exp $	*/
+/*	$NetBSD: bthidev.c,v 1.30 2017/12/10 17:03:07 bouyer Exp $	*/
 
 /*-
  * Copyright (c) 2006 Itronix Inc.
@@ -32,7 +32,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: bthidev.c,v 1.29 2014/08/05 07:55:31 rtr Exp $");
+__KERNEL_RCSID(0, "$NetBSD: bthidev.c,v 1.30 2017/12/10 17:03:07 bouyer Exp $");
 
 #include <sys/param.h>
 #include <sys/condvar.h>
@@ -54,7 +54,7 @@ __KERNEL_RCSID(0, "$NetBSD: bthidev.c,v 
 #include <netbt/bluetooth.h>
 #include <netbt/l2cap.h>
 
-#include <dev/usb/hid.h>
+#include <dev/hid/hid.h>
 #include <dev/bluetooth/btdev.h>
 #include <dev/bluetooth/bthid.h>
 #include <dev/bluetooth/bthidev.h>

Index: src/sys/dev/bluetooth/btkbd.c
diff -u src/sys/dev/bluetooth/btkbd.c:1.17 src/sys/dev/bluetooth/btkbd.c:1.18
--- src/sys/dev/bluetooth/btkbd.c:1.17	Sun Nov 16 16:20:00 2014
+++ src/sys/dev/bluetooth/btkbd.c	Sun Dec 10 17:03:07 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: btkbd.c,v 1.17 2014/11/16 16:20:00 ozaki-r Exp $	*/
+/*	$NetBSD: btkbd.c,v 1.18 2017/12/10 17:03:07 bouyer Exp $	*/
 
 /*
  * Copyright (c) 1998 The NetBSD Foundation, Inc.
@@ -66,7 +66,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: btkbd.c,v 1.17 2014/11/16 16:20:00 ozaki-r Exp $");
+__KERNEL_RCSID(0, "$NetBSD: btkbd.c,v 1.18 2017/12/10 17:03:07 bouyer Exp $");
 
 #include <sys/param.h>
 #include <sys/callout.h>
@@ -81,7 +81,7 @@ __KERNEL_RCSID(0, "$NetBSD: btkbd.c,v 1.
 #include <dev/bluetooth/bthid.h>
 #include <dev/bluetooth/bthidev.h>
 
-#include <dev/usb/hid.h>
+#include <dev/hid/hid.h>
 #include <dev/usb/usb.h>
 #include <dev/usb/usbhid.h>
 
@@ -163,10 +163,10 @@ static const struct wskbd_accessops btkb
 };
 
 /* wskbd(4) keymap data */
-extern const struct wscons_keydesc ukbd_keydesctab[];
+extern const struct wscons_keydesc hidkbd_keydesctab[];
 
 const struct wskbd_mapdata btkbd_keymapdata = {
-	ukbd_keydesctab,
+	hidkbd_keydesctab,
 #if defined(BTKBD_LAYOUT)
 	BTKBD_LAYOUT,
 #elif defined(PCKBD_LAYOUT)

Index: src/sys/dev/bluetooth/btmagic.c
diff -u src/sys/dev/bluetooth/btmagic.c:1.16 src/sys/dev/bluetooth/btmagic.c:1.17
--- src/sys/dev/bluetooth/btmagic.c:1.16	Thu Jul  7 06:55:41 2016
+++ src/sys/dev/bluetooth/btmagic.c	Sun Dec 10 17:03:07 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: btmagic.c,v 1.16 2016/07/07 06:55:41 msaitoh Exp $	*/
+/*	$NetBSD: btmagic.c,v 1.17 2017/12/10 17:03:07 bouyer Exp $	*/
 
 /*-
  * Copyright (c) 2010 The NetBSD Foundation, Inc.
@@ -85,7 +85,7 @@
  *****************************************************************************/
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: btmagic.c,v 1.16 2016/07/07 06:55:41 msaitoh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: btmagic.c,v 1.17 2017/12/10 17:03:07 bouyer Exp $");
 
 #include <sys/param.h>
 #include <sys/conf.h>
@@ -108,7 +108,7 @@ __KERNEL_RCSID(0, "$NetBSD: btmagic.c,v 
 #include <dev/bluetooth/bthid.h>
 #include <dev/bluetooth/bthidev.h>
 
-#include <dev/usb/hid.h>
+#include <dev/hid/hid.h>
 #include <dev/usb/usb.h>
 #include <dev/usb/usbdevs.h>
 

Index: src/sys/dev/bluetooth/btms.c
diff -u src/sys/dev/bluetooth/btms.c:1.12 src/sys/dev/bluetooth/btms.c:1.13
--- src/sys/dev/bluetooth/btms.c:1.12	Sat Dec 13 19:28:55 2014
+++ src/sys/dev/bluetooth/btms.c	Sun Dec 10 17:03:07 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: btms.c,v 1.12 2014/12/13 19:28:55 nonaka Exp $	*/
+/*	$NetBSD: btms.c,v 1.13 2017/12/10 17:03:07 bouyer Exp $	*/
 
 /*
  * Copyright (c) 1998 The NetBSD Foundation, Inc.
@@ -66,7 +66,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: btms.c,v 1.12 2014/12/13 19:28:55 nonaka Exp $");
+__KERNEL_RCSID(0, "$NetBSD: btms.c,v 1.13 2017/12/10 17:03:07 bouyer Exp $");
 
 #include <sys/param.h>
 #include <sys/conf.h>
@@ -79,7 +79,7 @@ __KERNEL_RCSID(0, "$NetBSD: btms.c,v 1.1
 #include <dev/bluetooth/bthid.h>
 #include <dev/bluetooth/bthidev.h>
 
-#include <dev/usb/hid.h>
+#include <dev/hid/hid.h>
 #include <dev/usb/usb.h>
 #include <dev/usb/usbhid.h>
 

Index: src/sys/dev/fdt/gpiokeys.c
diff -u src/sys/dev/fdt/gpiokeys.c:1.5 src/sys/dev/fdt/gpiokeys.c:1.6
--- src/sys/dev/fdt/gpiokeys.c:1.5	Sat Sep 23 23:54:30 2017
+++ src/sys/dev/fdt/gpiokeys.c	Sun Dec 10 17:03:07 2017
@@ -1,4 +1,4 @@
-/* $NetBSD: gpiokeys.c,v 1.5 2017/09/23 23:54:30 jmcneill Exp $ */
+/* $NetBSD: gpiokeys.c,v 1.6 2017/12/10 17:03:07 bouyer Exp $ */
 
 /*-
  * Copyright (c) 2015 Jared D. McNeill <jmcne...@invisible.ca>
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: gpiokeys.c,v 1.5 2017/09/23 23:54:30 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: gpiokeys.c,v 1.6 2017/12/10 17:03:07 bouyer Exp $");
 
 #include <sys/param.h>
 #include <sys/kernel.h>
@@ -59,9 +59,9 @@ static void	gpiokeys_attach(device_t, de
 static void	gpiokeys_tick(void *);
 static void	gpiokeys_task(void *);
 
-extern const struct wscons_keydesc ukbd_keydesctab[];
+extern const struct wscons_keydesc hidkbd_keydesctab[];
 static const struct wskbd_mapdata gpiokeys_keymapdata = {
-	ukbd_keydesctab,
+	hidkbd_keydesctab,
 	KB_US,
 };
 

Index: src/sys/dev/i2c/tcakp.c
diff -u src/sys/dev/i2c/tcakp.c:1.4 src/sys/dev/i2c/tcakp.c:1.5
--- src/sys/dev/i2c/tcakp.c:1.4	Thu Aug 31 19:55:43 2017
+++ src/sys/dev/i2c/tcakp.c	Sun Dec 10 17:03:07 2017
@@ -1,4 +1,4 @@
-/* $NetBSD: tcakp.c,v 1.4 2017/08/31 19:55:43 jmcneill Exp $ */
+/* $NetBSD: tcakp.c,v 1.5 2017/12/10 17:03:07 bouyer Exp $ */
 
 /*-
  * Copyright (c) 2017 Jared McNeill <jmcne...@invisible.ca>
@@ -29,7 +29,7 @@
 #include "opt_fdt.h"
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: tcakp.c,v 1.4 2017/08/31 19:55:43 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: tcakp.c,v 1.5 2017/12/10 17:03:07 bouyer Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -306,9 +306,9 @@ static const struct wskbd_consops tcakp_
 };
 #endif
 
-extern const struct wscons_keydesc ukbd_keydesctab[];
+extern const struct wscons_keydesc hidkbd_keydesctab[];
 static const struct wskbd_mapdata tcakp_keymapdata = {
-	ukbd_keydesctab,
+	hidkbd_keydesctab,
 	KB_US,
 };
 

Index: src/sys/dev/usb/files.usb
diff -u src/sys/dev/usb/files.usb:1.147 src/sys/dev/usb/files.usb:1.148
--- src/sys/dev/usb/files.usb:1.147	Thu Oct 19 23:58:41 2017
+++ src/sys/dev/usb/files.usb	Sun Dec 10 17:03:07 2017
@@ -1,4 +1,4 @@
-#	$NetBSD: files.usb,v 1.147 2017/10/19 23:58:41 jmcneill Exp $
+#	$NetBSD: files.usb,v 1.148 2017/12/10 17:03:07 bouyer Exp $
 #
 # Config file and device description for machine-independent USB code.
 # Included by ports that need it.  Ports that use it must provide
@@ -162,10 +162,9 @@ defflag		opt_ukbd.h 	GDIUM_KEYBOARD_HACK
 device	ukbd: hid, wskbddev
 attach	ukbd at uhidbus
 file	dev/usb/ukbd.c			ukbd			needs-flag
-file	dev/usb/ukbdmap.c		ukbd | btkbd | linux_keymap
 
 # Mice
-device	ums: hid, wsmousedev
+device	ums: hid, hidms, wsmousedev
 attach	ums at uhidbus
 file	dev/usb/ums.c			ums
 

Index: src/sys/dev/usb/uatp.c
diff -u src/sys/dev/usb/uatp.c:1.14 src/sys/dev/usb/uatp.c:1.15
--- src/sys/dev/usb/uatp.c:1.14	Sun Apr  9 16:40:42 2017
+++ src/sys/dev/usb/uatp.c	Sun Dec 10 17:03:07 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: uatp.c,v 1.14 2017/04/09 16:40:42 riastradh Exp $	*/
+/*	$NetBSD: uatp.c,v 1.15 2017/12/10 17:03:07 bouyer Exp $	*/
 
 /*-
  * Copyright (c) 2011-2014 The NetBSD Foundation, Inc.
@@ -146,7 +146,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: uatp.c,v 1.14 2017/04/09 16:40:42 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: uatp.c,v 1.15 2017/12/10 17:03:07 bouyer Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_usb.h"
@@ -170,8 +170,8 @@ __KERNEL_RCSID(0, "$NetBSD: uatp.c,v 1.1
 #include <dev/usb/usbdi_util.h>
 #include <dev/usb/usbdevs.h>
 #include <dev/usb/uhidev.h>
-#include <dev/usb/hid.h>
 #include <dev/usb/usbhid.h>
+#include <dev/hid/hid.h>
 
 #include <dev/wscons/wsconsio.h>
 #include <dev/wscons/wsmousevar.h>

Index: src/sys/dev/usb/ucycom.c
diff -u src/sys/dev/usb/ucycom.c:1.45 src/sys/dev/usb/ucycom.c:1.46
--- src/sys/dev/usb/ucycom.c:1.45	Fri Nov 25 12:56:29 2016
+++ src/sys/dev/usb/ucycom.c	Sun Dec 10 17:03:07 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: ucycom.c,v 1.45 2016/11/25 12:56:29 skrll Exp $	*/
+/*	$NetBSD: ucycom.c,v 1.46 2017/12/10 17:03:07 bouyer Exp $	*/
 
 /*
  * Copyright (c) 2005 The NetBSD Foundation, Inc.
@@ -38,7 +38,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ucycom.c,v 1.45 2016/11/25 12:56:29 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ucycom.c,v 1.46 2017/12/10 17:03:07 bouyer Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_usb.h"
@@ -64,7 +64,7 @@ __KERNEL_RCSID(0, "$NetBSD: ucycom.c,v 1
 #include <dev/usb/usbdi_util.h>
 #include <dev/usb/usbdevs.h>
 #include <dev/usb/uhidev.h>
-#include <dev/usb/hid.h>
+#include <dev/hid/hid.h>
 
 #include "ioconf.h"
 

Index: src/sys/dev/usb/uhid.c
diff -u src/sys/dev/usb/uhid.c:1.100 src/sys/dev/usb/uhid.c:1.101
--- src/sys/dev/usb/uhid.c:1.100	Wed Oct 25 08:12:39 2017
+++ src/sys/dev/usb/uhid.c	Sun Dec 10 17:03:07 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: uhid.c,v 1.100 2017/10/25 08:12:39 maya Exp $	*/
+/*	$NetBSD: uhid.c,v 1.101 2017/12/10 17:03:07 bouyer Exp $	*/
 
 /*
  * Copyright (c) 1998, 2004, 2008, 2012 The NetBSD Foundation, Inc.
@@ -35,7 +35,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: uhid.c,v 1.100 2017/10/25 08:12:39 maya Exp $");
+__KERNEL_RCSID(0, "$NetBSD: uhid.c,v 1.101 2017/12/10 17:03:07 bouyer Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_compat_netbsd.h"
@@ -64,8 +64,8 @@ __KERNEL_RCSID(0, "$NetBSD: uhid.c,v 1.1
 #include <dev/usb/usbdevs.h>
 #include <dev/usb/usbdi.h>
 #include <dev/usb/usbdi_util.h>
-#include <dev/usb/hid.h>
 #include <dev/usb/usb_quirks.h>
+#include <dev/hid/hid.h>
 
 #include <dev/usb/uhidev.h>
 

Index: src/sys/dev/usb/uhidev.c
diff -u src/sys/dev/usb/uhidev.c:1.72 src/sys/dev/usb/uhidev.c:1.73
--- src/sys/dev/usb/uhidev.c:1.72	Sat Sep  2 04:35:51 2017
+++ src/sys/dev/usb/uhidev.c	Sun Dec 10 17:03:07 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: uhidev.c,v 1.72 2017/09/02 04:35:51 ryoon Exp $	*/
+/*	$NetBSD: uhidev.c,v 1.73 2017/12/10 17:03:07 bouyer Exp $	*/
 
 /*
  * Copyright (c) 2001, 2012 The NetBSD Foundation, Inc.
@@ -35,7 +35,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: uhidev.c,v 1.72 2017/09/02 04:35:51 ryoon Exp $");
+__KERNEL_RCSID(0, "$NetBSD: uhidev.c,v 1.73 2017/12/10 17:03:07 bouyer Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_usb.h"
@@ -57,10 +57,10 @@ __KERNEL_RCSID(0, "$NetBSD: uhidev.c,v 1
 #include <dev/usb/usbdevs.h>
 #include <dev/usb/usbdi.h>
 #include <dev/usb/usbdi_util.h>
-#include <dev/usb/hid.h>
 #include <dev/usb/usb_quirks.h>
 
 #include <dev/usb/uhidev.h>
+#include <dev/hid/hid.h>
 
 /* Report descriptor for broken Wacom Graphire */
 #include <dev/usb/ugraphire_rdesc.h>

Index: src/sys/dev/usb/ukbd.c
diff -u src/sys/dev/usb/ukbd.c:1.138 src/sys/dev/usb/ukbd.c:1.139
--- src/sys/dev/usb/ukbd.c:1.138	Sun Aug 13 22:19:56 2017
+++ src/sys/dev/usb/ukbd.c	Sun Dec 10 17:03:07 2017
@@ -1,4 +1,4 @@
-/*      $NetBSD: ukbd.c,v 1.138 2017/08/13 22:19:56 jakllsch Exp $        */
+/*      $NetBSD: ukbd.c,v 1.139 2017/12/10 17:03:07 bouyer Exp $        */
 
 /*
  * Copyright (c) 1998 The NetBSD Foundation, Inc.
@@ -35,7 +35,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ukbd.c,v 1.138 2017/08/13 22:19:56 jakllsch Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ukbd.c,v 1.139 2017/12/10 17:03:07 bouyer Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_ddb.h"
@@ -66,8 +66,8 @@ __KERNEL_RCSID(0, "$NetBSD: ukbd.c,v 1.1
 #include <dev/usb/usbdevs.h>
 #include <dev/usb/usb_quirks.h>
 #include <dev/usb/uhidev.h>
-#include <dev/usb/hid.h>
 #include <dev/usb/ukbdvar.h>
+#include <dev/hid/hid.h>
 
 #include <dev/wscons/wsconsio.h>
 #include <dev/wscons/wskbdvar.h>
@@ -352,10 +352,10 @@ const struct wskbd_accessops ukbd_access
 	ukbd_ioctl,
 };
 
-extern const struct wscons_keydesc ukbd_keydesctab[];
+extern const struct wscons_keydesc hidkbd_keydesctab[];
 
 const struct wskbd_mapdata ukbd_keymapdata = {
-	ukbd_keydesctab,
+	hidkbd_keydesctab,
 #if defined(UKBD_LAYOUT)
 	UKBD_LAYOUT,
 #elif defined(PCKBD_LAYOUT)

Index: src/sys/dev/usb/ums.c
diff -u src/sys/dev/usb/ums.c:1.90 src/sys/dev/usb/ums.c:1.91
--- src/sys/dev/usb/ums.c:1.90	Wed Apr 27 19:35:17 2016
+++ src/sys/dev/usb/ums.c	Sun Dec 10 17:03:07 2017
@@ -1,7 +1,7 @@
-/*	$NetBSD: ums.c,v 1.90 2016/04/27 19:35:17 jakllsch Exp $	*/
+/*	$NetBSD: ums.c,v 1.91 2017/12/10 17:03:07 bouyer Exp $	*/
 
 /*
- * Copyright (c) 1998 The NetBSD Foundation, Inc.
+ * Copyright (c) 1998, 2017 The NetBSD Foundation, Inc.
  * All rights reserved.
  *
  * This code is derived from software contributed to The NetBSD Foundation
@@ -35,7 +35,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ums.c,v 1.90 2016/04/27 19:35:17 jakllsch Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ums.c,v 1.91 2017/12/10 17:03:07 bouyer Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_usb.h"
@@ -60,10 +60,8 @@ __KERNEL_RCSID(0, "$NetBSD: ums.c,v 1.90
 #include <dev/usb/usbdevs.h>
 #include <dev/usb/usb_quirks.h>
 #include <dev/usb/uhidev.h>
-#include <dev/usb/hid.h>
-
-#include <dev/wscons/wsconsio.h>
-#include <dev/wscons/wsmousevar.h>
+#include <dev/hid/hid.h>
+#include <dev/hid/hidms.h>
 
 #ifdef UMS_DEBUG
 #define DPRINTF(x)	if (umsdebug) printf x
@@ -74,56 +72,16 @@ int	umsdebug = 0;
 #define DPRINTFN(n,x)
 #endif
 
-#define UMS_BUT(i) ((i) == 1 || (i) == 2 ? 3 - (i) : i)
-
 #define UMSUNIT(s)	(minor(s))
 
-#define PS2LBUTMASK	x01
-#define PS2RBUTMASK	x02
-#define PS2MBUTMASK	x04
-#define PS2BUTMASK 0x0f
-
-#define MAX_BUTTONS	31	/* must not exceed size of sc_buttons */
-
 struct ums_softc {
 	struct uhidev sc_hdev;
+	struct hidms sc_ms;
 
-	struct hid_location sc_loc_x, sc_loc_y, sc_loc_z, sc_loc_w;
-	struct hid_location sc_loc_btn[MAX_BUTTONS];
-
-	int sc_enabled;
-
-	u_int flags;		/* device configuration */
-#define UMS_Z			0x001	/* z direction available */
-#define UMS_SPUR_BUT_UP		0x002	/* spurious button up events */
-#define UMS_REVZ		0x004	/* Z-axis is reversed */
-#define UMS_W			0x008	/* w direction/tilt available */
-#define UMS_ABS			0x010	/* absolute position, touchpanel */
-#define UMS_TIP_SWITCH  	0x020	/* digitizer tip switch */
-#define UMS_SEC_TIP_SWITCH 	0x040	/* digitizer secondary tip switch */
-#define UMS_BARREL_SWITCH 	0x080	/* digitizer barrel switch */
-#define UMS_ERASER 		0x100	/* digitizer eraser */
-
-	int nbuttons;
-
-	uint32_t sc_buttons;	/* mouse button status */
-	device_t sc_wsmousedev;
-
-	char			sc_dying;
-};
-
-static const struct {
-	u_int feature;
-	u_int flag;
-} digbut[] = {
-	{ HUD_TIP_SWITCH, UMS_TIP_SWITCH },
-	{ HUD_SEC_TIP_SWITCH, UMS_SEC_TIP_SWITCH },
-	{ HUD_BARREL_SWITCH, UMS_BARREL_SWITCH },
-	{ HUD_ERASER, UMS_ERASER },
+	int	sc_enabled;
+	char	sc_dying;
 };
 
-#define MOUSE_FLAGS_MASK (HIO_CONST|HIO_RELATIVE)
-
 Static void ums_intr(struct uhidev *, void *, u_int);
 
 Static int	ums_enable(void *);
@@ -177,13 +135,9 @@ ums_attach(device_t parent, device_t sel
 {
 	struct ums_softc *sc = device_private(self);
 	struct uhidev_attach_arg *uha = aux;
-	struct wsmousedev_attach_args a;
 	int size;
 	void *desc;
-	uint32_t flags, quirks;
-	int i, hl;
-	struct hid_location *zloc;
-	bool isdigitizer;
+	uint32_t quirks;
 
 	aprint_naive("\n");
 
@@ -194,114 +148,17 @@ ums_attach(device_t parent, device_t sel
 
 	quirks = usbd_get_quirks(uha->parent->sc_udev)->uq_flags;
 	if (quirks & UQ_MS_REVZ)
-		sc->flags |= UMS_REVZ;
+		sc->sc_ms.flags |= HIDMS_REVZ;
 	if (quirks & UQ_SPUR_BUT_UP)
-		sc->flags |= UMS_SPUR_BUT_UP;
-
-	uhidev_get_report_desc(uha->parent, &desc, &size);
-
-	isdigitizer = hid_is_collection(desc, size, uha->reportid,
-	    HID_USAGE2(HUP_DIGITIZERS, 0x0002));
+		sc->sc_ms.flags |= HIDMS_SPUR_BUT_UP;
 
 	if (!pmf_device_register(self, NULL, NULL))
 		aprint_error_dev(self, "couldn't establish power handler\n");
 
-	if (!hid_locate(desc, size, HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_X),
-	       uha->reportid, hid_input, &sc->sc_loc_x, &flags)) {
-		aprint_error("\n%s: mouse has no X report\n",
-		       device_xname(sc->sc_hdev.sc_dev));
-		return;
-	}
-	switch (flags & MOUSE_FLAGS_MASK) {
-	case 0:
-		sc->flags |= UMS_ABS;
-		break;
-	case HIO_RELATIVE:
-		break;
-	default:
-		aprint_error("\n%s: X report 0x%04x not supported\n",
-		       device_xname(sc->sc_hdev.sc_dev), flags);
-		return;
-	}
+	uhidev_get_report_desc(uha->parent, &desc, &size);
 
-	if (!hid_locate(desc, size, HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_Y),
-	       uha->reportid, hid_input, &sc->sc_loc_y, &flags)) {
-		aprint_error("\n%s: mouse has no Y report\n",
-		       device_xname(sc->sc_hdev.sc_dev));
-		return;
-	}
-	switch (flags & MOUSE_FLAGS_MASK) {
-	case 0:
-		sc->flags |= UMS_ABS;
-		break;
-	case HIO_RELATIVE:
-		break;
-	default:
-		aprint_error("\n%s: Y report 0x%04x not supported\n",
-		       device_xname(sc->sc_hdev.sc_dev), flags);
+	if (!hidms_setup(self, &sc->sc_ms, uha->reportid, desc, size))
 		return;
-	}
-
-	/* Try the wheel first as the Z activator since it's tradition. */
-	hl = hid_locate(desc,
-			size,
-			HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_WHEEL),
-			uha->reportid,
-			hid_input,
-			&sc->sc_loc_z,
-			&flags);
-
-	zloc = &sc->sc_loc_z;
-	if (hl) {
-		if ((flags & MOUSE_FLAGS_MASK) != HIO_RELATIVE) {
-			aprint_verbose("\n%s: Wheel report 0x%04x not "
-			    "supported\n", device_xname(sc->sc_hdev.sc_dev),
-			    flags);
-			sc->sc_loc_z.size = 0;	/* Bad Z coord, ignore it */
-		} else {
-			sc->flags |= UMS_Z;
-			/* Wheels need the Z axis reversed. */
-			sc->flags ^= UMS_REVZ;
-			/* Put Z on the W coordinate */
-			zloc = &sc->sc_loc_w;
-		}
-	}
-
-	hl = hid_locate(desc,
-			size,
-			HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_Z),
-			uha->reportid,
-			hid_input,
-			zloc,
-			&flags);
-
-	/*
-	 * The horizontal component of the scrollball can also be given by
-	 * Application Control Pan in the Consumer page, so if we didnt see
-	 * any Z then check that.
-	 */
-	if (!hl) {
-		hl = hid_locate(desc,
-				size,
-				HID_USAGE2(HUP_CONSUMER, HUC_AC_PAN),
-				uha->reportid,
-				hid_input,
-				zloc,
-				&flags);
-	}
-
-	if (hl) {
-		if ((flags & MOUSE_FLAGS_MASK) != HIO_RELATIVE) {
-			aprint_verbose("\n%s: Z report 0x%04x not supported\n",
-			       device_xname(sc->sc_hdev.sc_dev), flags);
-			zloc->size = 0;	/* Bad Z coord, ignore it */
-		} else {
-			if (sc->flags & UMS_Z)
-				sc->flags |= UMS_W;
-			else
-				sc->flags |= UMS_Z;
-		}
-	}
 
 	if (uha->uiaa->uiaa_vendor == USB_VENDOR_MICROSOFT) {
 		int fixpos;
@@ -324,70 +181,17 @@ ums_attach(device_t parent, device_t sel
 			break;
 		}
 		if (fixpos) {
-			if ((sc->flags & UMS_Z) && sc->sc_loc_z.pos == 0)
-				sc->sc_loc_z.pos = fixpos;
-			if ((sc->flags & UMS_W) && sc->sc_loc_w.pos == 0)
-				sc->sc_loc_w.pos = sc->sc_loc_z.pos + 8;
+			if ((sc->sc_ms.flags & HIDMS_Z) &&
+			    sc->sc_ms.hidms_loc_z.pos == 0)
+				sc->sc_ms.hidms_loc_z.pos = fixpos;
+			if ((sc->sc_ms.flags & HIDMS_W) &&
+			    sc->sc_ms.hidms_loc_w.pos == 0)
+				sc->sc_ms.hidms_loc_w.pos =
+				    sc->sc_ms.hidms_loc_z.pos + 8;
 		}
 	}
 
-	/* figure out the number of buttons */
-	for (i = 1; i <= MAX_BUTTONS; i++)
-		if (!hid_locate(desc, size, HID_USAGE2(HUP_BUTTON, i),
-		    uha->reportid, hid_input, &sc->sc_loc_btn[i - 1], 0))
-			break;
-
-	if (isdigitizer) {
-		for (size_t j = 0; j < __arraycount(digbut); j++) {
-			if (hid_locate(desc, size, HID_USAGE2(HUP_DIGITIZERS,
-			    digbut[j].feature), uha->reportid, hid_input,
-			    &sc->sc_loc_btn[i - 1], 0)) {
-				if (i <= MAX_BUTTONS) {
-					i++;
-					sc->flags |= digbut[j].flag;
-				} else
-					aprint_error_dev(self,
-					    "ran out of buttons\n");
-			}
-		}
-	}
-	sc->nbuttons = i - 1;
-
-	aprint_normal(": %d button%s%s%s%s%s%s%s%s%s\n",
-	    sc->nbuttons, sc->nbuttons == 1 ? "" : "s",
-	    sc->flags & UMS_W ? ", W" : "",
-	    sc->flags & UMS_Z ? " and Z dir" : "",
-	    sc->flags & UMS_W ? "s" : "",
-	    isdigitizer ? " digitizer"  : "",
-	    sc->flags & UMS_TIP_SWITCH ? ", tip" : "",
-	    sc->flags & UMS_SEC_TIP_SWITCH ? ", sec tip" : "",
-	    sc->flags & UMS_BARREL_SWITCH ? ", barrel" : "",
-	    sc->flags & UMS_ERASER ? ", eraser" : "");
-
-#ifdef UMS_DEBUG
-	DPRINTF(("ums_attach: sc=%p\n", sc));
-	DPRINTF(("ums_attach: X\t%d/%d\n",
-		 sc->sc_loc_x.pos, sc->sc_loc_x.size));
-	DPRINTF(("ums_attach: Y\t%d/%d\n",
-		 sc->sc_loc_y.pos, sc->sc_loc_y.size));
-	if (sc->flags & UMS_Z)
-		DPRINTF(("ums_attach: Z\t%d/%d\n",
-			 sc->sc_loc_z.pos, sc->sc_loc_z.size));
-	if (sc->flags & UMS_W)
-		DPRINTF(("ums_attach: W\t%d/%d\n",
-			 sc->sc_loc_w.pos, sc->sc_loc_w.size));
-	for (i = 1; i <= sc->nbuttons; i++) {
-		DPRINTF(("ums_attach: B%d\t%d/%d\n",
-			 i, sc->sc_loc_btn[i-1].pos,sc->sc_loc_btn[i-1].size));
-	}
-#endif
-
-	a.accessops = &ums_accessops;
-	a.accesscookie = sc;
-
-	sc->sc_wsmousedev = config_found(self, &a, wsmousedevprint);
-
-	return;
+	hidms_attach(self, &sc->sc_ms, &ums_accessops);
 }
 
 int
@@ -409,8 +213,8 @@ ums_childdet(device_t self, device_t chi
 {
 	struct ums_softc *sc = device_private(self);
 
-	KASSERT(sc->sc_wsmousedev == child);
-	sc->sc_wsmousedev = NULL;
+	KASSERT(sc->sc_ms.hidms_wsmousedev == child);
+	sc->sc_ms.hidms_wsmousedev = NULL;
 }
 
 int
@@ -422,8 +226,8 @@ ums_detach(device_t self, int flags)
 	DPRINTF(("ums_detach: sc=%p flags=%d\n", sc, flags));
 
 	/* No need to do reference counting of ums, wsmouse has all the goo. */
-	if (sc->sc_wsmousedev != NULL)
-		rv = config_detach(sc->sc_wsmousedev, flags);
+	if (sc->sc_ms.hidms_wsmousedev != NULL)
+		rv = config_detach(sc->sc_ms.hidms_wsmousedev, flags);
 
 	pmf_device_deregister(self);
 
@@ -434,41 +238,7 @@ void
 ums_intr(struct uhidev *addr, void *ibuf, u_int len)
 {
 	struct ums_softc *sc = (struct ums_softc *)addr;
-	int dx, dy, dz, dw;
-	uint32_t buttons = 0;
-	int i, flags, s;
-
-	DPRINTFN(5,("ums_intr: len=%d\n", len));
-
-	flags = WSMOUSE_INPUT_DELTA;	/* equals 0 */
-
-	dx =  hid_get_data(ibuf, &sc->sc_loc_x);
-	if (sc->flags & UMS_ABS) {
-		flags |= (WSMOUSE_INPUT_ABSOLUTE_X | WSMOUSE_INPUT_ABSOLUTE_Y);
-		dy = hid_get_data(ibuf, &sc->sc_loc_y);
-	} else
-		dy = -hid_get_data(ibuf, &sc->sc_loc_y);
-	dz =  hid_get_data(ibuf, &sc->sc_loc_z);
-	dw =  hid_get_data(ibuf, &sc->sc_loc_w);
-
-	if (sc->flags & UMS_REVZ)
-		dz = -dz;
-	for (i = 0; i < sc->nbuttons; i++)
-		if (hid_get_data(ibuf, &sc->sc_loc_btn[i]))
-			buttons |= (1 << UMS_BUT(i));
-
-	if (dx != 0 || dy != 0 || dz != 0 || dw != 0 ||
-	    buttons != sc->sc_buttons) {
-		DPRINTFN(10, ("ums_intr: x:%d y:%d z:%d w:%d buttons:0x%x\n",
-			dx, dy, dz, dw, buttons));
-		sc->sc_buttons = buttons;
-		if (sc->sc_wsmousedev != NULL) {
-			s = spltty();
-			wsmouse_input(sc->sc_wsmousedev, buttons, dx, dy, dz,
-			    dw, flags);
-			splx(s);
-		}
-	}
+	hidms_intr(&sc->sc_ms, ibuf, len);
 }
 
 Static int
@@ -486,7 +256,7 @@ ums_enable(void *v)
 		return EBUSY;
 
 	sc->sc_enabled = 1;
-	sc->sc_buttons = 0;
+	sc->sc_ms.hidms_buttons = 0;
 
 	error = uhidev_open(&sc->sc_hdev);
 	if (error)
@@ -523,7 +293,7 @@ ums_ioctl(void *v, u_long cmd, void *dat
 
 	switch (cmd) {
 	case WSMOUSEIO_GTYPE:
-		if (sc->flags & UMS_ABS)
+		if (sc->sc_ms.flags & HIDMS_ABS)
 			*(u_int *)data = WSMOUSE_TYPE_TPANEL;
 		else
 			*(u_int *)data = WSMOUSE_TYPE_USB;

Index: src/sys/dev/usb/usbhid.h
diff -u src/sys/dev/usb/usbhid.h:1.16 src/sys/dev/usb/usbhid.h:1.17
--- src/sys/dev/usb/usbhid.h:1.16	Sat Apr 23 10:15:32 2016
+++ src/sys/dev/usb/usbhid.h	Sun Dec 10 17:03:07 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: usbhid.h,v 1.16 2016/04/23 10:15:32 skrll Exp $	*/
+/*	$NetBSD: usbhid.h,v 1.17 2017/12/10 17:03:07 bouyer Exp $	*/
 /*	$FreeBSD: src/sys/dev/usb/usbhid.h,v 1.7 1999/11/17 22:33:51 n_hibma Exp $ */
 
 /*
@@ -60,136 +60,8 @@ typedef struct usb_hid_descriptor {
 } UPACKED usb_hid_descriptor_t;
 #define USB_HID_DESCRIPTOR_SIZE(n) (9+(n)*3)
 
-/* Usage pages */
-#define HUP_UNDEFINED		0x0000
-#define HUP_GENERIC_DESKTOP	0x0001
-#define HUP_SIMULATION		0x0002
-#define HUP_VR_CONTROLS		0x0003
-#define HUP_SPORTS_CONTROLS	0x0004
-#define HUP_GAMING_CONTROLS	0x0005
-#define HUP_KEYBOARD		0x0007
-#define HUP_LEDS		0x0008
-#define HUP_BUTTON		0x0009
-#define HUP_ORDINALS		0x000a
-#define HUP_TELEPHONY		0x000b
-#define HUP_CONSUMER		0x000c
-#define HUP_DIGITIZERS		0x000d
-#define HUP_PHYSICAL_IFACE	0x000e
-#define HUP_UNICODE		0x0010
-#define HUP_ALPHANUM_DISPLAY	0x0014
-#define HUP_MONITOR		0x0080
-#define HUP_MONITOR_ENUM_VAL	0x0081
-#define HUP_VESA_VC		0x0082
-#define HUP_VESA_CMD		0x0083
-#define HUP_POWER		0x0084
-#define HUP_BATTERY_SYSTEM	0x0085
-#define HUP_BARCODE_SCANNER	0x008b
-#define HUP_SCALE		0x008c
-#define HUP_CAMERA_CONTROL	0x0090
-#define HUP_ARCADE		0x0091
-#define HUP_MICROSOFT		0xff00
-
-/* Usages, generic desktop */
-#define HUG_POINTER		0x0001
-#define HUG_MOUSE		0x0002
-#define HUG_JOYSTICK		0x0004
-#define HUG_GAME_PAD		0x0005
-#define HUG_KEYBOARD		0x0006
-#define HUG_KEYPAD		0x0007
-#define HUG_X			0x0030
-#define HUG_Y			0x0031
-#define HUG_Z			0x0032
-#define HUG_RX			0x0033
-#define HUG_RY			0x0034
-#define HUG_RZ			0x0035
-#define HUG_SLIDER		0x0036
-#define HUG_DIAL		0x0037
-#define HUG_WHEEL		0x0038
-#define HUG_HAT_SWITCH		0x0039
-#define HUG_COUNTED_BUFFER	0x003a
-#define HUG_BYTE_COUNT		0x003b
-#define HUG_MOTION_WAKEUP	0x003c
-#define HUG_VX			0x0040
-#define HUG_VY			0x0041
-#define HUG_VZ			0x0042
-#define HUG_VBRX		0x0043
-#define HUG_VBRY		0x0044
-#define HUG_VBRZ		0x0045
-#define HUG_VNO			0x0046
-#define HUG_SYSTEM_CONTROL	0x0080
-#define HUG_SYSTEM_POWER_DOWN	0x0081
-#define HUG_SYSTEM_SLEEP	0x0082
-#define HUG_SYSTEM_WAKEUP	0x0083
-#define HUG_SYSTEM_CONTEXT_MENU	0x0084
-#define HUG_SYSTEM_MAIN_MENU	0x0085
-#define HUG_SYSTEM_APP_MENU	0x0086
-#define HUG_SYSTEM_MENU_HELP	0x0087
-#define HUG_SYSTEM_MENU_EXIT	0x0088
-#define HUG_SYSTEM_MENU_SELECT	0x0089
-#define HUG_SYSTEM_MENU_RIGHT	0x008a
-#define HUG_SYSTEM_MENU_LEFT	0x008b
-#define HUG_SYSTEM_MENU_UP	0x008c
-#define HUG_SYSTEM_MENU_DOWN	0x008d
-
-/* Usages Digitizers */
-#define HUD_UNDEFINED		0x0000
-#define HUD_TOUCH_SCREEN	0x0004
-#define HUD_FINGER		0x0022
-#define HUD_TIP_PRESSURE	0x0030
-#define HUD_BARREL_PRESSURE	0x0031
-#define HUD_IN_RANGE		0x0032
-#define HUD_TOUCH		0x0033
-#define HUD_UNTOUCH		0x0034
-#define HUD_TAP			0x0035
-#define HUD_QUALITY		0x0036
-#define HUD_DATA_VALID		0x0037
-#define HUD_TRANSDUCER_INDEX	0x0038
-#define HUD_TABLET_FKEYS	0x0039
-#define HUD_PROGRAM_CHANGE_KEYS	0x003a
-#define HUD_BATTERY_STRENGTH	0x003b
-#define HUD_INVERT		0x003c
-#define HUD_X_TILT		0x003d
-#define HUD_Y_TILT		0x003e
-#define HUD_AZIMUTH		0x003f
-#define HUD_ALTITUDE		0x0040
-#define HUD_TWIST		0x0041
-#define HUD_TIP_SWITCH		0x0042
-#define HUD_SEC_TIP_SWITCH	0x0043
-#define HUD_BARREL_SWITCH	0x0044
-#define HUD_ERASER		0x0045
-#define HUD_TABLET_PICK		0x0046
-
-/* Usages LEDs */
-#define HUD_LED_NUM_LOCK	0x0001
-#define HUD_LED_CAPS_LOCK	0x0002
-#define HUD_LED_SCROLL_LOCK	0x0003
-#define HUD_LED_COMPOSE		0x0004
-#define HUD_LED_KANA		0x0005
-
-/* Usages, Consumer */
-#define HUC_AC_PAN		0x0238
-
-#define HID_USAGE2(p, u) (((p) << 16) | u)
-#define HID_GET_USAGE(u) ((u) & 0xffff)
-#define HID_GET_USAGE_PAGE(u) (((u) >> 16) & 0xffff)
-
 #define UHID_INPUT_REPORT 0x01
 #define UHID_OUTPUT_REPORT 0x02
 #define UHID_FEATURE_REPORT 0x03
 
-#define HCOLL_PHYSICAL		0
-#define HCOLL_APPLICATION	1
-#define HCOLL_LOGICAL		2
-
-/* Bits in the input/output/feature items */
-#define HIO_CONST	0x001
-#define HIO_VARIABLE	0x002
-#define HIO_RELATIVE	0x004
-#define HIO_WRAP	0x008
-#define HIO_NONLINEAR	0x010
-#define HIO_NOPREF	0x020
-#define HIO_NULLSTATE	0x040
-#define HIO_VOLATILE	0x080
-#define HIO_BUFBYTES	0x100
-
 #endif /* _DEV_USB_USBHID_H_ */

Index: src/sys/dev/usb/uthum.c
diff -u src/sys/dev/usb/uthum.c:1.13 src/sys/dev/usb/uthum.c:1.14
--- src/sys/dev/usb/uthum.c:1.13	Fri Nov 25 12:56:29 2016
+++ src/sys/dev/usb/uthum.c	Sun Dec 10 17:03:07 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: uthum.c,v 1.13 2016/11/25 12:56:29 skrll Exp $   */
+/*	$NetBSD: uthum.c,v 1.14 2017/12/10 17:03:07 bouyer Exp $   */
 /*	$OpenBSD: uthum.c,v 1.6 2010/01/03 18:43:02 deraadt Exp $   */
 
 /*
@@ -22,7 +22,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: uthum.c,v 1.13 2016/11/25 12:56:29 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: uthum.c,v 1.14 2017/12/10 17:03:07 bouyer Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_usb.h"
@@ -43,7 +43,7 @@ __KERNEL_RCSID(0, "$NetBSD: uthum.c,v 1.
 #include <dev/usb/usbdi_util.h>
 #include <dev/usb/usbdevs.h>
 #include <dev/usb/uhidev.h>
-#include <dev/usb/hid.h>
+#include <dev/hid/hid.h>
 
 #ifdef UTHUM_DEBUG
 int	uthumdebug = 0;

Index: src/sys/dev/usb/uts.c
diff -u src/sys/dev/usb/uts.c:1.7 src/sys/dev/usb/uts.c:1.8
--- src/sys/dev/usb/uts.c:1.7	Wed May 17 14:15:29 2017
+++ src/sys/dev/usb/uts.c	Sun Dec 10 17:03:07 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: uts.c,v 1.7 2017/05/17 14:15:29 macallan Exp $	*/
+/*	$NetBSD: uts.c,v 1.8 2017/12/10 17:03:07 bouyer Exp $	*/
 
 /*
  * Copyright (c) 2012 The NetBSD Foundation, Inc.
@@ -34,7 +34,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: uts.c,v 1.7 2017/05/17 14:15:29 macallan Exp $");
+__KERNEL_RCSID(0, "$NetBSD: uts.c,v 1.8 2017/12/10 17:03:07 bouyer Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_usb.h"
@@ -55,7 +55,7 @@ __KERNEL_RCSID(0, "$NetBSD: uts.c,v 1.7 
 #include <dev/usb/usbdevs.h>
 #include <dev/usb/usb_quirks.h>
 #include <dev/usb/uhidev.h>
-#include <dev/usb/hid.h>
+#include <dev/hid/hid.h>
 
 #include <dev/wscons/wsconsio.h>
 #include <dev/wscons/wsmousevar.h>

Index: src/sys/dev/usb/uyurex.c
diff -u src/sys/dev/usb/uyurex.c:1.12 src/sys/dev/usb/uyurex.c:1.13
--- src/sys/dev/usb/uyurex.c:1.12	Fri Nov 25 12:56:29 2016
+++ src/sys/dev/usb/uyurex.c	Sun Dec 10 17:03:07 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: uyurex.c,v 1.12 2016/11/25 12:56:29 skrll Exp $ */
+/*	$NetBSD: uyurex.c,v 1.13 2017/12/10 17:03:07 bouyer Exp $ */
 /*	$OpenBSD: uyurex.c,v 1.3 2010/03/04 03:47:22 deraadt Exp $ */
 
 /*
@@ -22,7 +22,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: uyurex.c,v 1.12 2016/11/25 12:56:29 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: uyurex.c,v 1.13 2017/12/10 17:03:07 bouyer Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_usb.h"
@@ -45,7 +45,7 @@ __KERNEL_RCSID(0, "$NetBSD: uyurex.c,v 1
 #include <dev/usb/usbdi_util.h>
 #include <dev/usb/usbdevs.h>
 #include <dev/usb/uhidev.h>
-#include <dev/usb/hid.h>
+#include <dev/hid/hid.h>
 
 #define	CMD_NONE	0xf0
 #define CMD_EOF		0x0d

Added files:

Index: src/sys/dev/hid/files.hid
diff -u /dev/null src/sys/dev/hid/files.hid:1.1
--- /dev/null	Sun Dec 10 17:03:08 2017
+++ src/sys/dev/hid/files.hid	Sun Dec 10 17:03:07 2017
@@ -0,0 +1,13 @@
+#       $NetBSD: files.hid,v 1.1 2017/12/10 17:03:07 bouyer Exp $
+
+# Human Interface Devices
+# Used by USB, bluetooth and i2c
+
+# HID processing
+define  hid
+file    dev/hid/hid.c			hid
+
+define	hidms
+file    dev/hid/hidms.c			hidms
+
+file	dev/hid/hidkbdmap.c		ukbd | btkbd | linux_keymap
Index: src/sys/dev/hid/hid.c
diff -u /dev/null src/sys/dev/hid/hid.c:1.1
--- /dev/null	Sun Dec 10 17:03:08 2017
+++ src/sys/dev/hid/hid.c	Sun Dec 10 17:03:07 2017
@@ -0,0 +1,533 @@
+/*	$NetBSD: hid.c,v 1.1 2017/12/10 17:03:07 bouyer Exp $	*/
+/*	$FreeBSD: src/sys/dev/usb/hid.c,v 1.11 1999/11/17 22:33:39 n_hibma Exp $ */
+
+/*
+ * Copyright (c) 1998 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Lennart Augustsson (lenn...@augustsson.net) at
+ * Carlstedt Research & Technology.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__KERNEL_RCSID(0, "$NetBSD: hid.c,v 1.1 2017/12/10 17:03:07 bouyer Exp $");
+
+#ifdef _KERNEL_OPT
+#include "opt_usb.h"
+#endif
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/kmem.h>
+
+#include <dev/usb/usb.h>
+#include <dev/usb/usbhid.h>
+
+#include <dev/hid/hid.h>
+
+#ifdef UHIDEV_DEBUG
+#define DPRINTF(x)	if (uhidevdebug) printf x
+#define DPRINTFN(n,x)	if (uhidevdebug>(n)) printf x
+extern int uhidevdebug;
+#else
+#define DPRINTF(x)
+#define DPRINTFN(n,x)
+#endif
+
+Static void hid_clear_local(struct hid_item *);
+
+#define MAXUSAGE 256
+struct hid_data {
+	const u_char *start;
+	const u_char *end;
+	const u_char *p;
+	struct hid_item cur;
+	int32_t usages[MAXUSAGE];
+	int nu;
+	int minset;
+	int multi;
+	int multimax;
+	enum hid_kind kind;
+};
+
+Static void
+hid_clear_local(struct hid_item *c)
+{
+
+	DPRINTFN(5,("hid_clear_local\n"));
+	c->usage = 0;
+	c->usage_minimum = 0;
+	c->usage_maximum = 0;
+	c->designator_index = 0;
+	c->designator_minimum = 0;
+	c->designator_maximum = 0;
+	c->string_index = 0;
+	c->string_minimum = 0;
+	c->string_maximum = 0;
+	c->set_delimiter = 0;
+}
+
+struct hid_data *
+hid_start_parse(const void *d, int len, enum hid_kind kind)
+{
+	struct hid_data *s;
+
+	s = kmem_zalloc(sizeof(*s), KM_SLEEP);
+	s->start = s->p = d;
+	s->end = (const char *)d + len;
+	s->kind = kind;
+	return s;
+}
+
+void
+hid_end_parse(struct hid_data *s)
+{
+
+	while (s->cur.next != NULL) {
+		struct hid_item *hi = s->cur.next->next;
+		kmem_free(s->cur.next, sizeof(*s->cur.next));
+		s->cur.next = hi;
+	}
+	kmem_free(s, sizeof(*s));
+}
+
+int
+hid_get_item(struct hid_data *s, struct hid_item *h)
+{
+	struct hid_item *c = &s->cur;
+	unsigned int bTag, bType, bSize;
+	uint32_t oldpos;
+	const u_char *data;
+	int32_t dval;
+	const u_char *p;
+	struct hid_item *hi;
+	int i;
+	enum hid_kind retkind;
+
+ top:
+	DPRINTFN(5,("hid_get_item: multi=%d multimax=%d\n",
+		    s->multi, s->multimax));
+	if (s->multimax != 0) {
+		if (s->multi < s->multimax) {
+			c->usage = s->usages[min(s->multi, s->nu-1)];
+			s->multi++;
+			*h = *c;
+			c->loc.pos += c->loc.size;
+			h->next = NULL;
+			DPRINTFN(5,("return multi\n"));
+			return 1;
+		} else {
+			c->loc.count = s->multimax;
+			s->multimax = 0;
+			s->nu = 0;
+			hid_clear_local(c);
+		}
+	}
+	for (;;) {
+		p = s->p;
+		if (p >= s->end)
+			return 0;
+
+		bSize = *p++;
+		if (bSize == 0xfe) {
+			/* long item */
+			bSize = *p++;
+			bSize |= *p++ << 8;
+			bTag = *p++;
+			data = p;
+			p += bSize;
+			bType = 0xff; /* XXX what should it be */
+		} else {
+			/* short item */
+			bTag = bSize >> 4;
+			bType = (bSize >> 2) & 3;
+			bSize &= 3;
+			if (bSize == 3) bSize = 4;
+			data = p;
+			p += bSize;
+		}
+		s->p = p;
+		switch(bSize) {
+		case 0:
+			dval = 0;
+			break;
+		case 1:
+			dval = (int8_t)*data++;
+			break;
+		case 2:
+			dval = *data++;
+			dval |= *data++ << 8;
+			dval = (int16_t)dval;
+			break;
+		case 4:
+			dval = *data++;
+			dval |= *data++ << 8;
+			dval |= *data++ << 16;
+			dval |= *data++ << 24;
+			dval = (int32_t)dval;
+			break;
+		default:
+			aprint_normal("BAD LENGTH %d\n", bSize);
+			continue;
+		}
+
+		DPRINTFN(5,("hid_get_item: bType=%d bTag=%d dval=%d\n",
+			 bType, bTag, dval));
+		switch (bType) {
+		case 0:			/* Main */
+			switch (bTag) {
+			case 8:		/* Input */
+				retkind = hid_input;
+			ret:
+				if (s->kind != retkind) {
+					s->minset = 0;
+					s->nu = 0;
+					hid_clear_local(c);
+					continue;
+				}
+				c->kind = retkind;
+				c->flags = dval;
+				if (c->flags & HIO_VARIABLE) {
+					s->multimax = c->loc.count;
+					s->multi = 0;
+					c->loc.count = 1;
+					if (s->minset) {
+						for (i = c->usage_minimum;
+						     i <= c->usage_maximum;
+						     i++) {
+							s->usages[s->nu] = i;
+							if (s->nu < MAXUSAGE-1)
+								s->nu++;
+						}
+						s->minset = 0;
+					}
+					goto top;
+				} else {
+					if (s->minset)
+						c->usage = c->usage_minimum;
+					*h = *c;
+					h->next = NULL;
+					c->loc.pos +=
+					    c->loc.size * c->loc.count;
+					s->minset = 0;
+					s->nu = 0;
+					hid_clear_local(c);
+					return 1;
+				}
+			case 9:		/* Output */
+				retkind = hid_output;
+				goto ret;
+			case 10:	/* Collection */
+				c->kind = hid_collection;
+				c->collection = dval;
+				c->collevel++;
+				*h = *c;
+				hid_clear_local(c);
+				s->nu = 0;
+				return 1;
+			case 11:	/* Feature */
+				retkind = hid_feature;
+				goto ret;
+			case 12:	/* End collection */
+				c->kind = hid_endcollection;
+				c->collevel--;
+				*h = *c;
+				s->nu = 0;
+				return 1;
+			default:
+				aprint_normal("Main bTag=%d\n", bTag);
+				break;
+			}
+			break;
+		case 1:		/* Global */
+			switch (bTag) {
+			case 0:
+				c->_usage_page = dval << 16;
+				break;
+			case 1:
+				c->logical_minimum = dval;
+				break;
+			case 2:
+				c->logical_maximum = dval;
+				break;
+			case 3:
+				c->physical_minimum = dval;
+				break;
+			case 4:
+				c->physical_maximum = dval;
+				break;
+			case 5:
+				c->unit_exponent = dval;
+				break;
+			case 6:
+				c->unit = dval;
+				break;
+			case 7:
+				c->loc.size = dval;
+				break;
+			case 8:
+				c->report_ID = dval;
+				c->loc.pos = 0;
+				break;
+			case 9:
+				c->loc.count = dval;
+				break;
+			case 10: /* Push */
+				hi = kmem_alloc(sizeof(*hi), KM_SLEEP);
+				*hi = *c;
+				c->next = hi;
+				break;
+			case 11: /* Pop */
+				hi = c->next;
+				if (hi == NULL)
+					break;
+				oldpos = c->loc.pos;
+				*c = *hi;
+				c->loc.pos = oldpos;
+				kmem_free(hi, sizeof(*hi));
+				break;
+			default:
+				aprint_normal("Global bTag=%d\n", bTag);
+				break;
+			}
+			break;
+		case 2:		/* Local */
+			switch (bTag) {
+			case 0:
+				if (bSize == 1)
+					dval = c->_usage_page | (dval&0xff);
+				else if (bSize == 2)
+					dval = c->_usage_page | (dval&0xffff);
+				c->usage = dval;
+				if (s->nu < MAXUSAGE)
+					s->usages[s->nu++] = dval;
+				/* else XXX */
+				break;
+			case 1:
+				s->minset = 1;
+				if (bSize == 1)
+					dval = c->_usage_page | (dval&0xff);
+				else if (bSize == 2)
+					dval = c->_usage_page | (dval&0xffff);
+				c->usage_minimum = dval;
+				break;
+			case 2:
+				if (bSize == 1)
+					dval = c->_usage_page | (dval&0xff);
+				else if (bSize == 2)
+					dval = c->_usage_page | (dval&0xffff);
+				c->usage_maximum = dval;
+				break;
+			case 3:
+				c->designator_index = dval;
+				break;
+			case 4:
+				c->designator_minimum = dval;
+				break;
+			case 5:
+				c->designator_maximum = dval;
+				break;
+			case 7:
+				c->string_index = dval;
+				break;
+			case 8:
+				c->string_minimum = dval;
+				break;
+			case 9:
+				c->string_maximum = dval;
+				break;
+			case 10:
+				c->set_delimiter = dval;
+				break;
+			default:
+				aprint_normal("Local bTag=%d\n", bTag);
+				break;
+			}
+			break;
+		default:
+			aprint_normal("default bType=%d\n", bType);
+			break;
+		}
+	}
+}
+
+int
+hid_report_size(const void *buf, int len, enum hid_kind k, uint8_t id)
+{
+	struct hid_data *d;
+	struct hid_item h;
+	int lo, hi;
+
+	h.report_ID = 0;
+	lo = hi = -1;
+	DPRINTFN(2,("hid_report_size: kind=%d id=%d\n", k, id));
+	for (d = hid_start_parse(buf, len, k); hid_get_item(d, &h); ) {
+		DPRINTFN(2,("hid_report_size: item kind=%d id=%d pos=%d "
+			    "size=%d count=%d\n",
+			    h.kind, h.report_ID, h.loc.pos, h.loc.size,
+			    h.loc.count));
+		if (h.report_ID == id && h.kind == k) {
+			if (lo < 0) {
+				lo = h.loc.pos;
+#ifdef DIAGNOSTIC
+				if (lo != 0) {
+					aprint_normal("hid_report_size:"
+					   " lo != 0\n");
+				}
+#endif
+			}
+			hi = h.loc.pos + h.loc.size * h.loc.count;
+			DPRINTFN(2,("hid_report_size: lo=%d hi=%d\n", lo, hi));
+		}
+	}
+	hid_end_parse(d);
+	return (hi - lo + 7) / 8;
+}
+
+int
+hid_locate(const void *desc, int size, uint32_t u, uint8_t id, enum hid_kind k,
+	   struct hid_location *loc, uint32_t *flags)
+{
+	struct hid_data *d;
+	struct hid_item h;
+
+	h.report_ID = 0;
+	DPRINTFN(5,("hid_locate: enter usage=0x%x kind=%d id=%d\n", u, k, id));
+	for (d = hid_start_parse(desc, size, k); hid_get_item(d, &h); ) {
+		DPRINTFN(5,("hid_locate: usage=0x%x kind=%d id=%d flags=0x%x\n",
+			    h.usage, h.kind, h.report_ID, h.flags));
+		if (h.kind == k && !(h.flags & HIO_CONST) &&
+		    h.usage == u && h.report_ID == id) {
+			if (loc != NULL)
+				*loc = h.loc;
+			if (flags != NULL)
+				*flags = h.flags;
+			hid_end_parse(d);
+			return 1;
+		}
+	}
+	hid_end_parse(d);
+	if (loc != NULL)
+		loc->size = 0;
+	return 0;
+}
+
+long
+hid_get_data(const u_char *buf, const struct hid_location *loc)
+{
+	u_int hsize = loc->size;
+	u_long data;
+
+	if (hsize == 0)
+		return 0;
+
+	data = hid_get_udata(buf, loc);
+	if (data < (1UL << (hsize - 1)) || hsize == sizeof(data) * NBBY)
+		return data;
+	return data - (1UL << hsize);
+}
+
+u_long
+hid_get_udata(const u_char *buf, const struct hid_location *loc)
+{
+	u_int hpos = loc->pos;
+	u_int hsize = loc->size;
+	u_int i, num, off;
+	u_long data;
+
+	if (hsize == 0)
+		return 0;
+
+	data = 0;
+	off = hpos / 8;
+	num = (hpos + hsize + 7) / 8 - off;
+
+	for (i = 0; i < num; i++)
+		data |= (unsigned long)buf[off + i] << (i * 8);
+
+	data >>= hpos % 8;
+	if (hsize < sizeof(data) * NBBY)
+		data &= (1UL << hsize) - 1;
+
+	DPRINTFN(10,("hid_get_udata: loc %d/%d = %lu\n", hpos, hsize, data));
+	return data;
+}
+
+/*
+ * hid_is_collection(desc, size, id, usage)
+ *
+ * This function is broken in the following way.
+ *
+ * It is used to discover if the given 'id' is part of 'usage' collection
+ * in the descriptor in order to match report id against device type.
+ *
+ * The semantics of hid_start_parse() means though, that only a single
+ * kind of report is considered. The current HID code that uses this for
+ * matching is actually only looking for input reports, so this works
+ * for now.
+ *
+ * This function could try all report kinds (input, output and feature)
+ * consecutively if necessary, but it may be better to integrate the
+ * libusbhid code which can consider multiple report kinds simultaneously
+ *
+ * Needs some thought.
+ */
+int
+hid_is_collection(const void *desc, int size, uint8_t id, uint32_t usage)
+{
+	struct hid_data *hd;
+	struct hid_item hi;
+	uint32_t coll_usage = ~0;
+
+	hd = hid_start_parse(desc, size, hid_input);
+	if (hd == NULL)
+		return 0;
+
+	DPRINTFN(2,("hid_is_collection: id=%d usage=0x%x\n", id, usage));
+	while (hid_get_item(hd, &hi)) {
+		DPRINTFN(2,("hid_is_collection: kind=%d id=%d usage=0x%x"
+			    "(0x%x)\n",
+			    hi.kind, hi.report_ID, hi.usage, coll_usage));
+
+		if (hi.kind == hid_collection &&
+		    hi.collection == HCOLL_APPLICATION)
+			coll_usage = hi.usage;
+
+		if (hi.kind == hid_endcollection)
+			coll_usage = ~0;
+
+		if (hi.kind == hid_input &&
+		    coll_usage == usage &&
+		    hi.report_ID == id) {
+			DPRINTFN(2,("hid_is_collection: found\n"));
+			hid_end_parse(hd);
+			return 1;
+		}
+	}
+	DPRINTFN(2,("hid_is_collection: not found\n"));
+	hid_end_parse(hd);
+	return 0;
+}
Index: src/sys/dev/hid/hid.h
diff -u /dev/null src/sys/dev/hid/hid.h:1.1
--- /dev/null	Sun Dec 10 17:03:08 2017
+++ src/sys/dev/hid/hid.h	Sun Dec 10 17:03:07 2017
@@ -0,0 +1,422 @@
+/*	$NetBSD: hid.h,v 1.1 2017/12/10 17:03:07 bouyer Exp $	*/
+/*	$FreeBSD: src/sys/dev/usb/hid.h,v 1.7 1999/11/17 22:33:40 n_hibma Exp $ */
+
+/*
+ * Copyright (c) 1998 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Lennart Augustsson (lenn...@augustsson.net) at
+ * Carlstedt Research & Technology.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _HIDHID_H_
+#define _HIDHID_H_
+
+#ifdef _KERNEL
+
+enum hid_kind {
+	hid_input,
+	hid_output,
+	hid_feature,
+	hid_collection,
+	hid_endcollection,
+	hid_none
+};
+
+struct hid_location {
+	uint32_t size;
+	uint32_t count;
+	uint32_t pos;
+};
+
+struct hid_item {
+	/* Global */
+	int32_t _usage_page;
+	int32_t logical_minimum;
+	int32_t logical_maximum;
+	int32_t physical_minimum;
+	int32_t physical_maximum;
+	int32_t unit_exponent;
+	int32_t unit;
+	int32_t report_ID;
+	/* Local */
+	int32_t usage;
+	int32_t usage_minimum;
+	int32_t usage_maximum;
+	int32_t designator_index;
+	int32_t designator_minimum;
+	int32_t designator_maximum;
+	int32_t string_index;
+	int32_t string_minimum;
+	int32_t string_maximum;
+	int32_t set_delimiter;
+	/* Misc */
+	int32_t collection;
+	int collevel;
+	enum hid_kind kind;
+	uint32_t flags;
+	/* Location */
+	struct hid_location loc;
+	/* */
+	struct hid_item *next;
+};
+
+struct hid_data *hid_start_parse(const void *, int, enum hid_kind);
+void hid_end_parse(struct hid_data *);
+int hid_get_item(struct hid_data *, struct hid_item *);
+int hid_report_size(const void *, int, enum hid_kind, uint8_t);
+int hid_locate(const void *, int, uint32_t, uint8_t, enum hid_kind,
+    struct hid_location *, uint32_t *);
+long hid_get_data(const u_char *, const struct hid_location *);
+u_long hid_get_udata(const u_char *, const struct hid_location *);
+int hid_is_collection(const void *, int, uint8_t, uint32_t);
+
+#endif /*  _KERNEL */
+
+/* Usage pages */
+#define HUP_UNDEFINED		0x0000
+#define HUP_GENERIC_DESKTOP	0x0001
+#define HUP_SIMULATION		0x0002
+#define HUP_VR_CONTROLS		0x0003
+#define HUP_SPORTS_CONTROLS	0x0004
+#define HUP_GAMING_CONTROLS	0x0005
+#define HUP_KEYBOARD		0x0007
+#define HUP_LEDS		0x0008
+#define HUP_BUTTON		0x0009
+#define HUP_ORDINALS		0x000a
+#define HUP_TELEPHONY		0x000b
+#define HUP_CONSUMER		0x000c
+#define HUP_DIGITIZERS		0x000d
+#define HUP_PHYSICAL_IFACE	0x000e
+#define HUP_UNICODE		0x0010
+#define HUP_ALPHANUM_DISPLAY	0x0014
+#define HUP_MONITOR		0x0080
+#define HUP_MONITOR_ENUM_VAL	0x0081
+#define HUP_VESA_VC		0x0082
+#define HUP_VESA_CMD		0x0083
+#define HUP_POWER		0x0084
+#define HUP_BATTERY		0x0085
+#define HUP_BARCODE_SCANNER	0x008b
+#define HUP_SCALE		0x008c
+#define HUP_CAMERA_CONTROL	0x0090
+#define HUP_ARCADE		0x0091
+#define HUP_VENDOR		0x00ff
+#define HUP_MICROSOFT		0xff00
+/* XXX compat */
+#define HUP_APPLE		0x00ff
+#define HUP_WACOM		0xff00
+
+/* Usages, Power Device */
+#define HUP_INAME		0x0001
+#define HUP_PRESENT_STATUS	0x0002
+#define HUP_CHANGED_STATUS	0x0003
+#define HUP_UPS			0x0004
+#define HUP_POWER_SUPPLY	0x0005
+#define HUP_BATTERY_SYSTEM	0x0010
+#define HUP_BATTERY_SYSTEM_ID	0x0011
+#define HUP_PD_BATTERY		0x0012
+#define HUP_BATTERY_ID		0x0013
+#define HUP_CHARGER		0x0014
+#define HUP_CHARGER_ID		0x0015
+#define HUP_POWER_CONVERTER	0x0016
+#define HUP_POWER_CONVERTER_ID	0x0017
+#define HUP_OUTLET_SYSTEM	0x0018
+#define HUP_OUTLET_SYSTEM_ID	0x0019
+#define HUP_INPUT		0x001a
+#define HUP_INPUT_ID		0x001b
+#define HUP_OUTPUT		0x001c
+#define HUP_OUTPUT_ID		0x001d
+#define HUP_FLOW		0x001e
+#define HUP_FLOW_ID		0x001f
+#define HUP_OUTLET		0x0020
+#define HUP_OUTLET_ID		0x0021
+#define HUP_GANG		0x0022
+#define HUP_GANG_ID		0x0023
+#define HUP_POWER_SUMMARY	0x0024
+#define HUP_POWER_SUMMARY_ID	0x0025
+#define HUP_VOLTAGE		0x0030
+#define HUP_CURRENT		0x0031
+#define HUP_FREQUENCY		0x0032
+#define HUP_APPARENT_POWER	0x0033
+#define HUP_ACTIVE_POWER	0x0034
+#define HUP_PERCENT_LOAD	0x0035
+#define HUP_TEMPERATURE		0x0036
+#define HUP_HUMIDITY		0x0037
+#define HUP_BADCOUNT		0x0038
+#define HUP_CONFIG_VOLTAGE	0x0040
+#define HUP_CONFIG_CURRENT	0x0041
+#define HUP_CONFIG_FREQUENCY	0x0042
+#define HUP_CONFIG_APP_POWER	0x0043
+#define HUP_CONFIG_ACT_POWER	0x0044
+#define HUP_CONFIG_PERCENT_LOAD	0x0045
+#define HUP_CONFIG_TEMPERATURE	0x0046
+#define HUP_CONFIG_HUMIDITY	0x0047
+#define HUP_SWITCHON_CONTROL	0x0050
+#define HUP_SWITCHOFF_CONTROL	0x0051
+#define HUP_TOGGLE_CONTROL	0x0052
+#define HUP_LOW_VOLT_TRANSF	0x0053
+#define HUP_HIGH_VOLT_TRANSF	0x0054
+#define HUP_DELAYBEFORE_REBOOT	0x0055
+#define HUP_DELAYBEFORE_STARTUP	0x0056
+#define HUP_DELAYBEFORE_SHUTDWN	0x0057
+#define HUP_TEST		0x0058
+#define HUP_MODULE_RESET	0x0059
+#define HUP_AUDIBLE_ALRM_CTL	0x005a
+#define HUP_PRESENT		0x0060
+#define HUP_GOOD		0x0061
+#define HUP_INTERNAL_FAILURE	0x0062
+#define HUP_PD_VOLT_OUTOF_RANGE	0x0063
+#define HUP_FREQ_OUTOFRANGE	0x0064
+#define HUP_OVERLOAD		0x0065
+#define HUP_OVERCHARGED		0x0066
+#define HUP_OVERTEMPERATURE	0x0067
+#define HUP_SHUTDOWN_REQUESTED	0x0068
+#define HUP_SHUTDOWN_IMMINENT	0x0069
+#define HUP_SWITCH_ON_OFF	0x006b
+#define HUP_SWITCHABLE		0x006c
+#define HUP_USED		0x006d
+#define HUP_BOOST		0x006e
+#define HUP_BUCK		0x006f
+#define HUP_INITIALIZED		0x0070
+#define HUP_TESTED		0x0071
+#define HUP_AWAITING_POWER	0x0072
+#define HUP_COMMUNICATION_LOST	0x0073
+#define HUP_IMANUFACTURER	0x00fd
+#define HUP_IPRODUCT		0x00fe
+#define HUP_ISERIALNUMBER	0x00ff
+
+/* Usages, Battery */
+#define HUB_SMB_BATTERY_MODE	0x0001
+#define HUB_SMB_BATTERY_STATUS	0x0002
+#define HUB_SMB_ALARM_WARNING	0x0003
+#define HUB_SMB_CHARGER_MODE	0x0004
+#define HUB_SMB_CHARGER_STATUS	0x0005
+#define HUB_SMB_CHARGER_SPECINF	0x0006
+#define HUB_SMB_SELECTR_STATE	0x0007
+#define HUB_SMB_SELECTR_PRESETS	0x0008
+#define HUB_SMB_SELECTR_INFO	0x0009
+#define HUB_SMB_OPT_MFGFUNC1	0x0010
+#define HUB_SMB_OPT_MFGFUNC2	0x0011
+#define HUB_SMB_OPT_MFGFUNC3	0x0012
+#define HUB_SMB_OPT_MFGFUNC4	0x0013
+#define HUB_SMB_OPT_MFGFUNC5	0x0014
+#define HUB_CONNECTIONTOSMBUS	0x0015
+#define HUB_OUTPUT_CONNECTION	0x0016
+#define HUB_CHARGER_CONNECTION	0x0017
+#define HUB_BATTERY_INSERTION	0x0018
+#define HUB_USENEXT		0x0019
+#define HUB_OKTOUSE		0x001a
+#define HUB_BATTERY_SUPPORTED	0x001b
+#define HUB_SELECTOR_REVISION	0x001c
+#define HUB_CHARGING_INDICATOR	0x001d
+#define HUB_MANUFACTURER_ACCESS	0x0028
+#define HUB_REM_CAPACITY_LIM	0x0029
+#define HUB_REM_TIME_LIM	0x002a
+#define HUB_ATRATE		0x002b
+#define HUB_CAPACITY_MODE	0x002c
+#define HUB_BCAST_TO_CHARGER	0x002d
+#define HUB_PRIMARY_BATTERY	0x002e
+#define HUB_CHANGE_CONTROLLER	0x002f
+#define HUB_TERMINATE_CHARGE	0x0040
+#define HUB_TERMINATE_DISCHARGE	0x0041
+#define HUB_BELOW_REM_CAP_LIM	0x0042
+#define HUB_REM_TIME_LIM_EXP	0x0043
+#define HUB_CHARGING		0x0044
+#define HUB_DISCHARGING		0x0045
+#define HUB_FULLY_CHARGED	0x0046
+#define HUB_FULLY_DISCHARGED	0x0047
+#define HUB_CONDITIONING_FLAG	0x0048
+#define HUB_ATRATE_OK		0x0049
+#define HUB_SMB_ERROR_CODE	0x004a
+#define HUB_NEED_REPLACEMENT	0x004b
+#define HUB_ATRATE_TIMETOFULL	0x0060
+#define HUB_ATRATE_TIMETOEMPTY	0x0061
+#define HUB_AVERAGE_CURRENT	0x0062
+#define HUB_MAXERROR		0x0063
+#define HUB_REL_STATEOF_CHARGE	0x0064
+#define HUB_ABS_STATEOF_CHARGE	0x0065
+#define HUB_REM_CAPACITY	0x0066
+#define HUB_FULLCHARGE_CAPACITY	0x0067
+#define HUB_RUNTIMETO_EMPTY	0x0068
+#define HUB_AVERAGETIMETO_EMPTY	0x0069
+#define HUB_AVERAGETIMETO_FULL	0x006a
+#define HUB_CYCLECOUNT		0x006b
+#define HUB_BATTPACKMODEL_LEVEL	0x0080
+#define HUB_INTERNAL_CHARGE_CTL	0x0081
+#define HUB_PRIMARY_BATTERY_SUP	0x0082
+#define HUB_DESIGN_CAPACITY	0x0083
+#define HUB_SPECIFICATION_INFO	0x0084
+#define HUB_MANUFACTURER_DATE	0x0085
+#define HUB_SERIAL_NUMBER	0x0086
+#define HUB_IMANUFACTURERNAME	0x0087
+#define HUB_IDEVICENAME		0x0088
+#define HUB_IDEVICECHEMISTERY	0x0089
+#define HUB_MANUFACTURERDATA	0x008a
+#define HUB_RECHARGABLE		0x008b
+#define HUB_WARN_CAPACITY_LIM	0x008c
+#define HUB_CAPACITY_GRANUL1	0x008d
+#define HUB_CAPACITY_GRANUL2	0x008e
+#define HUB_IOEM_INFORMATION	0x008f
+#define HUB_INHIBIT_CHARGE	0x00c0
+#define HUB_ENABLE_POLLING	0x00c1
+#define HUB_RESTORE_TO_ZERO	0x00c2
+#define HUB_AC_PRESENT		0x00d0
+#define HUB_BATTERY_PRESENT	0x00d1
+#define HUB_POWER_FAIL		0x00d2
+#define HUB_ALARM_INHIBITED	0x00d3
+#define HUB_THERMISTOR_UNDRANGE	0x00d4
+#define HUB_THERMISTOR_HOT	0x00d5
+#define HUB_THERMISTOR_COLD	0x00d6
+#define HUB_THERMISTOR_OVERANGE	0x00d7
+#define HUB_BS_VOLT_OUTOF_RANGE	0x00d8
+#define HUB_BS_CURR_OUTOF_RANGE	0x00d9
+#define HUB_BS_CURR_NOT_REGULTD	0x00da
+#define HUB_BS_VOLT_NOT_REGULTD	0x00db
+#define HUB_MASTER_MODE		0x00dc
+#define HUB_CHARGER_SELECTR_SUP	0x00f0
+#define HUB_CHARGER_SPEC	0x00f1
+#define HUB_LEVEL2		0x00f2
+#define HUB_LEVEL3		0x00f3
+
+/* Usages, generic desktop */
+#define HUG_POINTER		0x0001
+#define HUG_MOUSE		0x0002
+#define HUG_FN_KEY		0x0003
+#define HUG_JOYSTICK		0x0004
+#define HUG_GAME_PAD		0x0005
+#define HUG_KEYBOARD		0x0006
+#define HUG_KEYPAD		0x0007
+#define HUG_X			0x0030
+#define HUG_Y			0x0031
+#define HUG_Z			0x0032
+#define HUG_RX			0x0033
+#define HUG_RY			0x0034
+#define HUG_RZ			0x0035
+#define HUG_SLIDER		0x0036
+#define HUG_DIAL		0x0037
+#define HUG_WHEEL		0x0038
+#define HUG_HAT_SWITCH		0x0039
+#define HUG_COUNTED_BUFFER	0x003a
+#define HUG_BYTE_COUNT		0x003b
+#define HUG_MOTION_WAKEUP	0x003c
+#define HUG_VX			0x0040
+#define HUG_VY			0x0041
+#define HUG_VZ			0x0042
+#define HUG_VBRX		0x0043
+#define HUG_VBRY		0x0044
+#define HUG_VBRZ		0x0045
+#define HUG_VNO			0x0046
+#define HUG_TWHEEL		0x0048
+#define HUG_SYSTEM_CONTROL	0x0080
+#define HUG_SYSTEM_POWER_DOWN	0x0081
+#define HUG_SYSTEM_SLEEP	0x0082
+#define HUG_SYSTEM_WAKEUP	0x0083
+#define HUG_SYSTEM_CONTEXT_MENU	0x0084
+#define HUG_SYSTEM_MAIN_MENU	0x0085
+#define HUG_SYSTEM_APP_MENU	0x0086
+#define HUG_SYSTEM_MENU_HELP	0x0087
+#define HUG_SYSTEM_MENU_EXIT	0x0088
+#define HUG_SYSTEM_MENU_SELECT	0x0089
+#define HUG_SYSTEM_MENU_RIGHT	0x008a
+#define HUG_SYSTEM_MENU_LEFT	0x008b
+#define HUG_SYSTEM_MENU_UP	0x008c
+#define HUG_SYSTEM_MENU_DOWN	0x008d
+
+/* Usages, Digitizers */
+#define HUD_UNDEFINED		0x0000
+#define HUD_DIGITIZER		0x0001
+#define HUD_PEN			0x0002
+#define HUD_TOUCH_SCREEN	0x0004
+#define HUD_TOUCHPAD		0x0005
+#define HUD_CONFIG		0x000e
+#define HUD_FINGER		0x0022
+#define HUD_TIP_PRESSURE	0x0030
+#define HUD_BARREL_PRESSURE	0x0031
+#define HUD_IN_RANGE		0x0032
+#define HUD_TOUCH		0x0033
+#define HUD_UNTOUCH		0x0034
+#define HUD_TAP			0x0035
+#define HUD_QUALITY		0x0036
+#define HUD_DATA_VALID		0x0037
+#define HUD_TRANSDUCER_INDEX	0x0038
+#define HUD_TABLET_FKEYS	0x0039
+#define HUD_PROGRAM_CHANGE_KEYS	0x003a
+#define HUD_BATTERY_STRENGTH	0x003b
+#define HUD_INVERT		0x003c
+#define HUD_X_TILT		0x003d
+#define HUD_Y_TILT		0x003e
+#define HUD_AZIMUTH		0x003f
+#define HUD_ALTITUDE		0x0040
+#define HUD_TWIST		0x0041
+#define HUD_TIP_SWITCH		0x0042
+#define HUD_SEC_TIP_SWITCH	0x0043
+#define HUD_BARREL_SWITCH	0x0044
+#define HUD_ERASER		0x0045
+#define HUD_TABLET_PICK		0x0046
+#define HUD_CONFIDENCE		0x0047
+#define HUD_WIDTH		0x0048
+#define HUD_HEIGHT		0x0049
+#define HUD_CONTACTID		0x0051
+#define HUD_INPUT_MODE		0x0052
+#define HUD_DEVICE_INDEX	0x0053
+#define HUD_CONTACTCOUNT	0x0054
+#define HUD_CONTACT_MAX		0x0055
+#define HUD_SCAN_TIME		0x0056
+#define HUD_BUTTON_TYPE		0x0059
+
+/* Usages, LED */
+#define HUD_LED_NUM_LOCK	0x0001
+#define HUD_LED_CAPS_LOCK	0x0002
+#define HUD_LED_SCROLL_LOCK	0x0003
+#define HUD_LED_COMPOSE		0x0004
+#define HUD_LED_KANA		0x0005
+
+/* Usages, Consumer */
+#define HUC_AC_PAN		0x0238
+
+#define HID_USAGE2(p, u) (((p) << 16) | u)
+#define HID_GET_USAGE(u) ((u) & 0xffff)
+#define HID_GET_USAGE_PAGE(u) (((u) >> 16) & 0xffff)
+
+#define HCOLL_PHYSICAL		0
+#define HCOLL_APPLICATION	1
+#define HCOLL_LOGICAL		2
+
+/* Bits in the input/output/feature items */
+#define HIO_CONST	0x001
+#define HIO_VARIABLE	0x002
+#define HIO_RELATIVE	0x004
+#define HIO_WRAP	0x008
+#define HIO_NONLINEAR	0x010
+#define HIO_NOPREF	0x020
+#define HIO_NULLSTATE	0x040
+#define HIO_VOLATILE	0x080
+#define HIO_BUFBYTES	0x100
+
+/* Valid values for the country codes */
+#define	HCC_UNDEFINED	0x00
+#define	HCC_MAX		0x23
+
+#endif /* _HIDHID_H_ */
Index: src/sys/dev/hid/hidkbdmap.c
diff -u /dev/null src/sys/dev/hid/hidkbdmap.c:1.1
--- /dev/null	Sun Dec 10 17:03:08 2017
+++ src/sys/dev/hid/hidkbdmap.c	Sun Dec 10 17:03:07 2017
@@ -0,0 +1,658 @@
+/*	$NetBSD: hidkbdmap.c,v 1.1 2017/12/10 17:03:07 bouyer Exp $	*/
+
+/*
+ * Copyright (c) 1999,2001 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Lennart Augustsson (lenn...@augustsson.net) at
+ * Carlstedt Research & Technology.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__KERNEL_RCSID(0, "$NetBSD: hidkbdmap.c,v 1.1 2017/12/10 17:03:07 bouyer Exp $");
+
+#include <sys/types.h>
+#include <dev/wscons/wsksymdef.h>
+#include <dev/wscons/wsksymvar.h>
+
+#include <dev/usb/usb.h>
+
+#define KC(n)		KS_KEYCODE(n)
+
+Static const keysym_t hidkbd_keydesc_us[] = {
+/*  pos      command		normal		shifted */
+    KC(4), 			KS_a,
+    KC(5), 			KS_b,
+    KC(6), 			KS_c,
+    KC(7), 			KS_d,
+    KC(8), 			KS_e,
+    KC(9), 			KS_f,
+    KC(10), 			KS_g,
+    KC(11), 			KS_h,
+    KC(12), 			KS_i,
+    KC(13), 			KS_j,
+    KC(14), 			KS_k,
+    KC(15), 			KS_l,
+    KC(16), 			KS_m,
+    KC(17), 			KS_n,
+    KC(18), 			KS_o,
+    KC(19), 			KS_p,
+    KC(20), 			KS_q,
+    KC(21), 			KS_r,
+    KC(22), 			KS_s,
+    KC(23), 			KS_t,
+    KC(24), 			KS_u,
+    KC(25), 			KS_v,
+    KC(26), 			KS_w,
+    KC(27), 			KS_x,
+    KC(28), 			KS_y,
+    KC(29), 			KS_z,
+    KC(30),  			KS_1,		KS_exclam,
+    KC(31),  			KS_2,		KS_at,
+    KC(32),  			KS_3,		KS_numbersign,
+    KC(33),  			KS_4,		KS_dollar,
+    KC(34),  			KS_5,		KS_percent,
+    KC(35),  			KS_6,		KS_asciicircum,
+    KC(36),  			KS_7,		KS_ampersand,
+    KC(37),  			KS_8,		KS_asterisk,
+    KC(38), 			KS_9,		KS_parenleft,
+    KC(39), 			KS_0,		KS_parenright,
+    KC(40), 			KS_Return,
+    KC(41),   KS_Cmd_Debugger,	KS_Escape,
+    KC(42), 			KS_BackSpace,
+    KC(43), 			KS_Tab,
+    KC(44), 			KS_space,
+    KC(45), 			KS_minus,	KS_underscore,
+    KC(46), 			KS_equal,	KS_plus,
+    KC(47), 			KS_bracketleft,	KS_braceleft,
+    KC(48), 			KS_bracketright,KS_braceright,
+    KC(49), 			KS_backslash,	KS_bar,
+    KC(50), 			KS_backslash,	KS_bar,
+    KC(51), 			KS_semicolon,	KS_colon,
+    KC(52), 			KS_apostrophe,	KS_quotedbl,
+    KC(53), 			KS_grave,	KS_asciitilde,
+    KC(54), 			KS_comma,	KS_less,
+    KC(55), 			KS_period,	KS_greater,
+    KC(56), 			KS_slash,	KS_question,
+    KC(57), 			KS_Caps_Lock,
+    KC(58),  KS_Cmd_Screen0,	KS_f1,
+    KC(59),  KS_Cmd_Screen1,	KS_f2,
+    KC(60),  KS_Cmd_Screen2,	KS_f3,
+    KC(61),  KS_Cmd_Screen3,	KS_f4,
+    KC(62),  KS_Cmd_Screen4,	KS_f5,
+    KC(63),  KS_Cmd_Screen5,	KS_f6,
+    KC(64),  KS_Cmd_Screen6,	KS_f7,
+    KC(65),  KS_Cmd_Screen7,	KS_f8,
+    KC(66),  KS_Cmd_Screen8,	KS_f9,
+    KC(67),  KS_Cmd_Screen9,	KS_f10,
+    KC(68), 			KS_f11,
+    KC(69), 			KS_f12,
+    KC(70),			KS_Print_Screen,
+    KC(71), 			KS_Hold_Screen,
+    KC(72),			KS_Pause,
+    KC(73),			KS_Insert,
+    KC(74),			KS_Home,
+    KC(75), KS_Cmd_ScrollFastUp, KS_Prior,
+    KC(76),			KS_Delete,
+    KC(77),			KS_End,
+    KC(78), KS_Cmd_ScrollFastDown, KS_Next,
+    KC(79),			KS_Right,
+    KC(80),			KS_Left,
+    KC(81),			KS_Down,
+    KC(82),			KS_Up,
+    KC(83), 			KS_Num_Lock,
+    KC(84),			KS_KP_Divide,
+    KC(85), 			KS_KP_Multiply,
+    KC(86), 			KS_KP_Subtract,
+    KC(87), 			KS_KP_Add,
+    KC(88),			KS_KP_Enter,
+    KC(89), 			KS_KP_End,	KS_KP_1,
+    KC(90), 			KS_KP_Down,	KS_KP_2,
+    KC(91), KS_Cmd_ScrollFastDown, KS_KP_Next,	KS_KP_3,
+    KC(92), 			KS_KP_Left,	KS_KP_4,
+    KC(93), 			KS_KP_Begin,	KS_KP_5,
+    KC(94), 			KS_KP_Right,	KS_KP_6,
+    KC(95), 			KS_KP_Home,	KS_KP_7,
+    KC(96), 			KS_KP_Up,	KS_KP_8,
+    KC(97), KS_Cmd_ScrollFastUp, KS_KP_Prior,	KS_KP_9,
+    KC(98), 			KS_KP_Insert,	KS_KP_0,
+    KC(99), 			KS_KP_Delete,	KS_KP_Decimal,
+    KC(100),			KS_backslash,	KS_bar,
+    KC(101),			KS_Menu,
+/* ... */
+    KC(104), 			KS_f13,
+    KC(105), 			KS_f14,
+    KC(106), 			KS_f15,
+    KC(107), 			KS_f16,
+/* ... */
+    KC(109),			KS_Power,
+/* ... many unmapped keys ... */
+    KC(224),  KS_Cmd1,		KS_Control_L,
+    KC(225), 			KS_Shift_L,
+    KC(226),  KS_Cmd2,		KS_Alt_L,
+    KC(227),			KS_Meta_L,
+    KC(228),			KS_Control_R,
+    KC(229), 			KS_Shift_R,
+    KC(230),			KS_Alt_R,	KS_Multi_key,
+    KC(231),			KS_Meta_R,
+};
+
+Static const keysym_t hidkbd_keydesc_jp[] = {
+/*  pos      command		normal			shifted */
+    KC(31),  			KS_2,			KS_quotedbl,
+    KC(35),  			KS_6,			KS_ampersand,
+    KC(36),  			KS_7,			KS_apostrophe,
+    KC(37),  			KS_8,			KS_parenleft,
+    KC(38), 			KS_9,			KS_parenright,
+    KC(39), 			KS_0,
+    KC(45),			KS_minus,		KS_equal,
+    KC(46),			KS_asciicircum,		KS_asciitilde,
+    KC(47),			KS_at,			KS_grave,
+    KC(48),			KS_bracketleft,		KS_braceleft,
+    KC(50),			KS_bracketright,	KS_braceright,
+    KC(51),			KS_semicolon,		KS_plus,
+    KC(52),			KS_colon,		KS_asterisk,
+    KC(53), 			KS_Zenkaku_Hankaku, /* replace grave/tilde */
+    KC(135),			KS_backslash,		KS_underscore,
+    KC(136),			KS_Hiragana_Katakana,
+    KC(137),			KS_backslash,		KS_bar,
+    KC(138),			KS_Henkan,
+    KC(139),			KS_Muhenkan,
+};
+
+Static const keysym_t hidkbd_keydesc_us_dvorak[] = {
+/*  pos      command		normal			shifted */
+    KC(4), 			KS_a,
+    KC(5), 			KS_x,
+    KC(6), 			KS_j,
+    KC(7), 			KS_e,
+    KC(8), 			KS_period,		KS_greater,
+    KC(9), 			KS_u,
+    KC(10), 			KS_i,
+    KC(11), 			KS_d,
+    KC(12), 			KS_c,
+    KC(13), 			KS_h,
+    KC(14), 			KS_t,
+    KC(15), 			KS_n,
+    KC(16), 			KS_m,
+    KC(17), 			KS_b,
+    KC(18), 			KS_r,
+    KC(19), 			KS_l,
+    KC(20), 			KS_apostrophe,		KS_quotedbl,
+    KC(21), 			KS_p,
+    KC(22), 			KS_o,
+    KC(23), 			KS_y,
+    KC(24), 			KS_g,
+    KC(25), 			KS_k,
+    KC(26), 			KS_comma,		KS_less,
+    KC(27), 			KS_q,
+    KC(28), 			KS_f,
+    KC(29), 			KS_semicolon,		KS_colon,
+    KC(45), 			KS_bracketleft,		KS_braceleft,
+    KC(46), 			KS_bracketright,	KS_braceright,
+    KC(47), 			KS_slash,		KS_question,
+    KC(48), 			KS_equal,		KS_plus,
+    KC(51), 			KS_s,
+    KC(52), 			KS_minus,		KS_underscore,
+    KC(54), 			KS_w,
+    KC(55), 			KS_v,
+    KC(56), 			KS_z,
+};
+
+Static const keysym_t hidkbd_keydesc_us_colemak[] = {
+/*  pos      command		normal		shifted */
+    KC(4), 			KS_a,		KS_A,		KS_aacute,	KS_Aacute,
+    KC(5), 			KS_b,		KS_B,		KS_asciitilde,	KS_asciitilde,
+    KC(6), 			KS_c,		KS_C,		KS_ccedilla,	KS_Ccedilla,
+    KC(7), 			KS_s,		KS_S,		KS_ssharp,	KS_asciitilde,
+    KC(8), 			KS_f,		KS_F,		KS_atilde,	KS_Atilde,
+    KC(9), 			KS_t,		KS_T,		KS_dead_acute,	KS_asciitilde,
+    KC(10), 			KS_d,		KS_D,		KS_dead_diaeresis, KS_asciitilde,
+    KC(11), 			KS_h,		KS_H,		KS_asciitilde,	KS_asciitilde,
+    KC(12), 			KS_u,		KS_U,		KS_uacute,	KS_Uacute,
+    KC(13), 			KS_n,		KS_N,		KS_ntilde,	KS_Ntilde,
+    KC(14), 			KS_e,		KS_E,		KS_eacute,	KS_Eacute,
+    KC(15), 			KS_i,		KS_I,		KS_iacute,	KS_Iacute,
+    KC(16), 			KS_m,		KS_M,		KS_asciitilde,	KS_asciitilde,
+    KC(17), 			KS_k,		KS_K,		KS_asciitilde,	KS_asciitilde,
+    KC(18), 			KS_y,		KS_Y,		KS_udiaeresis,	KS_Udiaeresis,
+    KC(19), 			KS_semicolon,	KS_colon,	KS_odiaeresis,	KS_Odiaeresis,
+    KC(20), 			KS_q,		KS_Q,		KS_adiaeresis,	KS_Adiaeresis,
+    KC(21), 			KS_p,		KS_P,		KS_oslash,	KS_Ooblique,
+    KC(22), 			KS_r,		KS_R,		KS_dead_grave,	KS_asciitilde,
+    KC(23), 			KS_g,		KS_G,		KS_asciitilde,	KS_asciitilde,
+    KC(24), 			KS_l,		KS_L,		KS_asciitilde,	KS_asciitilde,
+    KC(25), 			KS_v,		KS_V,		KS_asciitilde,	KS_asciitilde,
+    KC(26), 			KS_w,		KS_W,		KS_aring,	KS_Aring,
+    KC(27), 			KS_x,		KS_X,		KS_dead_circumflex, KS_asciitilde,
+    KC(28), 			KS_j,		KS_J,		KS_asciitilde,	KS_asciitilde,
+    KC(29), 			KS_z,		KS_Z,		KS_ae,		KS_AE,
+    KC(30),  			KS_1,		KS_exclam,	KS_exclamdown,	KS_onesuperior,
+    KC(31),  			KS_2,		KS_at,		KS_masculine,	KS_twosuperior,
+    KC(32),  			KS_3,		KS_numbersign,	KS_ordfeminine,	KS_threesuperior,
+    KC(33),  			KS_4,		KS_dollar,	KS_cent,	KS_sterling,
+    KC(34),  			KS_5,		KS_percent,	KS_asciitilde,	KS_yen,
+    KC(35),  			KS_6,		KS_asciicircum,	KS_asciitilde,	KS_asciitilde,
+    KC(36),  			KS_7,		KS_ampersand,	KS_eth,		KS_ETH,
+    KC(37),  			KS_8,		KS_asterisk,	KS_thorn,	KS_THORN,
+    KC(38), 			KS_9,		KS_parenleft,	KS_asciitilde,	KS_asciitilde,
+    KC(39), 			KS_0,		KS_parenright,	KS_asciitilde,	KS_asciitilde,
+    KC(44), 			KS_space,	KS_space,	KS_space,	KS_nobreakspace,
+    KC(45), 			KS_minus,	KS_underscore,	KS_asciitilde,	KS_asciitilde,
+    KC(46), 			KS_equal,	KS_plus,	KS_multiply,	KS_division,
+    KC(47), 			KS_bracketleft,	KS_braceleft,	KS_guillemotleft, KS_asciitilde,
+    KC(48), 			KS_bracketright, KS_braceright,	KS_guillemotright, KS_asciitilde,
+    KC(49), 			KS_backslash,	KS_bar,		KS_asciitilde,	KS_asciitilde,
+    KC(50), 			KS_backslash,	KS_bar,		KS_asciitilde,	KS_asciitilde,
+    KC(51), 			KS_o,		KS_O,		KS_oacute,	KS_Oacute,
+    KC(52), 			KS_apostrophe,	KS_quotedbl,	KS_otilde,	KS_Otilde,
+    KC(53), 			KS_grave,	KS_asciitilde,	KS_dead_tilde,	KS_asciitilde,
+    KC(54), 			KS_comma,	KS_less,	KS_dead_cedilla, KS_asciitilde,
+    KC(55), 			KS_period,	KS_greater,	KS_asciitilde,	KS_asciitilde,
+    KC(56), 			KS_slash,	KS_question,	KS_questiondown, KS_asciitilde,
+    KC(57), 			KS_BackSpace,
+    KC(100), 			KS_minus,	KS_underscore,	KS_asciitilde,	KS_asciitilde,
+    KC(230), KS_Mode_switch,	KS_Multi_key,
+};
+
+Static const keysym_t hidkbd_keydesc_swapctrlcaps[] = {
+/*  pos      command		normal		shifted */
+    KC(57), 			KS_Control_L,
+    KC(224), KS_Cmd1,		KS_Caps_Lock,
+};
+
+Static const keysym_t hidkbd_keydesc_de[] = {
+/*  pos      normal		shifted		altgr		shift-altgr */
+    KC(16),  KS_m,		KS_M,		KS_mu,
+    KC(20),  KS_q,		KS_Q,		KS_at,
+    KC(28),  KS_z,
+    KC(29),  KS_y,
+    KC(31),  KS_2,		KS_quotedbl,	KS_twosuperior,
+    KC(32),  KS_3,		KS_section,	KS_threesuperior,
+    KC(35),  KS_6,		KS_ampersand,
+    KC(36),  KS_7,		KS_slash,	KS_braceleft,
+    KC(37),  KS_8,		KS_parenleft,	KS_bracketleft,
+    KC(38),  KS_9,		KS_parenright,	KS_bracketright,
+    KC(39),  KS_0,		KS_equal,	KS_braceright,
+    KC(45),  KS_ssharp,		KS_question,	KS_backslash,
+    KC(46),  KS_dead_acute,	KS_dead_grave,
+    KC(47),  KS_udiaeresis,
+    KC(48),  KS_plus,		KS_asterisk,	KS_dead_tilde,
+    KC(50),  KS_numbersign,	KS_apostrophe,
+    KC(51),  KS_odiaeresis,
+    KC(52),  KS_adiaeresis,
+    KC(53),  KS_dead_circumflex,KS_dead_abovering,
+    KC(54),  KS_comma,		KS_semicolon,
+    KC(55),  KS_period,		KS_colon,
+    KC(56),  KS_minus,		KS_underscore,
+    KC(100), KS_less,		KS_greater,	KS_bar,		KS_brokenbar,
+    KC(230), KS_Mode_switch,	KS_Multi_key,
+};
+
+Static const keysym_t hidkbd_keydesc_de_nodead[] = {
+/*  pos      normal		shifted		altgr		shift-altgr */
+    KC(46),  KS_apostrophe,	KS_grave,
+    KC(48),  KS_plus,		KS_asterisk,	KS_asciitilde,
+    KC(53),  KS_asciicircum,	KS_degree,
+};
+
+Static const keysym_t hidkbd_keydesc_dk[] = {
+/*  pos      normal		shifted		altgr		shift-altgr */
+    KC(31),  KS_2,		KS_quotedbl,	KS_at,
+    KC(32),  KS_3,		KS_numbersign,	KS_sterling,
+    KC(33),  KS_4,		KS_currency,	KS_dollar,
+    KC(35),  KS_6,		KS_ampersand,
+    KC(36),  KS_7,		KS_slash,	KS_braceleft,
+    KC(37),  KS_8,		KS_parenleft,	KS_bracketleft,
+    KC(38),  KS_9,		KS_parenright,	KS_bracketright,
+    KC(39),  KS_0,		KS_equal,	KS_braceright,
+    KC(45),  KS_plus,		KS_question,
+    KC(46),  KS_dead_acute,	KS_dead_grave,	KS_bar,
+    KC(47),  KS_aring,
+    KC(48),  KS_dead_diaeresis,	KS_dead_circumflex, KS_dead_tilde,
+    KC(50),  KS_apostrophe,	KS_asterisk,
+    KC(51),  KS_ae,
+    KC(52),  KS_oslash,
+    KC(53),  KS_onehalf,	KS_paragraph,
+    KC(54),  KS_comma,		KS_semicolon,
+    KC(55),  KS_period,		KS_colon,
+    KC(56),  KS_minus,		KS_underscore,
+    KC(100), KS_less,		KS_greater,	KS_backslash,
+    KC(230), KS_Mode_switch,	KS_Multi_key,
+};
+
+Static const keysym_t hidkbd_keydesc_dk_nodead[] = {
+/*  pos      normal		shifted		altgr		shift-altgr */
+    KC(46),  KS_apostrophe,	KS_grave,	KS_bar,
+    KC(48),  KS_diaeresis,	KS_asciicircum,	KS_asciitilde,
+};
+
+Static const keysym_t hidkbd_keydesc_sv[] = {
+/*  pos      normal		shifted		altgr		shift-altgr */
+    KC(45),  KS_plus,		KS_question,	KS_backslash,
+    KC(48),  KS_dead_diaeresis,	KS_dead_circumflex, KS_dead_tilde,
+    KC(50),  KS_apostrophe,	KS_asterisk,
+    KC(51),  KS_odiaeresis,
+    KC(52),  KS_adiaeresis,
+    KC(53),  KS_paragraph,	KS_onehalf,
+    KC(100), KS_less,		KS_greater,	KS_bar,
+    KC(230), KS_Mode_switch,	KS_Multi_key,
+};
+
+Static const keysym_t hidkbd_keydesc_sv_nodead[] = {
+/*  pos      normal		shifted		altgr		shift-altgr */
+    KC(46),  KS_apostrophe,	KS_grave,	KS_bar,
+    KC(48),  KS_diaeresis,	KS_asciicircum,	KS_asciitilde,
+};
+
+Static const keysym_t hidkbd_keydesc_no[] = {
+/*  pos      normal		shifted		altgr		shift-altgr */
+    KC(46),  KS_backslash,	KS_dead_grave,	KS_dead_acute,
+    KC(48),  KS_dead_diaeresis,	KS_dead_circumflex, KS_dead_tilde,
+    KC(50),  KS_comma,		KS_asterisk,
+    KC(51),  KS_oslash,
+    KC(52),  KS_ae,
+    KC(53),  KS_bar,		KS_paragraph,
+    KC(100), KS_less,		KS_greater,
+};
+
+Static const keysym_t hidkbd_keydesc_no_nodead[] = {
+/*  pos      normal		shifted		altgr		shift-altgr */
+    KC(46),  KS_backslash,	KS_grave,	KS_acute,
+    KC(48),  KS_diaeresis,	KS_asciicircum,	KS_asciitilde,
+};
+
+Static const keysym_t hidkbd_keydesc_fr[] = {
+/*  pos	     normal		shifted		altgr		shift-altgr */
+    KC(4),   KS_q,
+    KC(16),  KS_comma,		KS_question,
+    KC(20),  KS_a,
+    KC(26),  KS_z,
+    KC(29),  KS_w,
+    KC(30),  KS_ampersand,	KS_1,
+    KC(31),  KS_eacute,		KS_2,		KS_asciitilde,
+    KC(32),  KS_quotedbl,	KS_3,		KS_numbersign,
+    KC(33),  KS_apostrophe,	KS_4,		KS_braceleft,
+    KC(34),  KS_parenleft,	KS_5,		KS_bracketleft,
+    KC(35),  KS_minus,		KS_6,		KS_bar,
+    KC(36),  KS_egrave,		KS_7,		KS_grave,
+    KC(37),  KS_underscore,	KS_8,		KS_backslash,
+    KC(38),  KS_ccedilla,	KS_9,		KS_asciicircum,
+    KC(39),  KS_agrave,		KS_0,		KS_at,
+    KC(45),  KS_parenright,	KS_degree,	KS_bracketright,
+    KC(46),  KS_equal,		KS_plus,	KS_braceright,
+    KC(47),  KS_dead_circumflex, KS_dead_diaeresis,
+    KC(48),  KS_dollar,		KS_sterling,	KS_currency,
+    KC(50),  KS_asterisk,	KS_mu,
+    KC(51),  KS_m,
+    KC(52),  KS_ugrave,		KS_percent,
+    KC(53),  KS_twosuperior,
+    KC(54),  KS_semicolon,	KS_period,
+    KC(55),  KS_colon,		KS_slash,
+    KC(56),  KS_exclam,		KS_section,
+    KC(100), KS_less,		KS_greater,
+    KC(230), KS_Mode_switch,	KS_Multi_key,
+};
+
+Static const keysym_t hidkbd_keydesc_be[] = {
+/*  pos	     normal		shifted		altgr		shift-altgr */
+    KC(30),  KS_ampersand,	KS_1,		KS_bar,
+    KC(31),  KS_eacute,		KS_2,		KS_at,
+    KC(33),  KS_apostrophe,	KS_4,
+    KC(34),  KS_parenleft,	KS_5,
+    KC(35),  KS_section,	KS_6,		KS_asciicircum,
+    KC(36),  KS_egrave,		KS_7,
+    KC(37),  KS_exclam,		KS_8,
+    KC(38),  KS_ccedilla,	KS_9,		KS_braceleft,
+    KC(39),  KS_agrave,		KS_0,		KS_braceright,
+    KC(45),  KS_parenright,	KS_degree,
+    KC(46),  KS_minus,		KS_underscore,
+    KC(47),  KS_dead_circumflex, KS_dead_diaeresis,	KS_bracketleft,
+    KC(48),  KS_dollar,		KS_asterisk,	KS_bracketright,
+    KC(50),  KS_mu,		KS_sterling,	KS_grave,
+    KC(52),  KS_ugrave,		KS_percent,	KS_acute,
+    KC(53),  KS_twosuperior,	KS_threesuperior,
+    KC(56),  KS_equal,		KS_plus,	KS_asciitilde,
+    KC(100), KS_less,		KS_greater,	KS_backslash,
+};
+
+Static const keysym_t hidkbd_keydesc_it[] = {
+/*  pos      normal		shifted		altgr		shift-altgr */
+    KC(31),  KS_2,	    	KS_quotedbl,	KS_twosuperior,
+    KC(32),  KS_3,	    	KS_sterling,	KS_threesuperior,
+    KC(33),  KS_4,	    	KS_dollar,
+    KC(34),  KS_5,	    	KS_percent,
+    KC(35),  KS_6,	    	KS_ampersand,
+    KC(36),  KS_7,	    	KS_slash,
+    KC(37),  KS_8,	    	KS_parenleft,
+    KC(38),  KS_9,	    	KS_parenright,
+    KC(39),  KS_0,	    	KS_equal,
+    KC(45),  KS_apostrophe,	KS_question,
+    KC(46),  KS_igrave,	    	KS_asciicircum,
+    KC(47),  KS_egrave,		KS_eacute,	KS_braceleft,	KS_bracketleft,
+    KC(48),  KS_plus,		KS_asterisk,	KS_braceright,	KS_bracketright,
+    KC(49),  KS_ugrave,		KS_section,
+    KC(51),  KS_ograve,		KS_Ccedilla,	KS_at,
+    KC(52),  KS_agrave,		KS_degree,	KS_numbersign,
+    KC(53),  KS_backslash,	KS_bar,
+    KC(54),  KS_comma,		KS_semicolon,
+    KC(55),  KS_period,		KS_colon,
+    KC(56),  KS_minus,		KS_underscore,
+    KC(100), KS_less,		KS_greater,
+    KC(230), KS_Mode_switch,	KS_Multi_key,
+};
+
+Static const keysym_t hidkbd_keydesc_uk[] = {
+/*  pos      normal             shifted         altgr           shift-altgr */
+    KC(30),  KS_1,              KS_exclam,      KS_plusminus,   KS_exclamdown,
+    KC(31),  KS_2,              KS_quotedbl,    KS_twosuperior, KS_cent,
+    KC(32),  KS_3,              KS_sterling,    KS_threesuperior,
+    KC(33),  KS_4,              KS_dollar,      KS_acute,       KS_currency,
+    KC(34),  KS_5,              KS_percent,     KS_mu,          KS_yen,
+    KC(35),  KS_6,              KS_asciicircum, KS_paragraph,
+    KC(36),  KS_7,              KS_ampersand,   KS_periodcentered, KS_brokenbar,
+    KC(37),  KS_8,              KS_asterisk,    KS_cedilla,     KS_ordfeminine,
+    KC(38),  KS_9,              KS_parenleft,   KS_onesuperior, KS_diaeresis,
+    KC(39),  KS_0,              KS_parenright,  KS_masculine,   KS_copyright,
+    KC(45),  KS_minus,          KS_underscore,  KS_hyphen,      KS_ssharp,
+    KC(46),  KS_equal,          KS_plus,        KS_onehalf,    KS_guillemotleft,
+    KC(49),  KS_numbersign,     KS_asciitilde,  KS_sterling,    KS_thorn,
+    KC(50),  KS_numbersign,	KS_asciitilde,
+    KC(52),  KS_apostrophe,     KS_at,          KS_section,     KS_Agrave,
+    KC(53),  KS_grave,          KS_grave,       KS_agrave,      KS_agrave,
+    KC(100), KS_backslash,      KS_bar,         KS_Udiaeresis,
+};
+
+Static const keysym_t hidkbd_keydesc_es[] = {
+/*  pos      normal		shifted		altgr		shift-altgr */
+    KC(30),  KS_1,		KS_exclam,	KS_bar,
+    KC(31),  KS_2,		KS_quotedbl,	KS_at,
+    KC(32),  KS_3,		KS_periodcentered, KS_numbersign,
+    KC(33),  KS_4,		KS_dollar,	KS_asciitilde,
+    KC(35),  KS_6,		KS_ampersand,
+    KC(36),  KS_7,		KS_slash,
+    KC(37),  KS_8,		KS_parenleft,
+    KC(38),  KS_9,		KS_parenright,
+    KC(39),  KS_0,		KS_equal,
+    KC(45),  KS_apostrophe,	KS_question,
+    KC(46),  KS_exclamdown,	KS_questiondown,
+    KC(47),  KS_dead_grave,	KS_dead_circumflex, KS_bracketleft,
+    KC(48),  KS_plus,		KS_asterisk,	KS_bracketright,
+    KC(49),  KS_ccedilla,	KS_Ccedilla,	KS_braceright,
+    KC(50),  KS_ccedilla,	KS_Ccedilla,	KS_braceright,
+    KC(51),  KS_ntilde,
+    KC(52),  KS_dead_acute,	KS_dead_diaeresis, KS_braceleft,
+    KC(53),  KS_degree,		KS_ordfeminine,	KS_backslash,
+    KC(54),  KS_comma,		KS_semicolon,
+    KC(55),  KS_period,		KS_colon,
+    KC(56),  KS_minus,		KS_underscore,
+    KC(100), KS_less,		KS_greater,
+    KC(230), KS_Mode_switch,	KS_Multi_key,
+};
+
+Static const keysym_t hidkbd_keydesc_pt[] = {
+/*  pos      normal		shifted		altgr		shift-altgr */
+    KC(31),  KS_2,		KS_quotedbl,	KS_at,
+    KC(32),  KS_3,		KS_numbersign,	KS_sterling,
+    KC(35),  KS_6,		KS_ampersand,
+    KC(36),  KS_7,		KS_slash,	KS_braceleft,
+    KC(37),  KS_8,		KS_parenleft,	KS_bracketleft,
+    KC(38),  KS_9,		KS_parenright,	KS_bracketright,
+    KC(39),  KS_0,		KS_equal,	KS_braceright,
+    KC(45),  KS_apostrophe,	KS_question,
+    KC(46),  KS_plus,		KS_asterisk,
+    KC(47),  KS_plus,		KS_asterisk,
+    KC(48),  KS_dead_acute,	KS_dead_grave,
+    KC(49),  KS_less,		KS_greater,
+    KC(50),  KS_dead_tilde,	KS_dead_circumflex,
+    KC(51),  KS_ccedilla,	KS_Ccedilla,
+    KC(52),  KS_masculine,	KS_ordfeminine,
+    KC(53),  KS_backslash,	KS_bar,
+    KC(54),  KS_comma,		KS_semicolon,
+    KC(55),  KS_period,		KS_colon,
+    KC(56),  KS_minus,		KS_underscore,
+    KC(100), KS_less,		KS_greater,
+    KC(226), KS_Mode_switch,	KS_Multi_key,
+    KC(230), KS_Mode_switch,	KS_Multi_key,
+};
+
+Static const keysym_t hidkbd_keydesc_sg[] = {
+/*  pos      normal		shifted		altgr		shift-altgr */
+    KC(30),  KS_1,		KS_plus,	KS_bar,
+    KC(31),  KS_2,		KS_quotedbl,	KS_at,
+    KC(32),  KS_3,		KS_asterisk,	KS_numbersign,
+    KC(33),  KS_4,		KS_ccedilla,
+    KC(35),  KS_6,		KS_ampersand,	KS_notsign,
+    KC(36),  KS_7,		KS_slash,	KS_brokenbar,
+    KC(37),  KS_8,		KS_parenleft,	KS_cent,
+    KC(38),  KS_9,		KS_parenright,
+    KC(39),  KS_0,		KS_equal,
+    KC(45),  KS_apostrophe,	KS_question,	KS_dead_acute,
+    KC(46),  KS_dead_circumflex,KS_dead_grave,	KS_dead_tilde,
+    KC(8),   KS_e,		KS_E,		KS_currency,
+    KC(28),  KS_z,
+    KC(47),  KS_udiaeresis,	KS_egrave,	KS_bracketleft,
+    KC(48),  KS_dead_diaeresis,	KS_exclam,	KS_bracketright,
+    KC(51),  KS_odiaeresis,	KS_eacute,
+    KC(52),  KS_adiaeresis,	KS_agrave,	KS_braceleft,
+    KC(53),  KS_section,	KS_degree,	KS_dead_abovering,
+    KC(50),  KS_dollar,		KS_sterling,	KS_braceright,
+    KC(29),  KS_y,
+    KC(54),  KS_comma,		KS_semicolon,
+    KC(55),  KS_period,		KS_colon,
+    KC(56),  KS_minus,		KS_underscore,
+    KC(100), KS_less,		KS_greater,	KS_backslash,
+    KC(230), KS_Mode_switch,	KS_Multi_key,
+};
+
+Static const keysym_t hidkbd_keydesc_sg_nodead[] = {
+/*  pos      normal		shifted		altgr		shift-altgr */
+    KC(45),  KS_apostrophe,	KS_question,	KS_acute,
+    KC(46),  KS_asciicircum,	KS_grave,	KS_asciitilde,
+    KC(48),  KS_diaeresis,	KS_exclam,	KS_bracketright
+};
+
+Static const keysym_t hidkbd_keydesc_sf[] = {
+/*  pos      normal            shifted         altgr           shift-altgr */
+    KC(47),  KS_egrave,        KS_udiaeresis,  KS_bracketleft,
+    KC(51),  KS_eacute,        KS_odiaeresis,
+    KC(52),  KS_agrave,        KS_adiaeresis,  KS_braceleft
+};
+
+static const keysym_t hidkbd_keydesc_hu[] = {
+/*  pos      normal		shifted		altgr		shift-altgr */
+    KC(5),   KS_b,		KS_B,		KS_braceleft,
+    KC(6),   KS_c,		KS_C,		KS_ampersand,
+    KC(9),   KS_f,		KS_F,		KS_bracketleft,
+    KC(10),  KS_g,		KS_G,		KS_bracketright,
+    KC(17),  KS_n,		KS_N,		KS_braceright,
+    KC(20),  KS_q,		KS_Q,		KS_backslash,
+    KC(25),  KS_v,		KS_V,		KS_at,
+    KC(26),  KS_w,		KS_W,		KS_bar,
+    KC(27),  KS_x,		KS_X,		KS_numbersign,
+    KC(28),  KS_z,
+    KC(29),  KS_y,		KS_Y,		KS_greater,
+    KC(30),  KS_1,		KS_apostrophe,	KS_asciitilde,
+    KC(31),  KS_2,		KS_quotedbl,	KS_dead_caron,
+    KC(32),  KS_3,		KS_plus,	KS_asciicircum,
+    KC(33),  KS_4,		KS_exclam,	KS_dead_breve,
+    KC(34),  KS_5,		KS_percent,	KS_dead_abovering,
+    KC(35),  KS_6,		KS_slash,	KS_dead_ogonek,
+    KC(36),  KS_7,		KS_equal,	KS_grave,
+    KC(37),  KS_8,		KS_parenleft,	KS_dead_dotaccent,
+    KC(38),  KS_9,		KS_parenright,	KS_dead_acute,
+    KC(39),  KS_odiaeresis,	KS_Odiaeresis,	KS_dead_hungarumlaut,
+    KC(45),  KS_udiaeresis,	KS_Udiaeresis,	KS_dead_diaeresis,
+    KC(46),  KS_oacute,		KS_Oacute,	KS_dead_cedilla,
+    KC(47),  KS_odoubleacute,	KS_Odoubleacute,KS_division,
+    KC(48),  KS_uacute,		KS_Uacute,	KS_multiply,
+    KC(49),  KS_udoubleacute,	KS_Udoubleacute,KS_currency,
+    KC(50),  KS_iacute,		KS_Iacute,	KS_less,
+    KC(51),  KS_eacute,		KS_Eacute,	KS_dollar,
+    KC(52),  KS_aacute,		KS_Aacute,	KS_ssharp,
+    KC(53),  KS_0,		KS_section,
+    KC(54),  KS_comma,		KS_question,	KS_semicolon,
+    KC(55),  KS_period,		KS_colon,
+    KC(56),  KS_minus,		KS_underscore,	KS_asterisk,
+    KC(230), KS_Mode_switch,	KS_Multi_key
+};
+
+#define KBD_MAP(name, base, map) \
+			{ name, base, sizeof(map)/sizeof(keysym_t), map }
+
+const struct wscons_keydesc hidkbd_keydesctab[] = {
+	KBD_MAP(KB_US,			0,	hidkbd_keydesc_us),
+	KBD_MAP(KB_US | KB_SWAPCTRLCAPS,KB_US,	hidkbd_keydesc_swapctrlcaps),
+	KBD_MAP(KB_US | KB_DVORAK,	KB_US,	hidkbd_keydesc_us_dvorak),
+	KBD_MAP(KB_US | KB_DVORAK | KB_SWAPCTRLCAPS,	KB_US| KB_DVORAK,
+		hidkbd_keydesc_swapctrlcaps),
+	KBD_MAP(KB_US | KB_COLEMAK,	KB_US,	hidkbd_keydesc_us_colemak),
+	KBD_MAP(KB_JP,			KB_US,	hidkbd_keydesc_jp),
+	KBD_MAP(KB_JP | KB_SWAPCTRLCAPS,KB_JP,	hidkbd_keydesc_swapctrlcaps),
+	KBD_MAP(KB_DE,			KB_US,	hidkbd_keydesc_de),
+	KBD_MAP(KB_DE | KB_NODEAD,	KB_DE,	hidkbd_keydesc_de_nodead),
+	KBD_MAP(KB_FR,                  KB_US,  hidkbd_keydesc_fr),
+	KBD_MAP(KB_FR | KB_SWAPCTRLCAPS,KB_FR,	hidkbd_keydesc_swapctrlcaps),
+	KBD_MAP(KB_BE,                  KB_FR,  hidkbd_keydesc_be),
+	KBD_MAP(KB_DK,			KB_US,	hidkbd_keydesc_dk),
+	KBD_MAP(KB_DK | KB_NODEAD,	KB_DK,	hidkbd_keydesc_dk_nodead),
+	KBD_MAP(KB_IT,			KB_US,	hidkbd_keydesc_it),
+	KBD_MAP(KB_UK,			KB_US,	hidkbd_keydesc_uk),
+	KBD_MAP(KB_SV,			KB_DK,	hidkbd_keydesc_sv),
+	KBD_MAP(KB_SV | KB_NODEAD,	KB_SV,	hidkbd_keydesc_sv_nodead),
+	KBD_MAP(KB_NO,			KB_DK,	hidkbd_keydesc_no),
+	KBD_MAP(KB_NO | KB_NODEAD,	KB_NO,	hidkbd_keydesc_no_nodead),
+	KBD_MAP(KB_ES ,			KB_US,	hidkbd_keydesc_es),
+	KBD_MAP(KB_PT,			KB_US,	hidkbd_keydesc_pt),
+	KBD_MAP(KB_SG,			KB_US,	hidkbd_keydesc_sg),
+	KBD_MAP(KB_SG | KB_NODEAD,	KB_SG,	hidkbd_keydesc_sg_nodead),
+	KBD_MAP(KB_SF,			KB_SG,	hidkbd_keydesc_sf),
+	KBD_MAP(KB_SF | KB_NODEAD,	KB_SF,	hidkbd_keydesc_sg_nodead),
+	KBD_MAP(KB_HU,			KB_US,	hidkbd_keydesc_hu),
+	{0, 0, 0, 0}
+};
+
+#undef KBD_MAP
+#undef KC
Index: src/sys/dev/hid/hidms.c
diff -u /dev/null src/sys/dev/hid/hidms.c:1.1
--- /dev/null	Sun Dec 10 17:03:08 2017
+++ src/sys/dev/hid/hidms.c	Sun Dec 10 17:03:07 2017
@@ -0,0 +1,290 @@
+/*	$NetBSD: hidms.c,v 1.1 2017/12/10 17:03:07 bouyer Exp $	*/
+
+/*
+ * Copyright (c) 1998, 2017 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Lennart Augustsson (lenn...@augustsson.net) at
+ * Carlstedt Research & Technology.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * HID spec: http://www.usb.org/developers/devclass_docs/HID1_11.pdf
+ */
+
+#include <sys/cdefs.h>
+__KERNEL_RCSID(0, "$NetBSD: hidms.c,v 1.1 2017/12/10 17:03:07 bouyer Exp $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/device.h>
+
+#include <dev/hid/hid.h>
+#include <dev/hid/hidms.h>
+
+#ifdef HIDMS_DEBUG
+#define DPRINTF(x)	if (hidmsdebug) printf x
+#define DPRINTFN(n,x)	if (hidmsdebug>(n)) printf x
+int	hidmsdebug = 0;
+#else
+#define DPRINTF(x)
+#define DPRINTFN(n,x)
+#endif
+
+#define HIDMS_BUT(i) ((i) == 1 || (i) == 2 ? 3 - (i) : i)
+
+#define PS2LBUTMASK	x01
+#define PS2RBUTMASK	x02
+#define PS2MBUTMASK	x04
+#define PS2BUTMASK 0x0f
+
+static const struct {
+	u_int feature;
+	u_int flag;
+} digbut[] = {
+	{ HUD_TIP_SWITCH, HIDMS_TIP_SWITCH },
+	{ HUD_SEC_TIP_SWITCH, HIDMS_SEC_TIP_SWITCH },
+	{ HUD_BARREL_SWITCH, HIDMS_BARREL_SWITCH },
+	{ HUD_ERASER, HIDMS_ERASER },
+};
+
+#define MOUSE_FLAGS_MASK (HIO_CONST|HIO_RELATIVE)
+
+bool
+hidms_setup(device_t self, struct hidms *ms, int id, void *desc, int size)
+{
+	uint32_t flags;
+	struct hid_location *zloc;
+	bool isdigitizer;
+	int i, hl;
+
+	isdigitizer = hid_is_collection(desc, size, id,
+	    HID_USAGE2(HUP_DIGITIZERS, 0x0002));
+
+	if (!hid_locate(desc, size, HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_X),
+	       id, hid_input, &ms->hidms_loc_x, &flags)) {
+		aprint_error("\n%s: mouse has no X report\n",
+		       device_xname(self));
+		return false;
+	}
+	switch (flags & MOUSE_FLAGS_MASK) {
+	case 0:
+		ms->flags |= HIDMS_ABS;
+		break;
+	case HIO_RELATIVE:
+		break;
+	default:
+		aprint_error("\n%s: X report 0x%04x not supported\n",
+		       device_xname(self), flags);
+		return false;
+	}
+
+	if (!hid_locate(desc, size, HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_Y),
+	       id, hid_input, &ms->hidms_loc_y, &flags)) {
+		aprint_error("\n%s: mouse has no Y report\n",
+		       device_xname(self));
+		return false;
+	}
+	switch (flags & MOUSE_FLAGS_MASK) {
+	case 0:
+		ms->flags |= HIDMS_ABS;
+		break;
+	case HIO_RELATIVE:
+		break;
+	default:
+		aprint_error("\n%s: Y report 0x%04x not supported\n",
+		       device_xname(self), flags);
+		return false;
+	}
+
+	/* Try the wheel first as the Z activator since it's tradition. */
+	hl = hid_locate(desc,
+			size,
+			HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_WHEEL),
+			id,
+			hid_input,
+			&ms->hidms_loc_z,
+			&flags);
+
+	zloc = &ms->hidms_loc_z;
+	if (hl) {
+		if ((flags & MOUSE_FLAGS_MASK) != HIO_RELATIVE) {
+			aprint_verbose("\n%s: Wheel report 0x%04x not "
+			    "supported\n", device_xname(self),
+			    flags);
+			ms->hidms_loc_z.size = 0;	/* Bad Z coord, ignore it */
+		} else {
+			ms->flags |= HIDMS_Z;
+			/* Wheels need the Z axis reversed. */
+			ms->flags ^= HIDMS_REVZ;
+			/* Put Z on the W coordinate */
+			zloc = &ms->hidms_loc_w;
+		}
+	}
+
+	hl = hid_locate(desc,
+			size,
+			HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_Z),
+			id,
+			hid_input,
+			zloc,
+			&flags);
+
+	/*
+	 * The horizontal component of the scrollball can also be given by
+	 * Application Control Pan in the Consumer page, so if we didnt see
+	 * any Z then check that.
+	 */
+	if (!hl) {
+		hl = hid_locate(desc,
+				size,
+				HID_USAGE2(HUP_CONSUMER, HUC_AC_PAN),
+				id,
+				hid_input,
+				zloc,
+				&flags);
+	}
+
+	if (hl) {
+		if ((flags & MOUSE_FLAGS_MASK) != HIO_RELATIVE) {
+			aprint_verbose("\n%s: Z report 0x%04x not supported\n",
+			       device_xname(self), flags);
+			zloc->size = 0;	/* Bad Z coord, ignore it */
+		} else {
+			if (ms->flags & HIDMS_Z)
+				ms->flags |= HIDMS_W;
+			else
+				ms->flags |= HIDMS_Z;
+		}
+	}
+
+	/* figure out the number of buttons */
+	for (i = 1; i <= MAX_BUTTONS; i++)
+		if (!hid_locate(desc, size, HID_USAGE2(HUP_BUTTON, i),
+		    id, hid_input, &ms->hidms_loc_btn[i - 1], 0))
+			break;
+
+	if (isdigitizer) {
+		ms->flags |= HIDMS_DIGITIZER;
+		for (size_t j = 0; j < __arraycount(digbut); j++) {
+			if (hid_locate(desc, size, HID_USAGE2(HUP_DIGITIZERS,
+			    digbut[j].feature), id, hid_input,
+			    &ms->hidms_loc_btn[i - 1], 0)) {
+				if (i <= MAX_BUTTONS) {
+					i++;
+					ms->flags |= digbut[j].flag;
+				} else
+					aprint_error_dev(self,
+					    "ran out of buttons\n");
+			}
+		}
+	}
+	ms->nbuttons = i - 1;
+	return true;
+}
+
+void
+hidms_attach(device_t self, struct hidms *ms,
+    const struct wsmouse_accessops *ops)
+{
+	struct wsmousedev_attach_args a;
+	aprint_normal(": %d button%s%s%s%s%s%s%s%s%s\n",
+	    ms->nbuttons, ms->nbuttons == 1 ? "" : "s",
+	    ms->flags & HIDMS_W ? ", W" : "",
+	    ms->flags & HIDMS_Z ? " and Z dir" : "",
+	    ms->flags & HIDMS_W ? "s" : "",
+	    ms->flags & HIDMS_DIGITIZER ? " digitizer"  : "",
+	    ms->flags & HIDMS_TIP_SWITCH ? ", tip" : "",
+	    ms->flags & HIDMS_SEC_TIP_SWITCH ? ", sec tip" : "",
+	    ms->flags & HIDMS_BARREL_SWITCH ? ", barrel" : "",
+	    ms->flags & HIDMS_ERASER ? ", eraser" : "");
+
+#ifdef HIDMS_DEBUG
+	DPRINTF(("hidms_attach: ms=%p\n", ms));
+	DPRINTF(("hidms_attach: X\t%d/%d\n",
+		 ms->hidms_loc_x.pos, ms->hidms_loc_x.size));
+	DPRINTF(("hidms_attach: Y\t%d/%d\n",
+		 ms->hidms_loc_y.pos, ms->hidms_loc_y.size));
+	if (ms->flags & HIDMS_Z)
+		DPRINTF(("hidms_attach: Z\t%d/%d\n",
+			 ms->hidms_loc_z.pos, ms->hidms_loc_z.size));
+	if (ms->flags & HIDMS_W)
+		DPRINTF(("hidms_attach: W\t%d/%d\n",
+			 ms->hidms_loc_w.pos, ms->hidms_loc_w.size));
+	for (i = 1; i <= ms->nbuttons; i++) {
+		DPRINTF(("hidms_attach: B%d\t%d/%d\n",
+			 i, ms->hidms_loc_btn[i-1].pos,ms->hidms_loc_btn[i-1].size));
+	}
+#endif
+
+	a.accessops = ops;
+	a.accesscookie = device_private(self);
+
+	ms->hidms_wsmousedev = config_found(self, &a, wsmousedevprint);
+
+	return;
+}
+
+
+void
+hidms_intr(struct hidms *ms, void *ibuf, u_int len)
+{
+	int dx, dy, dz, dw;
+	uint32_t buttons = 0;
+	int i, flags, s;
+
+	DPRINTFN(5,("hidms_intr: len=%d\n", len));
+
+	flags = WSMOUSE_INPUT_DELTA;	/* equals 0 */
+
+	dx =  hid_get_data(ibuf, &ms->hidms_loc_x);
+	if (ms->flags & HIDMS_ABS) {
+		flags |= (WSMOUSE_INPUT_ABSOLUTE_X | WSMOUSE_INPUT_ABSOLUTE_Y);
+		dy = hid_get_data(ibuf, &ms->hidms_loc_y);
+	} else
+		dy = -hid_get_data(ibuf, &ms->hidms_loc_y);
+	dz =  hid_get_data(ibuf, &ms->hidms_loc_z);
+	dw =  hid_get_data(ibuf, &ms->hidms_loc_w);
+
+	if (ms->flags & HIDMS_REVZ)
+		dz = -dz;
+	for (i = 0; i < ms->nbuttons; i++)
+		if (hid_get_data(ibuf, &ms->hidms_loc_btn[i]))
+			buttons |= (1 << HIDMS_BUT(i));
+
+	if (dx != 0 || dy != 0 || dz != 0 || dw != 0 ||
+	    buttons != ms->hidms_buttons) {
+		DPRINTFN(10, ("hidms_intr: x:%d y:%d z:%d w:%d buttons:0x%x\n",
+			dx, dy, dz, dw, buttons));
+		ms->hidms_buttons = buttons;
+		if (ms->hidms_wsmousedev != NULL) {
+			s = spltty();
+			wsmouse_input(ms->hidms_wsmousedev, buttons, dx, dy, dz,
+			    dw, flags);
+			splx(s);
+		}
+	}
+}
Index: src/sys/dev/hid/hidms.h
diff -u /dev/null src/sys/dev/hid/hidms.h:1.1
--- /dev/null	Sun Dec 10 17:03:08 2017
+++ src/sys/dev/hid/hidms.h	Sun Dec 10 17:03:07 2017
@@ -0,0 +1,63 @@
+/*	$NetBSD: hidms.h,v 1.1 2017/12/10 17:03:07 bouyer Exp $	*/
+
+/*
+ * Copyright (c) 1998, 2017 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Lennart Augustsson (lenn...@augustsson.net) at
+ * Carlstedt Research & Technology.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <dev/wscons/wsconsio.h>
+#include <dev/wscons/wsmousevar.h>
+
+#define MAX_BUTTONS	31	/* must not exceed size of sc_buttons */
+
+struct hidms {
+	struct hid_location hidms_loc_x, hidms_loc_y, hidms_loc_z, hidms_loc_w;
+	struct hid_location hidms_loc_btn[MAX_BUTTONS];
+
+	u_int flags;		/* device configuration */
+#define HIDMS_Z			0x001	/* z direction available */
+#define HIDMS_SPUR_BUT_UP	0x002	/* spurious button up events */
+#define HIDMS_REVZ		0x004	/* Z-axis is reversed */
+#define HIDMS_W			0x008	/* w direction/tilt available */
+#define HIDMS_ABS		0x010	/* absolute position, touchpanel */
+#define HIDMS_TIP_SWITCH  	0x020	/* digitizer tip switch */
+#define HIDMS_SEC_TIP_SWITCH 	0x040	/* digitizer secondary tip switch */
+#define HIDMS_BARREL_SWITCH 	0x080	/* digitizer barrel switch */
+#define HIDMS_ERASER 		0x100	/* digitizer eraser */
+#define HIDMS_DIGITIZER 	0x200	/* digitizer */
+
+	int nbuttons;
+
+	uint32_t hidms_buttons;	/* mouse button status */
+	device_t hidms_wsmousedev;
+};
+
+bool hidms_setup(device_t, struct hidms *, int, void *, int);
+void hidms_attach(device_t, struct hidms *, const struct wsmouse_accessops *);
+void hidms_intr(struct hidms *, void *, u_int);
+

Reply via email to