akbd.c revision 1.12.8.2 1 1.12.8.2 nathanw /* $NetBSD: akbd.c,v 1.12.8.2 2002/04/01 07:40:48 nathanw Exp $ */
2 1.12.8.2 nathanw
3 1.12.8.2 nathanw /*
4 1.12.8.2 nathanw * Copyright (C) 1998 Colin Wood
5 1.12.8.2 nathanw * All rights reserved.
6 1.12.8.2 nathanw *
7 1.12.8.2 nathanw * Redistribution and use in source and binary forms, with or without
8 1.12.8.2 nathanw * modification, are permitted provided that the following conditions
9 1.12.8.2 nathanw * are met:
10 1.12.8.2 nathanw * 1. Redistributions of source code must retain the above copyright
11 1.12.8.2 nathanw * notice, this list of conditions and the following disclaimer.
12 1.12.8.2 nathanw * 2. Redistributions in binary form must reproduce the above copyright
13 1.12.8.2 nathanw * notice, this list of conditions and the following disclaimer in the
14 1.12.8.2 nathanw * documentation and/or other materials provided with the distribution.
15 1.12.8.2 nathanw * 3. All advertising materials mentioning features or use of this software
16 1.12.8.2 nathanw * must display the following acknowledgement:
17 1.12.8.2 nathanw * This product includes software developed by Colin Wood.
18 1.12.8.2 nathanw * 4. The name of the author may not be used to endorse or promote products
19 1.12.8.2 nathanw * derived from this software without specific prior written permission.
20 1.12.8.2 nathanw *
21 1.12.8.2 nathanw * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
22 1.12.8.2 nathanw * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
23 1.12.8.2 nathanw * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
24 1.12.8.2 nathanw * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
25 1.12.8.2 nathanw * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
26 1.12.8.2 nathanw * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 1.12.8.2 nathanw * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 1.12.8.2 nathanw * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 1.12.8.2 nathanw * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 1.12.8.2 nathanw * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 1.12.8.2 nathanw */
32 1.12.8.2 nathanw
33 1.12.8.2 nathanw #include "opt_adb.h"
34 1.12.8.2 nathanw
35 1.12.8.2 nathanw #include <sys/param.h>
36 1.12.8.2 nathanw #include <sys/device.h>
37 1.12.8.2 nathanw #include <sys/fcntl.h>
38 1.12.8.2 nathanw #include <sys/poll.h>
39 1.12.8.2 nathanw #include <sys/select.h>
40 1.12.8.2 nathanw #include <sys/proc.h>
41 1.12.8.2 nathanw #include <sys/signalvar.h>
42 1.12.8.2 nathanw #include <sys/systm.h>
43 1.12.8.2 nathanw #include <sys/kernel.h>
44 1.12.8.2 nathanw
45 1.12.8.2 nathanw #include "aed.h"
46 1.12.8.2 nathanw #include "wskbd.h"
47 1.12.8.2 nathanw
48 1.12.8.2 nathanw #include <dev/wscons/wsconsio.h>
49 1.12.8.2 nathanw #include <dev/wscons/wskbdvar.h>
50 1.12.8.2 nathanw #include <dev/wscons/wsksymdef.h>
51 1.12.8.2 nathanw #include <dev/wscons/wsksymvar.h>
52 1.12.8.2 nathanw
53 1.12.8.2 nathanw #include <machine/autoconf.h>
54 1.12.8.2 nathanw #include <machine/cpu.h>
55 1.12.8.2 nathanw #define KEYBOARD_ARRAY
56 1.12.8.2 nathanw #include <machine/keyboard.h>
57 1.12.8.2 nathanw #include <machine/viareg.h>
58 1.12.8.2 nathanw
59 1.12.8.2 nathanw #include <mac68k/mac68k/macrom.h>
60 1.12.8.2 nathanw #include <mac68k/dev/adbvar.h>
61 1.12.8.2 nathanw #include <mac68k/dev/aedvar.h>
62 1.12.8.2 nathanw #include <mac68k/dev/akbdmap.h>
63 1.12.8.2 nathanw #include <mac68k/dev/akbdvar.h>
64 1.12.8.2 nathanw #include <mac68k/dev/amsvar.h>
65 1.12.8.2 nathanw
66 1.12.8.2 nathanw /*
67 1.12.8.2 nathanw * Function declarations.
68 1.12.8.2 nathanw */
69 1.12.8.2 nathanw static int akbdmatch __P((struct device *, struct cfdata *, void *));
70 1.12.8.2 nathanw static void akbdattach __P((struct device *, struct device *, void *));
71 1.12.8.2 nathanw void kbd_adbcomplete __P((caddr_t buffer, caddr_t data_area, int adb_command));
72 1.12.8.2 nathanw static void kbd_processevent __P((adb_event_t *event, struct akbd_softc *));
73 1.12.8.2 nathanw #ifdef notyet
74 1.12.8.2 nathanw static u_char getleds __P((int));
75 1.12.8.2 nathanw static int setleds __P((struct akbd_softc *, u_char));
76 1.12.8.2 nathanw static void blinkleds __P((struct akbd_softc *));
77 1.12.8.2 nathanw #endif
78 1.12.8.2 nathanw
79 1.12.8.2 nathanw /*
80 1.12.8.2 nathanw * Local variables.
81 1.12.8.2 nathanw */
82 1.12.8.2 nathanw
83 1.12.8.2 nathanw /* Driver definition. */
84 1.12.8.2 nathanw struct cfattach akbd_ca = {
85 1.12.8.2 nathanw sizeof(struct akbd_softc), akbdmatch, akbdattach
86 1.12.8.2 nathanw };
87 1.12.8.2 nathanw
88 1.12.8.2 nathanw extern struct cfdriver akbd_cd;
89 1.12.8.2 nathanw
90 1.12.8.2 nathanw int kbd_intr __P((adb_event_t *event, struct akbd_softc *));
91 1.12.8.2 nathanw int akbd_enable __P((void *, int));
92 1.12.8.2 nathanw void akbd_set_leds __P((void *, int));
93 1.12.8.2 nathanw int akbd_ioctl __P((void *, u_long, caddr_t, int, struct proc *));
94 1.12.8.2 nathanw
95 1.12.8.2 nathanw struct wskbd_accessops akbd_accessops = {
96 1.12.8.2 nathanw akbd_enable,
97 1.12.8.2 nathanw akbd_set_leds,
98 1.12.8.2 nathanw akbd_ioctl,
99 1.12.8.2 nathanw };
100 1.12.8.2 nathanw
101 1.12.8.2 nathanw void akbd_cngetc __P((void *, u_int *, int *));
102 1.12.8.2 nathanw void akbd_cnpollc __P((void *, int));
103 1.12.8.2 nathanw int akbd_cnattach __P((void));
104 1.12.8.2 nathanw
105 1.12.8.2 nathanw struct wskbd_consops akbd_consops = {
106 1.12.8.2 nathanw akbd_cngetc,
107 1.12.8.2 nathanw akbd_cnpollc,
108 1.12.8.2 nathanw };
109 1.12.8.2 nathanw
110 1.12.8.2 nathanw struct wskbd_mapdata akbd_keymapdata = {
111 1.12.8.2 nathanw akbd_keydesctab,
112 1.12.8.2 nathanw KB_US,
113 1.12.8.2 nathanw };
114 1.12.8.2 nathanw
115 1.12.8.2 nathanw static int akbd_is_console __P((void));
116 1.12.8.2 nathanw
117 1.12.8.2 nathanw static int
118 1.12.8.2 nathanw akbdmatch(parent, cf, aux)
119 1.12.8.2 nathanw struct device *parent;
120 1.12.8.2 nathanw struct cfdata *cf;
121 1.12.8.2 nathanw void *aux;
122 1.12.8.2 nathanw {
123 1.12.8.2 nathanw struct adb_attach_args *aa_args = (struct adb_attach_args *)aux;
124 1.12.8.2 nathanw
125 1.12.8.2 nathanw if (aa_args->origaddr == ADBADDR_KBD)
126 1.12.8.2 nathanw return 1;
127 1.12.8.2 nathanw else
128 1.12.8.2 nathanw return 0;
129 1.12.8.2 nathanw }
130 1.12.8.2 nathanw
131 1.12.8.2 nathanw static void
132 1.12.8.2 nathanw akbdattach(parent, self, aux)
133 1.12.8.2 nathanw struct device *parent, *self;
134 1.12.8.2 nathanw void *aux;
135 1.12.8.2 nathanw {
136 1.12.8.2 nathanw ADBSetInfoBlock adbinfo;
137 1.12.8.2 nathanw struct akbd_softc *sc = (struct akbd_softc *)self;
138 1.12.8.2 nathanw struct adb_attach_args *aa_args = (struct adb_attach_args *)aux;
139 1.12.8.2 nathanw int error, kbd_done;
140 1.12.8.2 nathanw short cmd;
141 1.12.8.2 nathanw u_char buffer[9];
142 1.12.8.2 nathanw #if NWSKBD > 0
143 1.12.8.2 nathanw struct wskbddev_attach_args a;
144 1.12.8.2 nathanw static int akbd_console_initted = 0;
145 1.12.8.2 nathanw int wskbd_eligible;
146 1.12.8.2 nathanw
147 1.12.8.2 nathanw wskbd_eligible = 1;
148 1.12.8.2 nathanw #endif
149 1.12.8.2 nathanw
150 1.12.8.2 nathanw sc->origaddr = aa_args->origaddr;
151 1.12.8.2 nathanw sc->adbaddr = aa_args->adbaddr;
152 1.12.8.2 nathanw sc->handler_id = aa_args->handler_id;
153 1.12.8.2 nathanw
154 1.12.8.2 nathanw sc->sc_leds = (u_int8_t)0x00; /* initially off */
155 1.12.8.2 nathanw
156 1.12.8.2 nathanw adbinfo.siServiceRtPtr = (Ptr)adb_kbd_asmcomplete;
157 1.12.8.2 nathanw adbinfo.siDataAreaAddr = (caddr_t)sc;
158 1.12.8.2 nathanw
159 1.12.8.2 nathanw switch (sc->handler_id) {
160 1.12.8.2 nathanw case ADB_STDKBD:
161 1.12.8.2 nathanw printf("standard keyboard\n");
162 1.12.8.2 nathanw break;
163 1.12.8.2 nathanw case ADB_ISOKBD:
164 1.12.8.2 nathanw printf("standard keyboard (ISO layout)\n");
165 1.12.8.2 nathanw break;
166 1.12.8.2 nathanw case ADB_EXTKBD:
167 1.12.8.2 nathanw cmd = ADBTALK(sc->adbaddr, 1);
168 1.12.8.2 nathanw kbd_done =
169 1.12.8.2 nathanw (adb_op_sync((Ptr)buffer, (Ptr)0, (Ptr)0, cmd) == 0);
170 1.12.8.2 nathanw
171 1.12.8.2 nathanw /* Ignore Logitech MouseMan/Trackman pseudo keyboard */
172 1.12.8.2 nathanw if (kbd_done && buffer[1] == 0x9a && buffer[2] == 0x20) {
173 1.12.8.2 nathanw printf("Mouseman (non-EMP) pseudo keyboard\n");
174 1.12.8.2 nathanw adbinfo.siServiceRtPtr = (Ptr)0;
175 1.12.8.2 nathanw adbinfo.siDataAreaAddr = (Ptr)0;
176 1.12.8.2 nathanw #if NWSKBD > 0
177 1.12.8.2 nathanw wskbd_eligible = 0;
178 1.12.8.2 nathanw #endif /* NWSKBD > 0 */
179 1.12.8.2 nathanw } else if (kbd_done && buffer[1] == 0x9a && buffer[2] == 0x21) {
180 1.12.8.2 nathanw printf("Trackman (non-EMP) pseudo keyboard\n");
181 1.12.8.2 nathanw adbinfo.siServiceRtPtr = (Ptr)0;
182 1.12.8.2 nathanw adbinfo.siDataAreaAddr = (Ptr)0;
183 1.12.8.2 nathanw #if NWSKBD > 0
184 1.12.8.2 nathanw wskbd_eligible = 0;
185 1.12.8.2 nathanw #endif /* NWSKBD > 0 */
186 1.12.8.2 nathanw } else {
187 1.12.8.2 nathanw printf("extended keyboard\n");
188 1.12.8.2 nathanw #ifdef notyet
189 1.12.8.2 nathanw blinkleds(sc);
190 1.12.8.2 nathanw #endif
191 1.12.8.2 nathanw }
192 1.12.8.2 nathanw break;
193 1.12.8.2 nathanw case ADB_EXTISOKBD:
194 1.12.8.2 nathanw printf("extended keyboard (ISO layout)\n");
195 1.12.8.2 nathanw #ifdef notyet
196 1.12.8.2 nathanw blinkleds(sc);
197 1.12.8.2 nathanw #endif
198 1.12.8.2 nathanw break;
199 1.12.8.2 nathanw case ADB_KBDII:
200 1.12.8.2 nathanw printf("keyboard II\n");
201 1.12.8.2 nathanw break;
202 1.12.8.2 nathanw case ADB_ISOKBDII:
203 1.12.8.2 nathanw printf("keyboard II (ISO layout)\n");
204 1.12.8.2 nathanw break;
205 1.12.8.2 nathanw case ADB_PBKBD:
206 1.12.8.2 nathanw printf("PowerBook keyboard\n");
207 1.12.8.2 nathanw break;
208 1.12.8.2 nathanw case ADB_PBISOKBD:
209 1.12.8.2 nathanw printf("PowerBook keyboard (ISO layout)\n");
210 1.12.8.2 nathanw break;
211 1.12.8.2 nathanw case ADB_ADJKPD:
212 1.12.8.2 nathanw printf("adjustable keypad\n");
213 1.12.8.2 nathanw #if NWSKBD > 0
214 1.12.8.2 nathanw wskbd_eligible = 0;
215 1.12.8.2 nathanw #endif /* NWSKBD > 0 */
216 1.12.8.2 nathanw break;
217 1.12.8.2 nathanw case ADB_ADJKBD:
218 1.12.8.2 nathanw printf("adjustable keyboard\n");
219 1.12.8.2 nathanw break;
220 1.12.8.2 nathanw case ADB_ADJISOKBD:
221 1.12.8.2 nathanw printf("adjustable keyboard (ISO layout)\n");
222 1.12.8.2 nathanw break;
223 1.12.8.2 nathanw case ADB_ADJJAPKBD:
224 1.12.8.2 nathanw printf("adjustable keyboard (Japanese layout)\n");
225 1.12.8.2 nathanw break;
226 1.12.8.2 nathanw case ADB_PBEXTISOKBD:
227 1.12.8.2 nathanw printf("PowerBook extended keyboard (ISO layout)\n");
228 1.12.8.2 nathanw break;
229 1.12.8.2 nathanw case ADB_PBEXTJAPKBD:
230 1.12.8.2 nathanw printf("PowerBook extended keyboard (Japanese layout)\n");
231 1.12.8.2 nathanw break;
232 1.12.8.2 nathanw case ADB_JPKBDII:
233 1.12.8.2 nathanw printf("keyboard II (Japanese layout)\n");
234 1.12.8.2 nathanw break;
235 1.12.8.2 nathanw case ADB_PBEXTKBD:
236 1.12.8.2 nathanw printf("PowerBook extended keyboard\n");
237 1.12.8.2 nathanw break;
238 1.12.8.2 nathanw case ADB_DESIGNKBD:
239 1.12.8.2 nathanw printf("extended keyboard\n");
240 1.12.8.2 nathanw #ifdef notyet
241 1.12.8.2 nathanw blinkleds(sc);
242 1.12.8.2 nathanw #endif
243 1.12.8.2 nathanw break;
244 1.12.8.2 nathanw case ADB_PBJPKBD:
245 1.12.8.2 nathanw printf("PowerBook keyboard (Japanese layout)\n");
246 1.12.8.2 nathanw break;
247 1.12.8.2 nathanw default:
248 1.12.8.2 nathanw printf("mapped device (%d)\n", sc->handler_id);
249 1.12.8.2 nathanw #if NWSKBD > 0
250 1.12.8.2 nathanw wskbd_eligible = 0;
251 1.12.8.2 nathanw #endif /* NWSKBD > 0 */
252 1.12.8.2 nathanw break;
253 1.12.8.2 nathanw }
254 1.12.8.2 nathanw error = SetADBInfo(&adbinfo, sc->adbaddr);
255 1.12.8.2 nathanw #ifdef ADB_DEBUG
256 1.12.8.2 nathanw if (adb_debug)
257 1.12.8.2 nathanw printf("akbd: returned %d from SetADBInfo\n", error);
258 1.12.8.2 nathanw #endif
259 1.12.8.2 nathanw
260 1.12.8.2 nathanw #if NWSKBD > 0
261 1.12.8.2 nathanw if (akbd_is_console() && wskbd_eligible)
262 1.12.8.2 nathanw a.console = (++akbd_console_initted == 1);
263 1.12.8.2 nathanw else
264 1.12.8.2 nathanw a.console = 0;
265 1.12.8.2 nathanw a.keymap = &akbd_keymapdata;
266 1.12.8.2 nathanw a.accessops = &akbd_accessops;
267 1.12.8.2 nathanw a.accesscookie = sc;
268 1.12.8.2 nathanw
269 1.12.8.2 nathanw sc->sc_wskbddev = config_found(self, &a, wskbddevprint);
270 1.12.8.2 nathanw #endif
271 1.12.8.2 nathanw }
272 1.12.8.2 nathanw
273 1.12.8.2 nathanw
274 1.12.8.2 nathanw /*
275 1.12.8.2 nathanw * Handle putting the keyboard data received from the ADB into
276 1.12.8.2 nathanw * an ADB event record.
277 1.12.8.2 nathanw */
278 1.12.8.2 nathanw void
279 1.12.8.2 nathanw kbd_adbcomplete(buffer, data_area, adb_command)
280 1.12.8.2 nathanw caddr_t buffer;
281 1.12.8.2 nathanw caddr_t data_area;
282 1.12.8.2 nathanw int adb_command;
283 1.12.8.2 nathanw {
284 1.12.8.2 nathanw adb_event_t event;
285 1.12.8.2 nathanw struct akbd_softc *ksc;
286 1.12.8.2 nathanw int adbaddr;
287 1.12.8.2 nathanw #ifdef ADB_DEBUG
288 1.12.8.2 nathanw int i;
289 1.12.8.2 nathanw
290 1.12.8.2 nathanw if (adb_debug)
291 1.12.8.2 nathanw printf("adb: transaction completion\n");
292 1.12.8.2 nathanw #endif
293 1.12.8.2 nathanw
294 1.12.8.2 nathanw adbaddr = ADB_CMDADDR(adb_command);
295 1.12.8.2 nathanw ksc = (struct akbd_softc *)data_area;
296 1.12.8.2 nathanw
297 1.12.8.2 nathanw event.addr = adbaddr;
298 1.12.8.2 nathanw event.hand_id = ksc->handler_id;
299 1.12.8.2 nathanw event.def_addr = ksc->origaddr;
300 1.12.8.2 nathanw event.byte_count = buffer[0];
301 1.12.8.2 nathanw memcpy(event.bytes, buffer + 1, event.byte_count);
302 1.12.8.2 nathanw
303 1.12.8.2 nathanw #ifdef ADB_DEBUG
304 1.12.8.2 nathanw if (adb_debug) {
305 1.12.8.2 nathanw printf("akbd: from %d at %d (org %d) %d:", event.addr,
306 1.12.8.2 nathanw event.hand_id, event.def_addr, buffer[0]);
307 1.12.8.2 nathanw for (i = 1; i <= buffer[0]; i++)
308 1.12.8.2 nathanw printf(" %x", buffer[i]);
309 1.12.8.2 nathanw printf("\n");
310 1.12.8.2 nathanw }
311 1.12.8.2 nathanw #endif
312 1.12.8.2 nathanw
313 1.12.8.2 nathanw microtime(&event.timestamp);
314 1.12.8.2 nathanw
315 1.12.8.2 nathanw kbd_processevent(&event, ksc);
316 1.12.8.2 nathanw }
317 1.12.8.2 nathanw
318 1.12.8.2 nathanw /*
319 1.12.8.2 nathanw * Given a keyboard ADB event, record the keycodes and call the key
320 1.12.8.2 nathanw * repeat handler, optionally passing the event through the mouse
321 1.12.8.2 nathanw * button emulation handler first.
322 1.12.8.2 nathanw */
323 1.12.8.2 nathanw static void
324 1.12.8.2 nathanw kbd_processevent(event, ksc)
325 1.12.8.2 nathanw adb_event_t *event;
326 1.12.8.2 nathanw struct akbd_softc *ksc;
327 1.12.8.2 nathanw {
328 1.12.8.2 nathanw adb_event_t new_event;
329 1.12.8.2 nathanw
330 1.12.8.2 nathanw new_event = *event;
331 1.12.8.2 nathanw new_event.u.k.key = event->bytes[0];
332 1.12.8.2 nathanw new_event.bytes[1] = 0xff;
333 1.12.8.2 nathanw #if NAED > 0
334 1.12.8.2 nathanw if (adb_polling || !aed_input(&new_event))
335 1.12.8.2 nathanw #endif
336 1.12.8.2 nathanw #if NWSKBD > 0
337 1.12.8.2 nathanw if (ksc->sc_wskbddev != NULL) /* wskbd is attached? */
338 1.12.8.2 nathanw kbd_intr(&new_event, ksc);
339 1.12.8.2 nathanw #else
340 1.12.8.2 nathanw /* do nothing */ ;
341 1.12.8.2 nathanw #endif
342 1.12.8.2 nathanw if (event->bytes[1] != 0xff) {
343 1.12.8.2 nathanw new_event.u.k.key = event->bytes[1];
344 1.12.8.2 nathanw new_event.bytes[0] = event->bytes[1];
345 1.12.8.2 nathanw new_event.bytes[1] = 0xff;
346 1.12.8.2 nathanw #if NAED > 0
347 1.12.8.2 nathanw if (adb_polling || !aed_input(&new_event))
348 1.12.8.2 nathanw #endif
349 1.12.8.2 nathanw #if NWSKBD > 0
350 1.12.8.2 nathanw if (ksc->sc_wskbddev != NULL) /* wskbd is attached? */
351 1.12.8.2 nathanw kbd_intr(&new_event, ksc);
352 1.12.8.2 nathanw #else
353 1.12.8.2 nathanw /* do nothing */ ;
354 1.12.8.2 nathanw #endif
355 1.12.8.2 nathanw }
356 1.12.8.2 nathanw
357 1.12.8.2 nathanw }
358 1.12.8.2 nathanw
359 1.12.8.2 nathanw #ifdef notyet
360 1.12.8.2 nathanw /*
361 1.12.8.2 nathanw * Get the actual hardware LED state and convert it to softc format.
362 1.12.8.2 nathanw */
363 1.12.8.2 nathanw static u_char
364 1.12.8.2 nathanw getleds(addr)
365 1.12.8.2 nathanw int addr;
366 1.12.8.2 nathanw {
367 1.12.8.2 nathanw short cmd;
368 1.12.8.2 nathanw u_char buffer[9], leds;
369 1.12.8.2 nathanw
370 1.12.8.2 nathanw leds = 0x00; /* all off */
371 1.12.8.2 nathanw buffer[0] = 0;
372 1.12.8.2 nathanw
373 1.12.8.2 nathanw cmd = ADBTALK(addr, 2);
374 1.12.8.2 nathanw if (adb_op_sync((Ptr)buffer, (Ptr)0, (Ptr)0, cmd) == 0 &&
375 1.12.8.2 nathanw buffer[0] > 0)
376 1.12.8.2 nathanw leds = ~(buffer[2]) & 0x07;
377 1.12.8.2 nathanw
378 1.12.8.2 nathanw return (leds);
379 1.12.8.2 nathanw }
380 1.12.8.2 nathanw
381 1.12.8.2 nathanw /*
382 1.12.8.2 nathanw * Set the keyboard LED's.
383 1.12.8.2 nathanw *
384 1.12.8.2 nathanw * Automatically translates from ioctl/softc format to the
385 1.12.8.2 nathanw * actual keyboard register format
386 1.12.8.2 nathanw */
387 1.12.8.2 nathanw static int
388 1.12.8.2 nathanw setleds(ksc, leds)
389 1.12.8.2 nathanw struct akbd_softc *ksc;
390 1.12.8.2 nathanw u_char leds;
391 1.12.8.2 nathanw {
392 1.12.8.2 nathanw int addr;
393 1.12.8.2 nathanw short cmd;
394 1.12.8.2 nathanw u_char buffer[9];
395 1.12.8.2 nathanw
396 1.12.8.2 nathanw if ((leds & 0x07) == (ksc->sc_leds & 0x07))
397 1.12.8.2 nathanw return (0);
398 1.12.8.2 nathanw
399 1.12.8.2 nathanw addr = ksc->adbaddr;
400 1.12.8.2 nathanw buffer[0] = 0;
401 1.12.8.2 nathanw
402 1.12.8.2 nathanw cmd = ADBTALK(addr, 2);
403 1.12.8.2 nathanw if (adb_op_sync((Ptr)buffer, (Ptr)0, (Ptr)0, cmd) || buffer[0] == 0)
404 1.12.8.2 nathanw return (EIO);
405 1.12.8.2 nathanw
406 1.12.8.2 nathanw leds = ~leds & 0x07;
407 1.12.8.2 nathanw buffer[2] &= 0xf8;
408 1.12.8.2 nathanw buffer[2] |= leds;
409 1.12.8.2 nathanw
410 1.12.8.2 nathanw cmd = ADBLISTEN(addr, 2);
411 1.12.8.2 nathanw adb_op_sync((Ptr)buffer, (Ptr)0, (Ptr)0, cmd);
412 1.12.8.2 nathanw
413 1.12.8.2 nathanw /* talk R2 */
414 1.12.8.2 nathanw cmd = ADBTALK(addr, 2);
415 1.12.8.2 nathanw if (adb_op_sync((Ptr)buffer, (Ptr)0, (Ptr)0, cmd) || buffer[0] == 0)
416 1.12.8.2 nathanw return (EIO);
417 1.12.8.2 nathanw
418 1.12.8.2 nathanw ksc->sc_leds = ~((u_int8_t)buffer[2]) & 0x07;
419 1.12.8.2 nathanw
420 1.12.8.2 nathanw if ((buffer[2] & 0xf8) != leds)
421 1.12.8.2 nathanw return (EIO);
422 1.12.8.2 nathanw else
423 1.12.8.2 nathanw return (0);
424 1.12.8.2 nathanw }
425 1.12.8.2 nathanw
426 1.12.8.2 nathanw /*
427 1.12.8.2 nathanw * Toggle all of the LED's on and off, just for show.
428 1.12.8.2 nathanw */
429 1.12.8.2 nathanw static void
430 1.12.8.2 nathanw blinkleds(ksc)
431 1.12.8.2 nathanw struct akbd_softc *ksc;
432 1.12.8.2 nathanw {
433 1.12.8.2 nathanw int addr, i;
434 1.12.8.2 nathanw u_char blinkleds, origleds;
435 1.12.8.2 nathanw
436 1.12.8.2 nathanw addr = ksc->adbaddr;
437 1.12.8.2 nathanw origleds = getleds(addr);
438 1.12.8.2 nathanw blinkleds = LED_NUMLOCK | LED_CAPSLOCK | LED_SCROLL_LOCK;
439 1.12.8.2 nathanw
440 1.12.8.2 nathanw (void)setleds(ksc, blinkleds);
441 1.12.8.2 nathanw
442 1.12.8.2 nathanw for (i = 0; i < 10000; i++)
443 1.12.8.2 nathanw delay(50);
444 1.12.8.2 nathanw
445 1.12.8.2 nathanw /* make sure that we restore the LED settings */
446 1.12.8.2 nathanw i = 10;
447 1.12.8.2 nathanw do {
448 1.12.8.2 nathanw (void)setleds(ksc, (u_char)0x00);
449 1.12.8.2 nathanw } while (setleds(ksc, (u_char)0x00) && (i-- > 0));
450 1.12.8.2 nathanw
451 1.12.8.2 nathanw return;
452 1.12.8.2 nathanw }
453 1.12.8.2 nathanw #endif
454 1.12.8.2 nathanw
455 1.12.8.2 nathanw int
456 1.12.8.2 nathanw akbd_is_console()
457 1.12.8.2 nathanw {
458 1.12.8.2 nathanw extern struct mac68k_machine_S mac68k_machine;
459 1.12.8.2 nathanw
460 1.12.8.2 nathanw return ((mac68k_machine.serial_console & 0x03) == 0);
461 1.12.8.2 nathanw }
462 1.12.8.2 nathanw
463 1.12.8.2 nathanw int
464 1.12.8.2 nathanw akbd_enable(v, on)
465 1.12.8.2 nathanw void *v;
466 1.12.8.2 nathanw int on;
467 1.12.8.2 nathanw {
468 1.12.8.2 nathanw return 0;
469 1.12.8.2 nathanw }
470 1.12.8.2 nathanw
471 1.12.8.2 nathanw void
472 1.12.8.2 nathanw akbd_set_leds(v, on)
473 1.12.8.2 nathanw void *v;
474 1.12.8.2 nathanw int on;
475 1.12.8.2 nathanw {
476 1.12.8.2 nathanw }
477 1.12.8.2 nathanw
478 1.12.8.2 nathanw int
479 1.12.8.2 nathanw akbd_ioctl(v, cmd, data, flag, p)
480 1.12.8.2 nathanw void *v;
481 1.12.8.2 nathanw u_long cmd;
482 1.12.8.2 nathanw caddr_t data;
483 1.12.8.2 nathanw int flag;
484 1.12.8.2 nathanw struct proc *p;
485 1.12.8.2 nathanw {
486 1.12.8.2 nathanw switch (cmd) {
487 1.12.8.2 nathanw
488 1.12.8.2 nathanw case WSKBDIO_GTYPE:
489 1.12.8.2 nathanw *(int *)data = 0; /* XXX */
490 1.12.8.2 nathanw return 0;
491 1.12.8.2 nathanw case WSKBDIO_SETLEDS:
492 1.12.8.2 nathanw return 0;
493 1.12.8.2 nathanw case WSKBDIO_GETLEDS:
494 1.12.8.2 nathanw *(int *)data = 0;
495 1.12.8.2 nathanw return 0;
496 1.12.8.2 nathanw case WSKBDIO_BELL:
497 1.12.8.2 nathanw case WSKBDIO_COMPLEXBELL:
498 1.12.8.2 nathanw #define d ((struct wskbd_bell_data *)data)
499 1.12.8.2 nathanw mac68k_ring_bell(d->pitch, d->period * hz / 1000, 100);
500 1.12.8.2 nathanw /* comes in as msec, goes out as ticks; volume ignored */
501 1.12.8.2 nathanw #undef d
502 1.12.8.2 nathanw return (0);
503 1.12.8.2 nathanw }
504 1.12.8.2 nathanw /* kbdioctl(...); */
505 1.12.8.2 nathanw
506 1.12.8.2 nathanw return EPASSTHROUGH;
507 1.12.8.2 nathanw }
508 1.12.8.2 nathanw
509 1.12.8.2 nathanw static int polledkey;
510 1.12.8.2 nathanw extern int adb_polling;
511 1.12.8.2 nathanw
512 1.12.8.2 nathanw int
513 1.12.8.2 nathanw kbd_intr(event, sc)
514 1.12.8.2 nathanw adb_event_t *event;
515 1.12.8.2 nathanw struct akbd_softc *sc;
516 1.12.8.2 nathanw {
517 1.12.8.2 nathanw int key, press, val;
518 1.12.8.2 nathanw int type;
519 1.12.8.2 nathanw
520 1.12.8.2 nathanw key = event->u.k.key;
521 1.12.8.2 nathanw press = ADBK_PRESS(key);
522 1.12.8.2 nathanw val = ADBK_KEYVAL(key);
523 1.12.8.2 nathanw
524 1.12.8.2 nathanw type = press ? WSCONS_EVENT_KEY_DOWN : WSCONS_EVENT_KEY_UP;
525 1.12.8.2 nathanw
526 1.12.8.2 nathanw if (key == 185) { /* Caps Lock released */
527 1.12.8.2 nathanw type = WSCONS_EVENT_KEY_DOWN;
528 1.12.8.2 nathanw wskbd_input(sc->sc_wskbddev, type, val);
529 1.12.8.2 nathanw type = WSCONS_EVENT_KEY_UP;
530 1.12.8.2 nathanw }
531 1.12.8.2 nathanw
532 1.12.8.2 nathanw if (adb_polling)
533 1.12.8.2 nathanw polledkey = key;
534 1.12.8.2 nathanw else
535 1.12.8.2 nathanw wskbd_input(sc->sc_wskbddev, type, val);
536 1.12.8.2 nathanw
537 1.12.8.2 nathanw return 0;
538 1.12.8.2 nathanw }
539 1.12.8.2 nathanw
540 1.12.8.2 nathanw int
541 1.12.8.2 nathanw akbd_cnattach()
542 1.12.8.2 nathanw {
543 1.12.8.2 nathanw wskbd_cnattach(&akbd_consops, NULL, &akbd_keymapdata);
544 1.12.8.2 nathanw
545 1.12.8.2 nathanw return 0;
546 1.12.8.2 nathanw }
547 1.12.8.2 nathanw
548 1.12.8.2 nathanw void
549 1.12.8.2 nathanw akbd_cngetc(v, type, data)
550 1.12.8.2 nathanw void *v;
551 1.12.8.2 nathanw u_int *type;
552 1.12.8.2 nathanw int *data;
553 1.12.8.2 nathanw {
554 1.12.8.2 nathanw int intbits, key, press, val;
555 1.12.8.2 nathanw int s;
556 1.12.8.2 nathanw
557 1.12.8.2 nathanw s = splhigh();
558 1.12.8.2 nathanw
559 1.12.8.2 nathanw polledkey = -1;
560 1.12.8.2 nathanw adb_polling = 1;
561 1.12.8.2 nathanw
562 1.12.8.2 nathanw while (polledkey == -1) {
563 1.12.8.2 nathanw intbits = via_reg(VIA1, vIFR);
564 1.12.8.2 nathanw
565 1.12.8.2 nathanw if (intbits & V1IF_ADBRDY) {
566 1.12.8.2 nathanw mrg_adbintr();
567 1.12.8.2 nathanw via_reg(VIA1, vIFR) = V1IF_ADBRDY;
568 1.12.8.2 nathanw }
569 1.12.8.2 nathanw if (intbits & 0x10) {
570 1.12.8.2 nathanw mrg_pmintr();
571 1.12.8.2 nathanw via_reg(VIA1, vIFR) = 0x10;
572 1.12.8.2 nathanw }
573 1.12.8.2 nathanw }
574 1.12.8.2 nathanw
575 1.12.8.2 nathanw adb_polling = 0;
576 1.12.8.2 nathanw splx(s);
577 1.12.8.2 nathanw
578 1.12.8.2 nathanw key = polledkey;
579 1.12.8.2 nathanw press = ADBK_PRESS(key);
580 1.12.8.2 nathanw val = ADBK_KEYVAL(key);
581 1.12.8.2 nathanw
582 1.12.8.2 nathanw *data = val;
583 1.12.8.2 nathanw *type = press ? WSCONS_EVENT_KEY_DOWN : WSCONS_EVENT_KEY_UP;
584 1.12.8.2 nathanw }
585 1.12.8.2 nathanw
586 1.12.8.2 nathanw void
587 1.12.8.2 nathanw akbd_cnpollc(v, on)
588 1.12.8.2 nathanw void *v;
589 1.12.8.2 nathanw int on;
590 1.12.8.2 nathanw {
591 1.12.8.2 nathanw }
592