Module Name: src
Committed By: jmcneill
Date: Mon Dec 9 22:05:17 UTC 2024
Modified Files:
src/sys/dev/i2c: files.i2c
Added Files:
src/sys/dev/i2c: ikbd.c
Log Message:
Import ikbd(4) from OpenBSD.
To generate a diff of this commit:
cvs rdiff -u -r1.128 -r1.129 src/sys/dev/i2c/files.i2c
cvs rdiff -u -r0 -r1.1 src/sys/dev/i2c/ikbd.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/dev/i2c/files.i2c
diff -u src/sys/dev/i2c/files.i2c:1.128 src/sys/dev/i2c/files.i2c:1.129
--- src/sys/dev/i2c/files.i2c:1.128 Sun Dec 8 20:49:56 2024
+++ src/sys/dev/i2c/files.i2c Mon Dec 9 22:05:17 2024
@@ -1,4 +1,4 @@
-# $NetBSD: files.i2c,v 1.128 2024/12/08 20:49:56 jmcneill Exp $
+# $NetBSD: files.i2c,v 1.129 2024/12/09 22:05:17 jmcneill Exp $
obsolete defflag opt_i2cbus.h I2C_SCAN
define i2cbus { }
@@ -328,16 +328,21 @@ device ihidev: hid, ihidbus, gpio
attach ihidev at iic
file dev/i2c/ihidev.c ihidev
-#HID mice
+# HID mice
device ims: hid, hidms, wsmousedev
attach ims at ihidbus
file dev/i2c/ims.c ims
-#HID multitouch
+# HID multitouch
device imt: hid, hidmt, wsmousedev
attach imt at ihidbus
file dev/i2c/imt.c imt
+# HID keyboard
+device ikbd: hid, hidkbd, wskbddev
+attach ikbd at ihidbus
+file dev/i2c/ikbd.c ikbd
+
# Taos TSL256x ambient light sensor
device tsllux: sysmon_envsys
attach tsllux at iic
Added files:
Index: src/sys/dev/i2c/ikbd.c
diff -u /dev/null src/sys/dev/i2c/ikbd.c:1.1
--- /dev/null Mon Dec 9 22:05:17 2024
+++ src/sys/dev/i2c/ikbd.c Mon Dec 9 22:05:17 2024
@@ -0,0 +1,212 @@
+/* $NetBSD: ikbd.c,v 1.1 2024/12/09 22:05:17 jmcneill Exp $ */
+
+/* $OpenBSD: ikbd.c,v 1.2 2022/09/03 15:48:16 kettenis Exp $ */
+/*
+ * HID-over-i2c keyboard driver
+ *
+ * Copyright (c) 2016 Mark Kettenis <[email protected]>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/device.h>
+#include <sys/ioctl.h>
+
+#include <dev/i2c/i2cvar.h>
+#include <dev/i2c/ihidev.h>
+
+#include <dev/wscons/wsconsio.h>
+#include <dev/wscons/wskbdvar.h>
+#include <dev/wscons/wsksymdef.h>
+
+#include <dev/hid/hid.h>
+#include <dev/hid/hidkbdsc.h>
+
+extern const struct wscons_keydesc hidkbd_keydesctab[];
+static struct wskbd_mapdata ikbd_keymapdata = {
+ hidkbd_keydesctab,
+ KB_US,
+};
+
+struct ikbd_softc {
+ struct ihidev sc_hdev;
+ struct hidkbd sc_kbd;
+ int sc_spl;
+};
+
+void ikbd_intr(struct ihidev *addr, void *ibuf, u_int len);
+
+void ikbd_cngetc(void *, u_int *, int *);
+void ikbd_cnpollc(void *, int);
+
+const struct wskbd_consops ikbd_consops = {
+ .getc = ikbd_cngetc,
+ .pollc = ikbd_cnpollc,
+ .bell = NULL,
+};
+
+int ikbd_enable(void *, int);
+void ikbd_set_leds(void *, int);
+int ikbd_ioctl(void *, u_long, void *, int, lwp_t *);
+
+const struct wskbd_accessops ikbd_accessops = {
+ .enable = ikbd_enable,
+ .set_leds = ikbd_set_leds,
+ .ioctl = ikbd_ioctl,
+};
+
+int ikbd_match(device_t, cfdata_t, void *);
+void ikbd_attach(device_t, device_t, void *);
+int ikbd_detach(device_t, int);
+
+CFATTACH_DECL_NEW(ikbd, sizeof(struct ikbd_softc),
+ ikbd_match, ikbd_attach, ikbd_detach, NULL);
+
+int
+ikbd_match(device_t parent, cfdata_t match, void *aux)
+{
+ struct ihidev_attach_arg *iha = aux;
+ int size;
+ void *desc;
+
+ ihidev_get_report_desc(iha->parent, &desc, &size);
+ if (!hid_is_collection(desc, size, iha->reportid,
+ HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_KEYBOARD)))
+ return (IMATCH_NONE);
+
+ return (IMATCH_IFACECLASS);
+}
+
+void
+ikbd_attach(device_t parent, device_t self, void *aux)
+{
+ struct ikbd_softc *sc = device_private(self);
+ struct hidkbd *kbd = &sc->sc_kbd;
+ struct ihidev_attach_arg *iha = (struct ihidev_attach_arg *)aux;
+ int dlen, repid;
+ void *desc;
+
+ sc->sc_hdev.sc_idev = self;
+ sc->sc_hdev.sc_intr = ikbd_intr;
+ sc->sc_hdev.sc_parent = iha->parent;
+ sc->sc_hdev.sc_report_id = iha->reportid;
+
+ ihidev_get_report_desc(iha->parent, &desc, &dlen);
+ repid = iha->reportid;
+ sc->sc_hdev.sc_isize = hid_report_size(desc, dlen, hid_input, repid);
+ sc->sc_hdev.sc_osize = hid_report_size(desc, dlen, hid_output, repid);
+ sc->sc_hdev.sc_fsize = hid_report_size(desc, dlen, hid_feature, repid);
+
+ if (hidkbd_attach(self, kbd, 1, 0, repid, desc, dlen) != 0)
+ return;
+
+ aprint_naive("\n");
+ aprint_normal("\n");
+
+ if (kbd->sc_console_keyboard) {
+ wskbd_cnattach(&ikbd_consops, sc, &ikbd_keymapdata);
+ ikbd_enable(sc, 1);
+ }
+
+ hidkbd_attach_wskbd(kbd, KB_US, &ikbd_accessops);
+}
+
+int
+ikbd_detach(device_t self, int flags)
+{
+ struct ikbd_softc *sc = device_private(self);
+ struct hidkbd *kbd = &sc->sc_kbd;
+
+ return hidkbd_detach(kbd, flags);
+}
+
+void
+ikbd_intr(struct ihidev *addr, void *ibuf, u_int len)
+{
+ struct ikbd_softc *sc = (struct ikbd_softc *)addr;
+ struct hidkbd *kbd = &sc->sc_kbd;
+
+ if (kbd->sc_enabled != 0)
+ hidkbd_input(kbd, (uint8_t *)ibuf, len);
+}
+
+int
+ikbd_enable(void *v, int on)
+{
+ struct ikbd_softc *sc = v;
+ struct hidkbd *kbd = &sc->sc_kbd;
+ int rv;
+
+ if ((rv = hidkbd_enable(kbd, on)) != 0)
+ return rv;
+
+ if (on) {
+ return ihidev_open(&sc->sc_hdev);
+ } else {
+ ihidev_close(&sc->sc_hdev);
+ return 0;
+ }
+}
+
+void
+ikbd_set_leds(void *v, int leds)
+{
+}
+
+int
+ikbd_ioctl(void *v, u_long cmd, void *data, int flag, lwp_t *l)
+{
+ struct ikbd_softc *sc = v;
+ struct hidkbd *kbd = &sc->sc_kbd;
+
+ switch (cmd) {
+ case WSKBDIO_GTYPE:
+ /* XXX: should we set something else? */
+ *(u_int *)data = WSKBD_TYPE_USB;
+ return 0;
+ default:
+ return hidkbd_ioctl(kbd, cmd, data, flag, l);
+ }
+}
+
+/* Console interface. */
+void
+ikbd_cngetc(void *v, u_int *type, int *data)
+{
+ struct ikbd_softc *sc = v;
+ struct hidkbd *kbd = &sc->sc_kbd;
+
+ kbd->sc_polling = 1;
+#if notyet
+ while (kbd->sc_npollchar <= 0) {
+ ihidev_poll(sc->sc_hdev.sc_parent);
+ delay(1000);
+ }
+#endif
+ kbd->sc_polling = 0;
+ hidkbd_cngetc(kbd, type, data);
+}
+
+void
+ikbd_cnpollc(void *v, int on)
+{
+ struct ikbd_softc *sc = v;
+
+ if (on)
+ sc->sc_spl = spltty();
+ else
+ splx(sc->sc_spl);
+}