1 /* $NetBSD: dtkbd.c,v 1.7 2007/03/04 06:00:33 christos Exp $ */
4 * Copyright (c) 2002, 2003 The NetBSD Foundation, Inc.
7 * This code is derived from software contributed to The NetBSD Foundation
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
32 #include <sys/cdefs.h>
33 __KERNEL_RCSID(0, "$NetBSD: dtkbd.c,v 1.7 2007/03/04 06:00:33 christos Exp $");
37 #include <sys/param.h>
38 #include <sys/systm.h>
39 #include <sys/device.h>
40 #include <sys/ioctl.h>
41 #include <sys/callout.h>
43 #include <dev/wscons/wsconsio.h>
44 #include <dev/wscons/wskbdvar.h>
45 #include <dev/wscons/wsksymdef.h>
46 #include <dev/wscons/wsksymvar.h>
47 #include <dev/dec/wskbdmap_lk201.h>
48 #include <dev/tc/tcvar.h>
50 #include <machine/bus.h>
52 #include <pmax/tc/dtreg.h>
53 #include <pmax/tc/dtvar.h>
55 #include <pmax/pmax/cons.h>
59 struct device
*sc_wskbddev
;
63 int dtkbd_match(struct device
*, struct cfdata
*, void *);
64 void dtkbd_attach(struct device
*, struct device
*, void *);
65 int dtkbd_enable(void *, int);
66 int dtkbd_ioctl(void *, u_long
, void *, int, struct lwp
*);
67 void dtkbd_cngetc(void *, u_int
*, int *);
68 void dtkbd_cnpollc(void *, int);
69 int dtkbd_process_msg(struct dt_msg
*, u_int
*, int *);
70 void dtkbd_handler(void *, struct dt_msg
*);
71 void dtkbd_set_leds(void *, int);
73 const struct wskbd_accessops dtkbd_accessops
= {
79 const struct wskbd_consops dtkbd_consops
= {
84 CFATTACH_DECL(dtkbd
, sizeof(struct dtkbd_softc
),
85 dtkbd_match
, dtkbd_attach
, NULL
, NULL
);
87 const struct wskbd_mapdata dtkbd_keymapdata
= {
97 uint8_t dtkbd_map
[10];
101 dtkbd_match(struct device
*parent
, struct cfdata
*cf
, void *aux
)
103 struct dt_attach_args
*dta
;
106 return (dta
->dta_addr
== DT_ADDR_KBD
);
110 dtkbd_attach(struct device
*parent
, struct device
*self
, void *aux
)
113 struct dtkbd_softc
*sc
;
114 struct wskbddev_attach_args a
;
116 dt
= (struct dt_softc
*)parent
;
117 sc
= (struct dtkbd_softc
*)self
;
121 if (dt_establish_handler(dt
, &dt_kbd_dv
, self
, dtkbd_handler
)) {
122 printf("%s: unable to establish handler\n", self
->dv_xname
);
128 a
.console
= dtkbd_isconsole
;
129 a
.keymap
= &dtkbd_keymapdata
;
130 a
.accessops
= &dtkbd_accessops
;
132 sc
->sc_wskbddev
= config_found(self
, &a
, wskbddevprint
);
142 wskbd_cnattach(&dtkbd_consops
, &dtkbd_map
, &dtkbd_keymapdata
);
146 dtkbd_enable(void *v
, int on
)
148 struct dtkbd_softc
*sc
;
157 dtkbd_cngetc(void *v
, u_int
*type
, int *data
)
160 static u_int types
[20];
161 static int cnt
, i
, vals
[20];
165 if (dt_msg_get(&msg
, 0) == DT_GET_DONE
)
166 if (msg
.src
== dt_kbd_addr
&&
172 cnt
= dtkbd_process_msg(&msg
, types
, vals
);
181 dtkbd_cnpollc(void *v
, int on
)
188 dtkbd_ioctl(void *v
, u_long cmd
, void *data
, int flag
, struct lwp
*l
)
190 struct dtkbd_softc
*sc
;
192 sc
= (struct dtkbd_softc
*)v
;
196 *(int *)data
= WSKBD_TYPE_LK201
;
200 return (EPASSTHROUGH
);
205 dtkbd_set_leds(void *v
, int state
)
212 dtkbd_handler(void *cookie
, struct dt_msg
*msg
)
214 struct dtkbd_softc
*sc
;
216 int i
, cnt
, vals
[20];
223 cnt
= dtkbd_process_msg(msg
, types
, vals
);
224 for (i
= 0; i
< cnt
; i
++)
225 wskbd_input(sc
->sc_wskbddev
, types
[i
], vals
[i
]);
229 dtkbd_process_msg(struct dt_msg
*msg
, u_int
*types
, int *vals
)
234 len
= DT_CTL_LEN(msg
->ctl
);
236 if ((msg
->body
[0] < DT_KBD_KEY_MIN
&& msg
->body
[0] != DT_KBD_EMPTY
) ||
238 printf("dtkbd0: error: %x %x %x\n", len
, msg
->body
[0],
242 * Fake an "all ups" to avoid the stuck key syndrome.
244 msg
->body
[0] = DT_KBD_EMPTY
;
248 if (msg
->body
[0] == DT_KBD_EMPTY
) {
249 types
[0] = WSCONS_EVENT_ALL_KEYS_UP
;
257 for (i
= 0; i
< len
; i
++) {
260 for (j
= 0; j
< dtkbd_maplen
; j
++)
261 if (dtkbd_map
[j
] == c
)
264 if (j
== dtkbd_maplen
) {
265 types
[count
] = WSCONS_EVENT_KEY_DOWN
;
266 vals
[count
] = c
- MIN_LK201_KEY
;
271 for (j
= 0; j
< dtkbd_maplen
; j
++) {
274 for (i
= 0; i
< len
; i
++)
275 if (msg
->body
[i
] == c
)
279 types
[count
] = WSCONS_EVENT_KEY_UP
;
280 vals
[count
] = c
- MIN_LK201_KEY
;
285 memcpy(dtkbd_map
, msg
->body
, len
);