kb_ap.c revision 1.12
1/* $NetBSD: kb_ap.c,v 1.12 2018/10/14 00:10:11 tsutsui Exp $ */ 2 3/*- 4 * Copyright (c) 2000 Tsubai Masanari. All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 3. The name of the author may not be used to endorse or promote products 15 * derived from this software without specific prior written permission. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29#include <sys/cdefs.h> 30__KERNEL_RCSID(0, "$NetBSD: kb_ap.c,v 1.12 2018/10/14 00:10:11 tsutsui Exp $"); 31 32#include <sys/param.h> 33#include <sys/systm.h> 34#include <sys/device.h> 35 36#include <dev/wscons/wsconsio.h> 37#include <dev/wscons/wskbdvar.h> 38#include <dev/wscons/wsksymdef.h> 39 40#include <machine/adrsmap.h> 41#include <machine/cpu.h> 42#include <newsmips/apbus/apbusvar.h> 43 44struct kbreg { 45 volatile uint32_t kb_rx_data; 46 volatile uint32_t kb_rx_stat; 47 volatile uint32_t kb_rx_intr_en; 48 volatile uint32_t kb_rx_reset; 49 volatile uint32_t kb_rx_speed; 50 51 volatile uint32_t ms_rx_data; 52 volatile uint32_t ms_rx_stat; 53 volatile uint32_t ms_rx_intr_en; 54 volatile uint32_t ms_rx_reset; 55 volatile uint32_t ms_rx_speed; 56 57 volatile uint32_t kb_buzzf; 58 volatile uint32_t kb_buzz; 59 60 volatile uint32_t kb_tx_data; 61 volatile uint32_t kb_tx_stat; 62 volatile uint32_t kb_tx_intr_en; 63 volatile uint32_t kb_tx_reset; 64 volatile uint32_t kb_tx_speed; 65}; 66 67struct kb_ap_softc { 68 device_t sc_dev; 69 struct kbreg *sc_reg; 70 device_t sc_wskbddev; 71}; 72 73int kb_ap_match(device_t, cfdata_t, void *); 74void kb_ap_attach(device_t, device_t, void *); 75int kb_ap_intr(void *); 76 77void kb_ap_cnattach(void); 78void kb_ap_cngetc(void *, u_int *, int *); 79void kb_ap_cnpollc(void *, int); 80 81int kb_ap_enable(void *, int); 82void kb_ap_setleds(void *, int); 83int kb_ap_ioctl(void *, u_long, void *, int, struct lwp *); 84 85extern struct wscons_keydesc newskb_keydesctab[]; 86 87CFATTACH_DECL_NEW(kb_ap, sizeof(struct kb_ap_softc), 88 kb_ap_match, kb_ap_attach, NULL, NULL); 89 90struct wskbd_accessops kb_ap_accessops = { 91 kb_ap_enable, 92 kb_ap_setleds, 93 kb_ap_ioctl, 94}; 95 96struct wskbd_consops kb_ap_consops = { 97 kb_ap_cngetc, 98 kb_ap_cnpollc, 99}; 100 101struct wskbd_mapdata kb_ap_keymapdata = { 102 newskb_keydesctab, 103 KB_JP, 104}; 105 106int 107kb_ap_match(device_t parent, cfdata_t cf, void *aux) 108{ 109 struct apbus_attach_args *apa = aux; 110 111 if (strcmp(apa->apa_name, "kb") == 0) 112 return 1; 113 114 return 0; 115} 116 117void 118kb_ap_attach(device_t parent, device_t self, void *aux) 119{ 120 struct kb_ap_softc *sc = device_private(self); 121 struct apbus_attach_args *apa = aux; 122 struct kbreg *reg = (void *)apa->apa_hwbase; 123 volatile uint32_t *dipsw = (void *)NEWS5000_DIP_SWITCH; 124 struct wskbddev_attach_args waa; 125 int cons = 0; 126 127 sc->sc_dev = self; 128 aprint_normal(" slot%d addr 0x%lx", apa->apa_slotno, apa->apa_hwbase); 129 130 sc->sc_reg = reg; 131 132 if (systype == NEWS5000 && *dipsw & 7) { 133 aprint_normal(" (console)"); 134 cons = 1; 135 } 136 aprint_normal("\n"); 137 138 reg->kb_rx_reset = 0x03; 139 reg->kb_tx_reset = 0x03; 140 141 reg->kb_rx_speed = 0x04; 142 reg->kb_tx_speed = 0x04; 143 144 reg->kb_rx_intr_en = 1; 145 reg->kb_tx_intr_en = 0; 146 147 apbus_intr_establish(1, NEWS5000_INT1_KBD, 0, kb_ap_intr, sc, 148 device_xname(self), apa->apa_ctlnum); 149 150 waa.console = cons; 151 waa.keymap = &kb_ap_keymapdata; 152 waa.accessops = &kb_ap_accessops; 153 waa.accesscookie = sc; 154 155 sc->sc_wskbddev = config_found(self, &waa, wskbddevprint); 156} 157 158int 159kb_ap_intr(void *v) 160{ 161 struct kb_ap_softc *sc = v; 162 struct kbreg *reg = sc->sc_reg; 163 int key, val, type, release; 164 int rv = 0; 165 166 while (reg->kb_rx_stat & RX_KBRDY) { 167 key = reg->kb_rx_data; 168 val = key & 0x7f; 169 release = key & 0x80; 170 type = release ? WSCONS_EVENT_KEY_UP : WSCONS_EVENT_KEY_DOWN; 171 172 if (sc->sc_wskbddev) 173 wskbd_input(sc->sc_wskbddev, type, val); 174 175 rv = 1; 176 } 177 178 return rv; 179} 180 181void 182kb_ap_cnattach(void) 183{ 184 185 wskbd_cnattach(&kb_ap_consops, (void *)0xbf900000, &kb_ap_keymapdata); 186} 187 188void 189kb_ap_cngetc(void *v, u_int *type, int *data) 190{ 191 struct kbreg *reg = v; 192 int key, release, ointr; 193 194 /* Disable keyboard interrupt. */ 195 ointr = reg->kb_rx_intr_en; 196 reg->kb_rx_intr_en = 0; 197 198 /* Wait for key data. */ 199 while ((reg->kb_rx_stat & RX_KBRDY) == 0) 200 ; 201 202 key = reg->kb_rx_data; 203 release = key & 0x80; 204 *data = key & 0x7f; 205 *type = release ? WSCONS_EVENT_KEY_UP : WSCONS_EVENT_KEY_DOWN; 206 207 reg->kb_rx_intr_en = ointr; 208} 209 210void 211kb_ap_cnpollc(void *v, int on) 212{ 213} 214 215int 216kb_ap_enable(void *v, int on) 217{ 218 219 return 0; 220} 221 222void 223kb_ap_setleds(void *v, int on) 224{ 225} 226 227int 228kb_ap_ioctl(void *v, u_long cmd, void *data, int flag, struct lwp *l) 229{ 230 231 switch (cmd) { 232 case WSKBDIO_GTYPE: 233 *(int *)data = 0; /* XXX */ 234 return 0; 235 case WSKBDIO_SETLEDS: 236 return 0; 237 case WSKBDIO_GETLEDS: 238 *(int *)data = 0; 239 return 0; 240 } 241 242 return EPASSTHROUGH; 243} 244