1*c7fb772bSthorpej /* $NetBSD: kb_hb.c,v 1.15 2021/08/07 16:19:00 thorpej Exp $ */
208f4daf2Stsutsui
3b87210faStsutsui /*-
4b87210faStsutsui * Copyright (c) 2001 Izumi Tsutsui. All rights reserved.
508f4daf2Stsutsui *
608f4daf2Stsutsui * Redistribution and use in source and binary forms, with or without
708f4daf2Stsutsui * modification, are permitted provided that the following conditions
808f4daf2Stsutsui * are met:
908f4daf2Stsutsui * 1. Redistributions of source code must retain the above copyright
1008f4daf2Stsutsui * notice, this list of conditions and the following disclaimer.
1108f4daf2Stsutsui * 2. Redistributions in binary form must reproduce the above copyright
1208f4daf2Stsutsui * notice, this list of conditions and the following disclaimer in the
1308f4daf2Stsutsui * documentation and/or other materials provided with the distribution.
1408f4daf2Stsutsui *
1508f4daf2Stsutsui * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
1608f4daf2Stsutsui * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
1708f4daf2Stsutsui * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
1808f4daf2Stsutsui * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
1908f4daf2Stsutsui * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
2008f4daf2Stsutsui * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2108f4daf2Stsutsui * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2208f4daf2Stsutsui * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23b87210faStsutsui * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24b87210faStsutsui * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2508f4daf2Stsutsui */
2608f4daf2Stsutsui
27ed517291Slukem #include <sys/cdefs.h>
28*c7fb772bSthorpej __KERNEL_RCSID(0, "$NetBSD: kb_hb.c,v 1.15 2021/08/07 16:19:00 thorpej Exp $");
29ed517291Slukem
3008f4daf2Stsutsui #include <sys/param.h>
3108f4daf2Stsutsui #include <sys/systm.h>
3208f4daf2Stsutsui #include <sys/device.h>
3308f4daf2Stsutsui
3408f4daf2Stsutsui #include <machine/bus.h>
3508f4daf2Stsutsui #include <machine/cpu.h>
3608f4daf2Stsutsui
3708f4daf2Stsutsui #include <dev/wscons/wsconsio.h>
3808f4daf2Stsutsui #include <dev/wscons/wskbdvar.h>
3908f4daf2Stsutsui #include <dev/wscons/wsksymdef.h>
4008f4daf2Stsutsui #include <dev/wscons/wsksymvar.h>
4108f4daf2Stsutsui
4208f4daf2Stsutsui #include <news68k/dev/hbvar.h>
4308f4daf2Stsutsui #include <news68k/dev/kb_hbreg.h>
4408f4daf2Stsutsui #include <news68k/dev/kbvar.h>
4508f4daf2Stsutsui
4608f4daf2Stsutsui #include <news68k/news68k/isr.h>
4708f4daf2Stsutsui
48378871cdStsutsui #include "ioconf.h"
49378871cdStsutsui
5008f4daf2Stsutsui #define KB_SIZE 0x10 /* XXX */
5108f4daf2Stsutsui #define KB_PRI 5
5208f4daf2Stsutsui
53820a544dStsutsui static int kb_hb_match(device_t, cfdata_t, void *);
54820a544dStsutsui static void kb_hb_attach(device_t, device_t, void *);
5552b46dcfStsutsui static void kb_hb_init(struct kb_softc *);
5608f4daf2Stsutsui int kb_hb_intr(void *);
5708f4daf2Stsutsui int kb_hb_cnattach(void);
5808f4daf2Stsutsui
59820a544dStsutsui CFATTACH_DECL_NEW(kb_hb, sizeof(struct kb_softc),
60021b694dSthorpej kb_hb_match, kb_hb_attach, NULL, NULL);
6108f4daf2Stsutsui
6208f4daf2Stsutsui struct console_softc kb_hb_conssc;
6308f4daf2Stsutsui
6452b46dcfStsutsui static int
kb_hb_match(device_t parent,cfdata_t cf,void * aux)65820a544dStsutsui kb_hb_match(device_t parent, cfdata_t cf, void *aux)
6608f4daf2Stsutsui {
6708f4daf2Stsutsui struct hb_attach_args *ha = aux;
6808f4daf2Stsutsui u_int addr;
6908f4daf2Stsutsui
7008f4daf2Stsutsui if (strcmp(ha->ha_name, "kb"))
7108f4daf2Stsutsui return 0;
7208f4daf2Stsutsui
7308f4daf2Stsutsui /* XXX no default address */
745db9bf06Stsutsui if (ha->ha_address == (u_int)-1)
7508f4daf2Stsutsui return 0;
7608f4daf2Stsutsui
77217e34e4Stsutsui addr = (ha->ha_address); /* XXX */
7808f4daf2Stsutsui
7908f4daf2Stsutsui if (badaddr((void *)addr, 1))
8008f4daf2Stsutsui return 0;
8108f4daf2Stsutsui
8208f4daf2Stsutsui return 1;
8308f4daf2Stsutsui }
8408f4daf2Stsutsui
8552b46dcfStsutsui static void
kb_hb_attach(device_t parent,device_t self,void * aux)86820a544dStsutsui kb_hb_attach(device_t parent, device_t self, void *aux)
8708f4daf2Stsutsui {
88820a544dStsutsui struct kb_softc *sc = device_private(self);
8908f4daf2Stsutsui struct hb_attach_args *ha = aux;
9008f4daf2Stsutsui bus_space_tag_t bt = ha->ha_bust;
9108f4daf2Stsutsui bus_space_handle_t bh;
9208f4daf2Stsutsui struct wskbddev_attach_args wsa;
9308f4daf2Stsutsui int ipl;
9408f4daf2Stsutsui
95d062717cStsutsui sc->sc_dev = self;
96d062717cStsutsui
9708f4daf2Stsutsui if (bus_space_map(bt, ha->ha_address, KB_SIZE, 0, &bh) != 0) {
98820a544dStsutsui aprint_error(": can't map device space\n");
9908f4daf2Stsutsui return;
10008f4daf2Stsutsui }
10108f4daf2Stsutsui
102820a544dStsutsui aprint_normal("\n");
10308f4daf2Stsutsui
10408f4daf2Stsutsui sc->sc_bt = bt;
10508f4daf2Stsutsui sc->sc_bh = bh;
10608f4daf2Stsutsui sc->sc_offset = KB_REG_DATA;
10708f4daf2Stsutsui sc->sc_conssc = &kb_hb_conssc;
10808f4daf2Stsutsui
10908f4daf2Stsutsui ipl = ha->ha_ipl;
11008f4daf2Stsutsui if (ipl == -1)
11108f4daf2Stsutsui ipl = KB_PRI;
11208f4daf2Stsutsui
11308f4daf2Stsutsui kb_hb_init(sc);
11408f4daf2Stsutsui
1157d0e6302Stsutsui isrlink_autovec(kb_hb_intr, (void *)sc, ipl, IPL_TTY);
11608f4daf2Stsutsui
11708f4daf2Stsutsui wsa.console = kb_hb_conssc.cs_isconsole;
11808f4daf2Stsutsui wsa.keymap = &kb_keymapdata;
11908f4daf2Stsutsui wsa.accessops = &kb_accessops;
12008f4daf2Stsutsui wsa.accesscookie = sc;
12108f4daf2Stsutsui
122*c7fb772bSthorpej sc->sc_wskbddev = config_found(self, &wsa, wskbddevprint, CFARGS_NONE);
12308f4daf2Stsutsui }
12408f4daf2Stsutsui
12552b46dcfStsutsui static void
kb_hb_init(struct kb_softc * sc)12652b46dcfStsutsui kb_hb_init(struct kb_softc *sc)
12708f4daf2Stsutsui {
12808f4daf2Stsutsui bus_space_tag_t bt = sc->sc_bt;
12908f4daf2Stsutsui bus_space_handle_t bh = sc->sc_bh;
13008f4daf2Stsutsui
13108f4daf2Stsutsui bus_space_write_1(bt, bh, KB_REG_RESET, 0);
13208f4daf2Stsutsui bus_space_write_1(bt, bh, KB_REG_INTE, KB_INTE);
13308f4daf2Stsutsui }
13408f4daf2Stsutsui
13508f4daf2Stsutsui int
kb_hb_intr(void * arg)13652b46dcfStsutsui kb_hb_intr(void *arg)
13708f4daf2Stsutsui {
13808f4daf2Stsutsui struct kb_softc *sc = (struct kb_softc *)arg;
13908f4daf2Stsutsui struct console_softc *kb_conssc = sc->sc_conssc;
14008f4daf2Stsutsui bus_space_tag_t bt = sc->sc_bt;
14108f4daf2Stsutsui bus_space_handle_t bh = sc->sc_bh;
14208f4daf2Stsutsui int stat, handled = 0;
14308f4daf2Stsutsui
14408f4daf2Stsutsui kb_conssc->cs_nintr++;
14508f4daf2Stsutsui
14608f4daf2Stsutsui stat = bus_space_read_1(bt, bh, KB_REG_STAT);
14708f4daf2Stsutsui if (stat & KBSTAT_RDY) {
14808f4daf2Stsutsui kb_intr(sc);
14908f4daf2Stsutsui handled = 1;
15008f4daf2Stsutsui bus_space_write_1(bt, bh, KB_REG_INTE, KB_INTE);
15108f4daf2Stsutsui }
15208f4daf2Stsutsui
15308f4daf2Stsutsui return handled;
15408f4daf2Stsutsui }
15508f4daf2Stsutsui
15608f4daf2Stsutsui int
kb_hb_cnattach(void)15752b46dcfStsutsui kb_hb_cnattach(void)
15808f4daf2Stsutsui {
15908f4daf2Stsutsui
16008f4daf2Stsutsui kb_hb_conssc.cs_isconsole = 1;
16108f4daf2Stsutsui return kb_cnattach(&kb_hb_conssc);
16208f4daf2Stsutsui }
163