kb_hb.c revision 1.5
1/* $NetBSD: kb_hb.c,v 1.5 2003/05/09 13:36:40 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/param.h> 30#include <sys/device.h> 31#include <sys/systm.h> 32 33#include <dev/wscons/wsconsio.h> 34#include <dev/wscons/wskbdvar.h> 35#include <dev/wscons/wsksymdef.h> 36#include <dev/wscons/wsksymvar.h> 37 38#include <machine/adrsmap.h> 39 40#include <newsmips/dev/hbvar.h> 41 42struct kbreg { 43 u_char kb_data; 44 u_char kb_stat; 45 u_char kb_reset; 46 u_char kb_init; 47}; 48 49struct kb_hb_softc { 50 struct device sc_dev; 51 volatile struct kbreg *sc_reg; 52 struct device *sc_wskbddev; 53}; 54 55int kb_hb_match(struct device *, struct cfdata *, void *); 56void kb_hb_attach(struct device *, struct device *, void *); 57int kb_hb_intr(void *); 58 59void kb_hb_cnattach(void); 60void kb_hb_cngetc(void *, u_int *, int *); 61void kb_hb_cnpollc(void *, int); 62 63int kb_hb_enable(void *, int); 64void kb_hb_setleds(void *, int); 65int kb_hb_ioctl(void *, u_long, caddr_t, int, struct proc *); 66 67extern struct wscons_keydesc newskb_keydesctab[]; 68 69CFATTACH_DECL(kb_hb, sizeof(struct kb_hb_softc), 70 kb_hb_match, kb_hb_attach, NULL, NULL); 71 72struct wskbd_accessops kb_hb_accessops = { 73 kb_hb_enable, 74 kb_hb_setleds, 75 kb_hb_ioctl 76}; 77 78struct wskbd_consops kb_hb_consops = { 79 kb_hb_cngetc, 80 kb_hb_cnpollc 81}; 82 83struct wskbd_mapdata kb_hb_keymapdata = { 84 newskb_keydesctab, 85 KB_JP 86}; 87 88int 89kb_hb_match(parent, cf, aux) 90 struct device *parent; 91 struct cfdata *cf; 92 void *aux; 93{ 94 struct hb_attach_args *ha = aux; 95 96 if (strcmp(ha->ha_name, "kb") == 0) 97 return 1; 98 99 return 0; 100} 101 102void 103kb_hb_attach(parent, self, aux) 104 struct device *parent, *self; 105 void *aux; 106{ 107 struct kb_hb_softc *sc = (void *)self; 108 struct hb_attach_args *ha = aux; 109 volatile struct kbreg *reg; 110 volatile int *dipsw = (void *)DIP_SWITCH; 111 struct wskbddev_attach_args aa; 112 int intr, cons; 113 114 reg = (struct kbreg *)ha->ha_addr; 115 intr = ha->ha_level; 116 117 if (intr == -1) 118 intr = 2; 119 120 sc->sc_reg = reg; 121 reg->kb_reset = 0x01; 122 reg->kb_init = 0xf0; /* 9600 bps */ 123 124 printf(" level %d", intr); 125 cons = 0; 126 if (*dipsw & 7) { 127 cons = 1; 128 printf(" (console)"); 129 } 130 printf("\n"); 131 132 hb_intr_establish(intr, IPL_TTY, kb_hb_intr, sc); 133 134 aa.console = cons; 135 aa.keymap = &kb_hb_keymapdata; 136 aa.accessops = &kb_hb_accessops; 137 aa.accesscookie = sc; 138 sc->sc_wskbddev = config_found(self, &aa, wskbddevprint); 139} 140 141int 142kb_hb_intr(v) 143 void *v; 144{ 145 struct kb_hb_softc *sc = v; 146 volatile struct kbreg *reg = sc->sc_reg; 147 volatile u_char *ien = (void *)INTEN0; 148 int code, type, release, val; 149 int rv = 0; 150 151 *ien &= ~RX_KBINTE; 152 153 while (reg->kb_stat & RX_KBRDY) { 154 code = reg->kb_data; 155 release = code & 0x80; 156 val = code & 0x7f; 157 type = release ? WSCONS_EVENT_KEY_UP : WSCONS_EVENT_KEY_DOWN; 158 if (sc->sc_wskbddev) 159 wskbd_input(sc->sc_wskbddev, type, val); 160 rv = 1; 161 } 162 163 *ien |= RX_KBINTE; 164 return rv; 165} 166 167void 168kb_hb_cnattach() 169{ 170 volatile int *dipsw = (void *)DIP_SWITCH; 171 volatile struct kbreg *reg = (void *)KEYB_DATA; 172 173 if (*dipsw & 7) 174 wskbd_cnattach(&kb_hb_consops, (void *)reg, &kb_hb_keymapdata); 175} 176 177void 178kb_hb_cngetc(v, type, data) 179 void *v; 180 u_int *type; 181 int *data; 182{ 183 volatile struct kbreg *reg = v; 184 volatile u_char *ien = (void *)INTEN0; 185 int code, release, ointr; 186 187 ointr = *ien & RX_KBINTE; 188 *ien &= ~RX_KBINTE; 189 190 /* Wait for key data. */ 191 while ((reg->kb_stat & RX_KBRDY) == 0); 192 193 code = reg->kb_data; 194 release = code & 0x80; 195 *data = code & 0x7f; 196 *type = release ? WSCONS_EVENT_KEY_UP : WSCONS_EVENT_KEY_DOWN; 197 198 *ien |= ointr; 199} 200 201void 202kb_hb_cnpollc(v, on) 203 void *v; 204 int on; 205{ 206} 207 208int 209kb_hb_enable(v, on) 210 void *v; 211 int on; 212{ 213 return 0; 214} 215 216void 217kb_hb_setleds(v, on) 218 void *v; 219 int on; 220{ 221} 222 223int 224kb_hb_ioctl(v, cmd, data, flag, p) 225 void *v; 226 u_long cmd; 227 caddr_t data; 228 int flag; 229 struct proc *p; 230{ 231 switch (cmd) { 232 233 case WSKBDIO_GTYPE: 234 *(int *)data = 0; /* XXX */ 235 return 0; 236 case WSKBDIO_SETLEDS: 237 return 0; 238 case WSKBDIO_GETLEDS: 239 *(int *)data = 0; 240 return 0; 241 } 242 243 return EPASSTHROUGH; 244} 245