Allow ikbd(4) to become the console keyboard.
authorkettenis <kettenis@openbsd.org>
Sat, 3 Sep 2022 15:48:16 +0000 (15:48 +0000)
committerkettenis <kettenis@openbsd.org>
Sat, 3 Sep 2022 15:48:16 +0000 (15:48 +0000)
ok miod@

sys/dev/i2c/ihidev.h
sys/dev/i2c/ikbd.c

index 0404be6..cb87da7 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: ihidev.h,v 1.8 2020/07/09 21:01:56 jcs Exp $ */
+/* $OpenBSD: ihidev.h,v 1.9 2022/09/03 15:48:16 kettenis Exp $ */
 /*
  * HID-over-i2c driver
  *
@@ -135,3 +135,5 @@ int ihidev_ioctl(struct ihidev *, u_long, caddr_t, int, struct proc *);
 int ihidev_report_type_conv(int);
 int ihidev_set_report(struct device *, int, int, void *, int);
 int ihidev_get_report(struct device *, int, int, void *, int);
+
+void ihidev_poll(void *);
index 7c95b03..e1e4bf8 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: ikbd.c,v 1.1 2016/01/14 21:01:49 kettenis Exp $       */
+/*     $OpenBSD: ikbd.c,v 1.2 2022/09/03 15:48:16 kettenis Exp $       */
 /*
  * HID-over-i2c keyboard driver
  *
 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);
+void   ikbd_cnbell(void *, u_int, u_int, u_int);
+
+const struct wskbd_consops ikbd_consops = {
+       ikbd_cngetc,
+       ikbd_cnpollc,
+       ikbd_cnbell,
+};
+
 int    ikbd_enable(void *, int);
 void   ikbd_set_leds(void *, int);
 int    ikbd_ioctl(void *, u_long, caddr_t, int, struct proc *);
@@ -100,11 +111,19 @@ ikbd_attach(struct device *parent, struct device *self, void *aux)
        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, 0, 0, repid, desc, dlen) != 0)
+       if (hidkbd_attach(self, kbd, 1, 0, repid, desc, dlen) != 0)
                return;
 
        printf("\n");
 
+       if (kbd->sc_console_keyboard) {
+               extern struct wskbd_mapdata ukbd_keymapdata;
+
+               ukbd_keymapdata.layout = KB_US | KB_DEFAULT;
+               wskbd_cnattach(&ikbd_consops, sc, &ukbd_keymapdata);
+               ikbd_enable(sc, 1);
+       }
+
        hidkbd_attach_wskbd(kbd, KB_US | KB_DEFAULT, &ikbd_accessops);
 }
 
@@ -170,3 +189,36 @@ ikbd_ioctl(void *v, u_long cmd, caddr_t data, int flag, struct proc *p)
                        return hidkbd_ioctl(kbd, cmd, data, flag, p);
        }
 }
+
+/* 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;
+       while (kbd->sc_npollchar <= 0) {
+               ihidev_poll(sc->sc_hdev.sc_parent);
+               delay(1000);
+       }
+       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);
+}
+
+void
+ikbd_cnbell(void *v, u_int pitch, u_int period, u_int volume)
+{
+       hidkbd_bell(pitch, period, volume, 1);
+}