1 /* $NetBSD: dzkbd.c,v 1.22 2009/05/12 12:11:54 cegger Exp $ */
4 * Copyright (c) 1992, 1993
5 * The Regents of the University of California. All rights reserved.
7 * This software was developed by the Computer Systems Engineering group
8 * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
9 * contributed to Berkeley.
11 * All advertising materials mentioning features or use of this software
12 * must display the following acknowledgement:
13 * This product includes software developed by the University of
14 * California, Lawrence Berkeley Laboratory.
16 * Redistribution and use in source and binary forms, with or without
17 * modification, are permitted provided that the following conditions
19 * 1. Redistributions of source code must retain the above copyright
20 * notice, this list of conditions and the following disclaimer.
21 * 2. Redistributions in binary form must reproduce the above copyright
22 * notice, this list of conditions and the following disclaimer in the
23 * documentation and/or other materials provided with the distribution.
24 * 3. Neither the name of the University nor the names of its contributors
25 * may be used to endorse or promote products derived from this software
26 * without specific prior written permission.
28 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
29 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
30 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
31 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
32 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
33 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
34 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
35 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
36 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
37 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
40 * @(#)kbd.c 8.2 (Berkeley) 10/30/93
44 * LK200/LK400 keyboard attached to line 0 of the DZ*-11
47 #include <sys/cdefs.h>
48 __KERNEL_RCSID(0, "$NetBSD: dzkbd.c,v 1.22 2009/05/12 12:11:54 cegger Exp $");
50 #include <sys/param.h>
51 #include <sys/systm.h>
52 #include <sys/device.h>
53 #include <sys/ioctl.h>
54 #include <sys/syslog.h>
55 #include <sys/malloc.h>
58 #include <dev/wscons/wsconsio.h>
59 #include <dev/wscons/wskbdvar.h>
60 #include <dev/wscons/wsksymdef.h>
61 #include <dev/wscons/wsksymvar.h>
62 #include <dev/dec/wskbdmap_lk201.h>
66 #include <dev/dec/dzreg.h>
67 #include <dev/dec/dzvar.h>
68 #include <dev/dec/dzkbdvar.h>
69 #include <dev/dec/lk201reg.h>
70 #include <dev/dec/lk201var.h>
74 struct dzkbd_internal
{
75 struct dz_linestate
*dzi_ls
;
76 struct lk201_state dzi_ks
;
79 struct dzkbd_internal dzkbd_console_internal
;
82 struct device dzkbd_dev
; /* required first: base device */
84 struct dzkbd_internal
*sc_itl
;
92 static int dzkbd_input(void *, int);
94 static int dzkbd_match(device_t
, cfdata_t
, void *);
95 static void dzkbd_attach(device_t
, device_t
, void *);
97 CFATTACH_DECL(dzkbd
, sizeof(struct dzkbd_softc
),
98 dzkbd_match
, dzkbd_attach
, NULL
, NULL
);
100 static int dzkbd_enable(void *, int);
101 static void dzkbd_set_leds(void *, int);
102 static int dzkbd_ioctl(void *, u_long
, void *, int, struct lwp
*);
104 const struct wskbd_accessops dzkbd_accessops
= {
110 static void dzkbd_cngetc(void *, u_int
*, int *);
111 static void dzkbd_cnpollc(void *, int);
113 const struct wskbd_consops dzkbd_consops
= {
118 static int dzkbd_sendchar(void *, u_char
);
120 const struct wskbd_mapdata dzkbd_keymapdata
= {
130 * kbd_match: how is this dz line configured?
133 dzkbd_match(device_t parent
, cfdata_t cf
, void *aux
)
135 struct dzkm_attach_args
*daa
= aux
;
137 /* Exact match is better than wildcard. */
138 if (cf
->cf_loc
[DZCF_LINE
] == daa
->daa_line
)
141 /* This driver accepts wildcard. */
142 if (cf
->cf_loc
[DZCF_LINE
] == DZCF_LINE_DEFAULT
)
149 dzkbd_attach(device_t parent
, device_t self
, void *aux
)
151 struct dz_softc
*dz
= device_private(parent
);
152 struct dzkbd_softc
*dzkbd
= device_private(self
);
153 struct dzkm_attach_args
*daa
= aux
;
154 struct dz_linestate
*ls
;
155 struct dzkbd_internal
*dzi
;
156 struct wskbddev_attach_args a
;
159 dz
->sc_dz
[daa
->daa_line
].dz_catch
= dzkbd_input
;
160 dz
->sc_dz
[daa
->daa_line
].dz_private
= dzkbd
;
161 ls
= &dz
->sc_dz
[daa
->daa_line
];
163 isconsole
= (daa
->daa_flags
& DZKBD_CONSOLE
);
166 dzi
= &dzkbd_console_internal
;
168 dzi
= malloc(sizeof(struct dzkbd_internal
),
170 dzi
->dzi_ks
.attmt
.sendchar
= dzkbd_sendchar
;
171 dzi
->dzi_ks
.attmt
.cookie
= ls
;
180 lk201_init(&dzi
->dzi_ks
);
183 /* XXX should identify keyboard ID here XXX */
184 /* XXX layout and the number of LED is varying XXX */
186 dzkbd
->kbd_type
= WSKBD_TYPE_LK201
;
188 dzkbd
->sc_enabled
= 1;
190 a
.console
= isconsole
;
191 a
.keymap
= &dzkbd_keymapdata
;
192 a
.accessops
= &dzkbd_accessops
;
193 a
.accesscookie
= dzkbd
;
195 dzkbd
->sc_wskbddev
= config_found(self
, &a
, wskbddevprint
);
199 dzkbd_cnattach(struct dz_linestate
*ls
)
202 dzkbd_console_internal
.dzi_ks
.attmt
.sendchar
= dzkbd_sendchar
;
203 dzkbd_console_internal
.dzi_ks
.attmt
.cookie
= ls
;
204 lk201_init(&dzkbd_console_internal
.dzi_ks
);
205 dzkbd_console_internal
.dzi_ls
= ls
;
207 wskbd_cnattach(&dzkbd_consops
, &dzkbd_console_internal
,
214 dzkbd_enable(void *v
, int on
)
216 struct dzkbd_softc
*sc
= v
;
223 dzkbd_sendchar(void *v
, u_char c
)
225 struct dz_linestate
*ls
= v
;
235 dzkbd_cngetc(void *v
, u_int
*type
, int *data
)
237 struct dzkbd_internal
*dzi
= v
;
241 c
= dzgetc(dzi
->dzi_ls
);
242 } while (!lk201_decode(&dzi
->dzi_ks
, c
, type
, data
));
246 dzkbd_cnpollc(void *v
, int on
)
249 struct dzkbd_internal
*dzi
= v
;
254 dzkbd_set_leds(void *v
, int leds
)
256 struct dzkbd_softc
*sc
= (struct dzkbd_softc
*)v
;
258 //printf("dzkbd_set_leds\n");
259 lk201_set_leds(&sc
->sc_itl
->dzi_ks
, leds
);
263 dzkbd_ioctl(void *v
, u_long cmd
, void *data
, int flag
, struct lwp
*l
)
265 struct dzkbd_softc
*sc
= (struct dzkbd_softc
*)v
;
269 *(int *)data
= sc
->kbd_type
;
271 case WSKBDIO_SETLEDS
:
272 lk201_set_leds(&sc
->sc_itl
->dzi_ks
, *(int *)data
);
274 case WSKBDIO_GETLEDS
:
275 /* XXX don't dig in kbd internals */
276 *(int *)data
= sc
->sc_itl
->dzi_ks
.leds_state
;
278 case WSKBDIO_COMPLEXBELL
:
279 lk201_bell(&sc
->sc_itl
->dzi_ks
,
280 (struct wskbd_bell_data
*)data
);
282 case WSKBDIO_SETKEYCLICK
:
283 lk201_set_keyclick(&sc
->sc_itl
->dzi_ks
, *(int *)data
);
285 case WSKBDIO_GETKEYCLICK
:
286 /* XXX don't dig in kbd internals */
287 *(int *)data
= sc
->sc_itl
->dzi_ks
.kcvol
;
290 return (EPASSTHROUGH
);
294 dzkbd_input(void *v
, int data
)
296 struct dzkbd_softc
*sc
= (struct dzkbd_softc
*)v
;
300 if (sc
->sc_enabled
== 0)
303 if (lk201_decode(&sc
->sc_itl
->dzi_ks
, data
, &type
, &val
))
304 wskbd_input(sc
->sc_wskbddev
, type
, val
);