1 /* $OpenBSD: adb.c,v 1.52 2024/04/14 03:26:25 jsg Exp $ */
2 /* $NetBSD: adb.c,v 1.6 1999/08/16 06:28:09 tsubai Exp $ */
3 /* $NetBSD: adb_direct.c,v 1.14 2000/06/08 22:10:45 tsubai Exp $ */
4
5 /*
6 * Copyright (C) 1996, 1997 John P. Wittkoski
7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 * 3. All advertising materials mentioning features or use of this software
18 * must display the following acknowledgement:
19 * This product includes software developed by John P. Wittkoski.
20 * 4. The name of the author may not be used to endorse or promote products
21 * derived from this software without specific prior written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
24 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
25 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
26 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
27 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
28 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
29 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
30 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
32 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 */
34
35 /*-
36 * Copyright (C) 1994 Bradley A. Grantham
37 * All rights reserved.
38 *
39 * Redistribution and use in source and binary forms, with or without
40 * modification, are permitted provided that the following conditions
41 * are met:
42 * 1. Redistributions of source code must retain the above copyright
43 * notice, this list of conditions and the following disclaimer.
44 * 2. Redistributions in binary form must reproduce the above copyright
45 * notice, this list of conditions and the following disclaimer in the
46 * documentation and/or other materials provided with the distribution.
47 *
48 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
49 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
50 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
51 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
52 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
53 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
54 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
55 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
56 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
57 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
58 */
59
60 /*
61 * This code is rather messy, but I don't have time right now
62 * to clean it up as much as I would like.
63 * But it works, so I'm happy. :-) jpw
64 */
65
66 /*
67 * TO DO:
68 * - We could reduce the time spent in the adb_intr_* routines
69 * by having them save the incoming and outgoing data directly
70 * in the adbInbound and adbOutbound queues, as it would reduce
71 * the number of times we need to copy the data around. It
72 * would also make the code more readable and easier to follow.
73 * - (Related to above) Use the header part of adbCommand to
74 * reduce the number of copies we have to do of the data.
75 * - (Related to above) Actually implement the adbOutbound queue.
76 * This is fairly easy once you switch all the intr routines
77 * over to using adbCommand structs directly.
78 * - There is a bug in the state machine of adb_intr_cuda
79 * code that causes hangs, especially on 030 machines, probably
80 * because of some timing issues. Because I have been unable to
81 * determine the exact cause of this bug, I used the timeout function
82 * to check for and recover from this condition. If anyone finds
83 * the actual cause of this bug, the calls to timeout and the
84 * adb_cuda_tickle routine can be removed.
85 */
86
87 #include <sys/param.h>
88 #include <sys/device.h>
89 #include <sys/fcntl.h>
90 #include <sys/proc.h>
91 #include <sys/signalvar.h>
92 #include <sys/task.h>
93 #include <sys/timeout.h>
94 #include <sys/systm.h>
95
96 #include <machine/autoconf.h>
97 #include <machine/cpu.h>
98 #include <dev/ofw/openfirm.h>
99 #include <dev/wscons/wsconsio.h>
100
101 #include <dev/adb/adb.h>
102 #include <macppc/dev/adbvar.h>
103 #include <macppc/dev/pm_direct.h>
104 #include <macppc/dev/viareg.h>
105
106 #include "apm.h"
107
108 #define printf_intr printf
109
110 #ifdef DEBUG
111 #ifndef ADB_DEBUG
112 #define ADB_DEBUG
113 #endif
114 #endif
115
116 int adb_polling; /* Are we polling? (Debugger mode) */
117 #ifdef ADB_DEBUG
118 int adb_debug; /* Output debugging messages */
119 #endif /* ADB_DEBUG */
120
121 /* some misc. leftovers */
122 #define vPB 0x0000
123 #define vPB3 0x08
124 #define vPB4 0x10
125 #define vPB5 0x20
126 #define vSR_INT 0x04
127 #define vSR_OUT 0x10
128
129 /* the type of ADB action that we are currently performing */
130 #define ADB_ACTION_NOTREADY 0x1 /* has not been initialized yet */
131 #define ADB_ACTION_IDLE 0x2 /* the bus is currently idle */
132 #define ADB_ACTION_OUT 0x3 /* sending out a command */
133 #define ADB_ACTION_IN 0x4 /* receiving data */
134
135 /*
136 * Shortcuts for setting or testing the VIA bit states.
137 * Not all shortcuts are used for every type of ADB hardware.
138 */
139 #define ADB_SET_STATE_IDLE_CUDA() via_reg_or(VIA1, vBufB, (vPB4 | vPB5))
140 #define ADB_SET_STATE_TIP() via_reg_and(VIA1, vBufB, ~vPB5)
141 #define ADB_CLR_STATE_TIP() via_reg_or(VIA1, vBufB, vPB5)
142 #define ADB_TOGGLE_STATE_ACK_CUDA() via_reg_xor(VIA1, vBufB, vPB4)
143 #define ADB_SET_STATE_ACKOFF_CUDA() via_reg_or(VIA1, vBufB, vPB4)
144 #define ADB_SET_SR_INPUT() via_reg_and(VIA1, vACR, ~vSR_OUT)
145 #define ADB_SET_SR_OUTPUT() via_reg_or(VIA1, vACR, vSR_OUT)
146 #define ADB_SR() read_via_reg(VIA1, vSR)
147 #define ADB_VIA_INTR_ENABLE() write_via_reg(VIA1, vIER, 0x84)
148 #define ADB_VIA_INTR_DISABLE() write_via_reg(VIA1, vIER, 0x04)
149 #define ADB_VIA_CLR_INTR() write_via_reg(VIA1, vIFR, 0x04)
150 #define ADB_INTR_IS_OFF (vPB3 == (read_via_reg(VIA1, vBufB) & vPB3))
151 #define ADB_INTR_IS_ON (0 == (read_via_reg(VIA1, vBufB) & vPB3))
152 #define ADB_SR_INTR_IS_ON (vSR_INT == (read_via_reg(VIA1, \
153 vIFR) & vSR_INT))
154
155 /*
156 * This is the delay that is required (in uS) between certain
157 * ADB transactions. The actual timing delay for each uS is
158 * calculated at boot time to account for differences in machine speed.
159 */
160 #define ADB_DELAY 150
161
162 /*
163 * Maximum ADB message length; includes space for data, result, and
164 * device code - plus a little for safety.
165 */
166 #define ADB_MAX_MSG_LENGTH 16
167 #define ADB_MAX_HDR_LENGTH 8
168
169 #define ADB_QUEUE 32
170 #define ADB_TICKLE_TICKS 4
171
172 /*
173 * Eventually used for two separate queues, the queue between
174 * the upper and lower halves, and the outgoing packet queue.
175 */
176 struct adbCommand {
177 u_char header[ADB_MAX_HDR_LENGTH]; /* not used yet */
178 u_char data[ADB_MAX_MSG_LENGTH]; /* packet data only */
179 u_char *saveBuf; /* where to save result */
180 u_char *compRout; /* completion routine pointer */
181 u_char *compData; /* completion routine data pointer */
182 u_int cmd; /* the original command for this data */
183 u_int unsol; /* 1 if packet was unsolicited */
184 u_int ack_only; /* 1 for no special processing */
185 };
186
187 /*
188 * A few variables that we need and their initial values.
189 */
190 int adbHardware = ADB_HW_UNKNOWN;
191 int adbActionState = ADB_ACTION_NOTREADY;
192 int adbWaiting; /* waiting for return data from the device */
193 int adbWriteDelay; /* working on (or waiting to do) a write */
194
195 int adbWaitingCmd; /* ADB command we are waiting for */
196 u_char *adbBuffer; /* pointer to user data area */
197 void *adbCompRout; /* pointer to the completion routine */
198 void *adbCompData; /* pointer to the completion routine data */
199 int adbStarting = 1; /* doing adb_reinit so do polling differently */
200
201 u_char adbInputBuffer[ADB_MAX_MSG_LENGTH]; /* data input buffer */
202 u_char adbOutputBuffer[ADB_MAX_MSG_LENGTH]; /* data output buffer */
203
204 int adbSentChars; /* how many characters we have sent */
205
206 struct adbCommand adbInbound[ADB_QUEUE]; /* incoming queue */
207 int adbInCount; /* how many packets in queue */
208 int adbInHead; /* head of in queue */
209 int adbInTail; /* tail of in queue */
210
211 int tickle_count; /* how many tickles seen for this packet? */
212 int tickle_serial; /* the last packet tickled */
213 int adb_cuda_serial; /* the current packet */
214 struct timeout adb_cuda_timeout;
215 struct timeout adb_softintr_timeout;
216 int adbempty; /* nonzero if no adb devices */
217
218 extern struct cfdriver adb_cd;
219
220 volatile u_char *Via1Base;
221
222 /*
223 * The following are private routines.
224 */
225 #ifdef ADB_DEBUG
226 void print_single(u_char *);
227 #endif
228 void adb_intr_cuda(void);
229 void adb_soft_intr(void);
230 int send_adb_cuda(u_char *, u_char *, void *, void *, int);
231 void adb_cuda_tickle(void *);
232 void adb_pass_up(struct adbCommand *);
233 void adb_op_comprout(caddr_t, caddr_t, int);
234 void adb_reinit(struct adb_softc *);
235 int count_adbs(struct adb_softc *);
236 int get_ind_adb_info(struct adb_softc *, ADBDataBlock *, int);
237 int get_adb_info(ADBDataBlock *, int);
238 int adb_op(Ptr, Ptr, Ptr, short);
239 void adb_hw_setup(void);
240 int adb_cmd_result(u_char *);
241 void setsoftadb(void);
242
243 int adb_intr(void *arg);
244 void adb_cuda_autopoll(void);
245 void adb_cuda_fileserver_mode(void);
246 uint8_t pmu_backlight; /* keyboard backlight value */
247 int pmu_get_backlight(struct wskbd_backlight *);
248 int pmu_set_backlight(struct wskbd_backlight *);
249 extern int (*wskbd_get_backlight)(struct wskbd_backlight *);
250 extern int (*wskbd_set_backlight)(struct wskbd_backlight *);
251
252
253 #ifndef SMALL_KERNEL
254 void adb_shutdown(void *);
255 struct task adb_shutdown_task = TASK_INITIALIZER(adb_shutdown, NULL);
256 #ifdef SUSPEND
257 void adb_suspend(void *);
258 struct task adb_suspend_task = TASK_INITIALIZER(adb_suspend, NULL);
259 struct taskq *adb_suspendq;
260 #endif
261 #endif
262
263 #ifdef ADB_DEBUG
264 /*
265 * print_single
266 * Diagnostic display routine. Displays the hex values of the
267 * specified elements of the u_char. The length of the "string"
268 * is in [0].
269 */
270 void
print_single(u_char * str)271 print_single(u_char *str)
272 {
273 int x;
274
275 if (str == NULL) {
276 printf_intr("no data - null pointer\n");
277 return;
278 }
279 if (*str == '\0') {
280 printf_intr("nothing returned\n");
281 return;
282 }
283 if (*str > 20) {
284 printf_intr("ADB: ACK > 20 no way!\n");
285 *str = 20;
286 }
287 printf_intr("(length=0x%x):", *str);
288 for (x = 1; x <= *str; x++)
289 printf_intr(" 0x%02x", str[x]);
290 printf_intr("\n");
291 }
292 #endif
293
294 void
adb_cuda_tickle(void * unused)295 adb_cuda_tickle(void *unused)
296 {
297 volatile int s;
298
299 if (adbActionState == ADB_ACTION_IN) {
300 if (tickle_serial == adb_cuda_serial) {
301 if (++tickle_count > 0) {
302 s = splhigh();
303 adbActionState = ADB_ACTION_IDLE;
304 adbInputBuffer[0] = 0;
305 ADB_SET_STATE_IDLE_CUDA();
306 splx(s);
307 }
308 } else {
309 tickle_serial = adb_cuda_serial;
310 tickle_count = 0;
311 }
312 } else {
313 tickle_serial = adb_cuda_serial;
314 tickle_count = 0;
315 }
316
317 timeout_add(&adb_cuda_timeout, ADB_TICKLE_TICKS);
318 }
319
320 /*
321 * called when an adb interrupt happens
322 *
323 * Cuda version of adb_intr
324 * TO DO: do we want to add some calls to intr_dispatch() here to
325 * grab serial interrupts?
326 */
327 void
adb_intr_cuda(void)328 adb_intr_cuda(void)
329 {
330 volatile int i, ending;
331 volatile unsigned int s;
332 struct adbCommand packet;
333
334 s = splhigh(); /* can't be too careful - might be called */
335 /* from a routine, NOT an interrupt */
336
337 ADB_VIA_CLR_INTR(); /* clear interrupt */
338 ADB_VIA_INTR_DISABLE(); /* disable ADB interrupt on IIs. */
339
340 switch_start:
341 switch (adbActionState) {
342 case ADB_ACTION_IDLE:
343 /*
344 * This is an unexpected packet, so grab the first (dummy)
345 * byte, set up the proper vars, and tell the chip we are
346 * starting to receive the packet by setting the TIP bit.
347 */
348 adbInputBuffer[1] = ADB_SR();
349 adb_cuda_serial++;
350 if (ADB_INTR_IS_OFF) /* must have been a fake start */
351 break;
352
353 ADB_SET_SR_INPUT();
354 ADB_SET_STATE_TIP();
355
356 adbInputBuffer[0] = 1;
357 adbActionState = ADB_ACTION_IN;
358 #ifdef ADB_DEBUG
359 if (adb_debug)
360 printf_intr("idle 0x%02x ", adbInputBuffer[1]);
361 #endif
362 break;
363
364 case ADB_ACTION_IN:
365 adbInputBuffer[++adbInputBuffer[0]] = ADB_SR();
366 /* intr off means this is the last byte (end of frame) */
367 if (ADB_INTR_IS_OFF)
368 ending = 1;
369 else
370 ending = 0;
371
372 if (1 == ending) { /* end of message? */
373 #ifdef ADB_DEBUG
374 if (adb_debug) {
375 printf_intr("in end 0x%02x ",
376 adbInputBuffer[adbInputBuffer[0]]);
377 print_single(adbInputBuffer);
378 }
379 #endif
380
381 /*
382 * Are we waiting AND does this packet match what we
383 * are waiting for AND is it coming from either the
384 * ADB or RTC/PRAM sub-device? This section _should_
385 * recognize all ADB and RTC/PRAM type commands, but
386 * there may be more... NOTE: commands are always at
387 * [4], even for RTC/PRAM commands.
388 */
389 /* set up data for adb_pass_up */
390 memcpy(packet.data, adbInputBuffer, adbInputBuffer[0] + 1);
391
392 if ((adbWaiting == 1) &&
393 (adbInputBuffer[4] == adbWaitingCmd) &&
394 ((adbInputBuffer[2] == 0x00) ||
395 (adbInputBuffer[2] == 0x01))) {
396 packet.saveBuf = adbBuffer;
397 packet.compRout = adbCompRout;
398 packet.compData = adbCompData;
399 packet.unsol = 0;
400 packet.ack_only = 0;
401 adb_pass_up(&packet);
402
403 adbWaitingCmd = 0; /* reset "waiting" vars */
404 adbWaiting = 0;
405 adbBuffer = NULL;
406 adbCompRout = NULL;
407 adbCompData = NULL;
408 } else {
409 packet.unsol = 1;
410 packet.ack_only = 0;
411 adb_pass_up(&packet);
412 }
413
414
415 /* reset vars and signal the end of this frame */
416 adbActionState = ADB_ACTION_IDLE;
417 adbInputBuffer[0] = 0;
418 ADB_SET_STATE_IDLE_CUDA();
419 /*ADB_SET_SR_INPUT();*/
420
421 /*
422 * If there is something waiting to be sent out,
423 * the set everything up and send the first byte.
424 */
425 if (adbWriteDelay == 1) {
426 delay(ADB_DELAY); /* required */
427 adbSentChars = 0;
428 adbActionState = ADB_ACTION_OUT;
429 /*
430 * If the interrupt is on, we were too slow
431 * and the chip has already started to send
432 * something to us, so back out of the write
433 * and start a read cycle.
434 */
435 if (ADB_INTR_IS_ON) {
436 ADB_SET_SR_INPUT();
437 ADB_SET_STATE_IDLE_CUDA();
438 adbSentChars = 0;
439 adbActionState = ADB_ACTION_IDLE;
440 adbInputBuffer[0] = 0;
441 break;
442 }
443 /*
444 * If we got here, it's ok to start sending
445 * so load the first byte and tell the chip
446 * we want to send.
447 */
448 ADB_SET_STATE_TIP();
449 ADB_SET_SR_OUTPUT();
450 write_via_reg(VIA1, vSR, adbOutputBuffer[adbSentChars + 1]);
451 }
452 } else {
453 ADB_TOGGLE_STATE_ACK_CUDA();
454 #ifdef ADB_DEBUG
455 if (adb_debug)
456 printf_intr("in 0x%02x ",
457 adbInputBuffer[adbInputBuffer[0]]);
458 #endif
459 }
460 break;
461
462 case ADB_ACTION_OUT:
463 i = ADB_SR(); /* reset SR-intr in IFR */
464 #ifdef ADB_DEBUG
465 if (adb_debug)
466 printf_intr("intr out 0x%02x ", i);
467 #endif
468
469 adbSentChars++;
470 if (ADB_INTR_IS_ON) { /* ADB intr low during write */
471 #ifdef ADB_DEBUG
472 if (adb_debug)
473 printf_intr("intr was on ");
474 #endif
475 ADB_SET_SR_INPUT(); /* make sure SR is set to IN */
476 ADB_SET_STATE_IDLE_CUDA();
477 adbSentChars = 0; /* must start all over */
478 adbActionState = ADB_ACTION_IDLE; /* new state */
479 adbInputBuffer[0] = 0;
480 adbWriteDelay = 1; /* must retry when done with
481 * read */
482 delay(ADB_DELAY);
483 goto switch_start; /* process next state right
484 * now */
485 break;
486 }
487 if (adbOutputBuffer[0] == adbSentChars) { /* check for done */
488 if (0 == adb_cmd_result(adbOutputBuffer)) { /* do we expect data
489 * back? */
490 adbWaiting = 1; /* signal waiting for return */
491 adbWaitingCmd = adbOutputBuffer[2]; /* save waiting command */
492 } else { /* no talk, so done */
493 /* set up stuff for adb_pass_up */
494 memcpy(packet.data, adbInputBuffer, adbInputBuffer[0] + 1);
495 packet.saveBuf = adbBuffer;
496 packet.compRout = adbCompRout;
497 packet.compData = adbCompData;
498 packet.cmd = adbWaitingCmd;
499 packet.unsol = 0;
500 packet.ack_only = 1;
501 adb_pass_up(&packet);
502
503 /* reset "waiting" vars, just in case */
504 adbWaitingCmd = 0;
505 adbBuffer = NULL;
506 adbCompRout = NULL;
507 adbCompData = NULL;
508 }
509
510 adbWriteDelay = 0; /* done writing */
511 adbActionState = ADB_ACTION_IDLE; /* signal bus is idle */
512 ADB_SET_SR_INPUT();
513 ADB_SET_STATE_IDLE_CUDA();
514 #ifdef ADB_DEBUG
515 if (adb_debug)
516 printf_intr("write done ");
517 #endif
518 } else {
519 write_via_reg(VIA1, vSR, adbOutputBuffer[adbSentChars + 1]); /* send next byte */
520 ADB_TOGGLE_STATE_ACK_CUDA(); /* signal byte ready to
521 * shift */
522 #ifdef ADB_DEBUG
523 if (adb_debug)
524 printf_intr("toggle ");
525 #endif
526 }
527 break;
528
529 case ADB_ACTION_NOTREADY:
530 #ifdef ADB_DEBUG
531 if (adb_debug)
532 printf_intr("adb: not yet initialized\n");
533 #endif
534 break;
535
536 default:
537 ;
538 #ifdef ADB_DEBUG
539 if (adb_debug)
540 printf_intr("intr: unknown ADB state\n");
541 #endif
542 }
543
544 ADB_VIA_INTR_ENABLE(); /* enable ADB interrupt on IIs. */
545
546 splx(s); /* restore */
547 }
548
549
550 int
send_adb_cuda(u_char * in,u_char * buffer,void * compRout,void * data,int command)551 send_adb_cuda(u_char * in, u_char * buffer, void *compRout, void *data,
552 int command)
553 {
554 int s, len;
555
556 #ifdef ADB_DEBUG
557 if (adb_debug)
558 printf_intr("SEND\n");
559 #endif
560
561 if (adbActionState == ADB_ACTION_NOTREADY)
562 return 1;
563
564 /* Don't interrupt while we are messing with the ADB */
565 s = splhigh();
566
567 if ((adbActionState == ADB_ACTION_IDLE) && /* ADB available? */
568 (ADB_INTR_IS_OFF)) { /* and no incoming interrupt? */
569 } else
570 if (adbWriteDelay == 0) /* it's busy, but is anything waiting? */
571 adbWriteDelay = 1; /* if no, then we'll "queue"
572 * it up */
573 else {
574 splx(s);
575 return 1; /* really busy! */
576 }
577
578 #ifdef ADB_DEBUG
579 if (adb_debug)
580 printf_intr("QUEUE\n");
581 #endif
582 if ((long)in == (long)0) { /* need to convert? */
583 if ((command & 0x0c) == 0x08) /* copy addl data ONLY if
584 * doing a listen! */
585 len = buffer[0]; /* length of additional data */
586 else
587 len = 0;/* no additional data */
588
589 adbOutputBuffer[0] = 2 + len; /* dev. type + command + addl.
590 * data */
591 adbOutputBuffer[1] = 0x00; /* mark as an ADB command */
592 adbOutputBuffer[2] = (u_char)command; /* load command */
593
594 /* copy additional output data, if any */
595 memcpy(adbOutputBuffer + 3, buffer + 1, len);
596 } else
597 /* if data ready, just copy over */
598 memcpy(adbOutputBuffer, in, in[0] + 2);
599
600 adbSentChars = 0; /* nothing sent yet */
601 adbBuffer = buffer; /* save buffer to know where to save result */
602 adbCompRout = compRout; /* save completion routine pointer */
603 adbCompData = data; /* save completion routine data pointer */
604 adbWaitingCmd = adbOutputBuffer[2]; /* save wait command */
605
606 if (adbWriteDelay != 1) { /* start command now? */
607 #ifdef ADB_DEBUG
608 if (adb_debug)
609 printf_intr("out start NOW");
610 #endif
611 delay(ADB_DELAY);
612 adbActionState = ADB_ACTION_OUT; /* set next state */
613 ADB_SET_SR_OUTPUT(); /* set shift register for OUT */
614 write_via_reg(VIA1, vSR, adbOutputBuffer[adbSentChars + 1]); /* load byte for output */
615 ADB_SET_STATE_ACKOFF_CUDA();
616 ADB_SET_STATE_TIP(); /* tell ADB that we want to send */
617 }
618 adbWriteDelay = 1; /* something in the write "queue" */
619
620 splx(s);
621
622 if (adb_polling) /* XXX were VIA1 interrupts blocked ? */
623 /* poll until byte done */
624 while ((adbActionState != ADB_ACTION_IDLE) || (ADB_INTR_IS_ON)
625 || (adbWaiting == 1))
626 if (ADB_SR_INTR_IS_ON) { /* wait for "interrupt" */
627 adb_intr_cuda(); /* process it */
628 if (cold)
629 delay(ADB_DELAY);
630 adb_soft_intr();
631 }
632
633 return 0;
634 }
635
636 /*
637 * Called when an adb interrupt happens.
638 * This routine simply transfers control over to the appropriate
639 * code for the machine we are running on.
640 */
641 int
adb_intr(void * arg)642 adb_intr(void *arg)
643 {
644 switch (adbHardware) {
645 case ADB_HW_PMU:
646 pm_intr();
647 break;
648
649 case ADB_HW_CUDA:
650 adb_intr_cuda();
651 break;
652 }
653 return 1;
654 }
655
656
657 /*
658 * adb_pass_up is called by the interrupt-time routines.
659 * It takes the raw packet data that was received from the
660 * device and puts it into the queue that the upper half
661 * processes. It then signals for a soft ADB interrupt which
662 * will eventually call the upper half routine (adb_soft_intr).
663 *
664 * If in->unsol is 0, then this is either the notification
665 * that the packet was sent (on a LISTEN, for example), or the
666 * response from the device (on a TALK). The completion routine
667 * is called only if the user specified one.
668 *
669 * If in->unsol is 1, then this packet was unsolicited and
670 * so we look up the device in the ADB device table to determine
671 * what its default service routine is.
672 *
673 * If in->ack_only is 1, then we really only need to call
674 * the completion routine, so don't do any other stuff.
675 *
676 * Note that in->data contains the packet header AND data,
677 * while adbInbound[]->data contains ONLY data.
678 *
679 * Note: Called only at interrupt time. Assumes this.
680 */
681 void
adb_pass_up(struct adbCommand * in)682 adb_pass_up(struct adbCommand *in)
683 {
684 int start = 0, len = 0, cmd = 0;
685 ADBDataBlock block;
686
687 if (adbInCount >= ADB_QUEUE) {
688 #ifdef ADB_DEBUG
689 if (adb_debug)
690 printf_intr("adb: ring buffer overflow\n");
691 #endif
692 return;
693 }
694
695 if (in->ack_only) {
696 len = in->data[0];
697 cmd = in->cmd;
698 start = 0;
699 } else {
700 switch (adbHardware) {
701 case ADB_HW_CUDA:
702 /* If it's unsolicited, accept only ADB data for now */
703 if (in->unsol)
704 if (0 != in->data[2])
705 return;
706 cmd = in->data[4];
707 if (in->data[0] < 5)
708 len = 0;
709 else
710 len = in->data[0]-4;
711 start = 4;
712 break;
713
714 case ADB_HW_PMU:
715 cmd = in->data[1];
716 if (in->data[0] < 2)
717 len = 0;
718 else
719 len = in->data[0]-1;
720 start = 1;
721 break;
722
723 case ADB_HW_UNKNOWN:
724 return;
725 }
726
727 /* Make sure there is a valid device entry for this device */
728 if (in->unsol) {
729 /* ignore unsolicited data during adbreinit */
730 if (adbStarting)
731 return;
732 /* get device's comp. routine and data area */
733 if (-1 == get_adb_info(&block, ADB_CMDADDR(cmd)))
734 return;
735 }
736 }
737
738 /*
739 * If this is an unsolicited packet, we need to fill in
740 * some info so adb_soft_intr can process this packet
741 * properly. If it's not unsolicited, then use what
742 * the caller sent us.
743 */
744 if (in->unsol) {
745 adbInbound[adbInTail].compRout = (void *)block.dbServiceRtPtr;
746 adbInbound[adbInTail].compData = (void *)block.dbDataAreaAddr;
747 adbInbound[adbInTail].saveBuf = (void *)adbInbound[adbInTail].data;
748 } else {
749 adbInbound[adbInTail].compRout = (void *)in->compRout;
750 adbInbound[adbInTail].compData = (void *)in->compData;
751 adbInbound[adbInTail].saveBuf = (void *)in->saveBuf;
752 }
753
754 #ifdef ADB_DEBUG
755 if (adb_debug && in->data[1] == 2)
756 printf_intr("adb: caught error\n");
757 #endif
758
759 /* copy the packet data over */
760 /*
761 * TO DO: If the *_intr routines fed their incoming data
762 * directly into an adbCommand struct, which is passed to
763 * this routine, then we could eliminate this copy.
764 */
765 memcpy(adbInbound[adbInTail].data + 1, in->data + start + 1, len);
766 adbInbound[adbInTail].data[0] = len;
767 adbInbound[adbInTail].cmd = cmd;
768
769 adbInCount++;
770 if (++adbInTail >= ADB_QUEUE)
771 adbInTail = 0;
772
773 /*
774 * If the debugger is running, call upper half manually.
775 * Otherwise, trigger a soft interrupt to handle the rest later.
776 */
777 if (adb_polling)
778 adb_soft_intr();
779 else
780 setsoftadb();
781 }
782
783
784 /*
785 * Called to process the packets after they have been
786 * placed in the incoming queue.
787 *
788 */
789 void
adb_soft_intr(void)790 adb_soft_intr(void)
791 {
792 int s;
793 int cmd = 0;
794 u_char *buffer;
795 u_char *comprout;
796 u_char *compdata;
797
798 /*delay(2*ADB_DELAY);*/
799
800 while (adbInCount) {
801 #ifdef ADB_DEBUG
802 if (adb_debug & 0x80)
803 printf_intr("%x %x %x ",
804 adbInCount, adbInHead, adbInTail);
805 #endif
806 /* get the data we need from the queue */
807 buffer = adbInbound[adbInHead].saveBuf;
808 comprout = adbInbound[adbInHead].compRout;
809 compdata = adbInbound[adbInHead].compData;
810 cmd = adbInbound[adbInHead].cmd;
811
812 /* copy over data to data area if it's valid */
813 /*
814 * Note that for unsol packets we don't want to copy the
815 * data anywhere, so buffer was already set to 0.
816 * For ack_only buffer was set to 0, so don't copy.
817 */
818 if (buffer)
819 memcpy(buffer, adbInbound[adbInHead].data,
820 adbInbound[adbInHead].data[0] + 1);
821
822 #ifdef ADB_DEBUG
823 if (adb_debug & 0x80) {
824 printf_intr("%p %p %p %x ",
825 buffer, comprout, compdata, (short)cmd);
826 printf_intr("buf: ");
827 print_single(adbInbound[adbInHead].data);
828 }
829 #endif
830 /*
831 * Remove the packet from the queue before calling
832 * the completion routine, so that the completion
833 * routine can reentrantly process the queue. For
834 * example, this happens when polling is turned on
835 * by entering the debugger by keystroke.
836 */
837 s = splhigh();
838 adbInCount--;
839 if (++adbInHead >= ADB_QUEUE)
840 adbInHead = 0;
841 splx(s);
842
843 /* call default completion routine if it's valid */
844 if (comprout) {
845 ((int (*)(u_char *, u_char *, int)) comprout)
846 (buffer, compdata, cmd);
847 }
848
849 }
850 }
851
852 #ifndef SMALL_KERNEL
853 void
adb_shutdown(void * arg)854 adb_shutdown(void *arg)
855 {
856 extern int allowpowerdown;
857
858 if (allowpowerdown == 1) {
859 allowpowerdown = 0;
860 prsignal(initprocess, SIGUSR2);
861 }
862 }
863
864 #ifdef SUSPEND
865 void
adb_suspend(void * arg)866 adb_suspend(void *arg)
867 {
868 extern struct cfdriver apm_cd;
869
870 if (apm_cd.cd_ndevs > 0)
871 sleep_state(apm_cd.cd_devs[0], SLEEP_SUSPEND);
872 }
873 #endif
874 #endif /* !SMALL_KERNEL */
875
876 void
adb_lid_closed_intr(void)877 adb_lid_closed_intr(void)
878 {
879 #ifndef SMALL_KERNEL
880 switch (lid_action) {
881 #ifdef SUSPEND
882 case 1:
883 task_add(adb_suspendq, &adb_suspend_task);
884 break;
885 #endif
886 case 2:
887 /* Hibernate. */
888 break;
889 }
890 #endif
891 }
892
893 void
adb_power_button_intr(void)894 adb_power_button_intr(void)
895 {
896 #ifndef SMALL_KERNEL
897 switch (pwr_action) {
898 case 1:
899 task_add(systq, &adb_shutdown_task);
900 break;
901 #ifdef SUSPEND
902 case 2:
903 task_add(adb_suspendq, &adb_suspend_task);
904 break;
905 #endif
906 }
907 #endif
908 }
909
910
911 /*
912 * This is my version of the ADBOp routine. It mainly just calls the
913 * hardware-specific routine.
914 *
915 * data : pointer to data area to be used by compRout
916 * compRout : completion routine
917 * buffer : for LISTEN: points to data to send - MAX 8 data bytes,
918 * byte 0 = # of bytes
919 * : for TALK: points to place to save return data
920 * command : the adb command to send
921 * result : 0 = success
922 * : -1 = could not complete
923 */
924 int
adb_op(Ptr buffer,Ptr compRout,Ptr data,short command)925 adb_op(Ptr buffer, Ptr compRout, Ptr data, short command)
926 {
927 int result;
928
929 switch (adbHardware) {
930 case ADB_HW_PMU:
931 result = pm_adb_op((u_char *)buffer, (void *)compRout,
932 (void *)data, (int)command);
933
934 if (result == 0)
935 return 0;
936 else
937 return -1;
938 break;
939
940 case ADB_HW_CUDA:
941 result = send_adb_cuda(NULL, (u_char *)buffer,
942 (void *)compRout, (void *)data, (int)command);
943 if (result == 0)
944 return 0;
945 else
946 return -1;
947 break;
948
949 default:
950 return -1;
951 }
952 }
953
954
955 /*
956 * adb_hw_setup
957 * This routine sets up the possible machine specific hardware
958 * config (mainly VIA settings) for the various models.
959 */
960 void
adb_hw_setup(void)961 adb_hw_setup(void)
962 {
963 volatile int i;
964
965 switch (adbHardware) {
966
967 case ADB_HW_PMU:
968 /*
969 * XXX - really PM_VIA_CLR_INTR - should we put it in
970 * pm_direct.h?
971 */
972 write_via_reg(VIA1, vIFR, 0x90); /* clear interrupt */
973 break;
974
975 case ADB_HW_CUDA:
976 via_reg_or(VIA1, vDirB, 0x30); /* register B bits 4 and 5:
977 * outputs */
978 via_reg_and(VIA1, vDirB, 0xf7); /* register B bit 3: input */
979 via_reg_and(VIA1, vACR, ~vSR_OUT); /* make sure SR is set
980 * to IN */
981 write_via_reg(VIA1, vACR, (read_via_reg(VIA1, vACR) | 0x0c) & ~0x10);
982 adbActionState = ADB_ACTION_IDLE; /* used by all types of
983 * hardware */
984 write_via_reg(VIA1, vIER, 0x84);/* make sure VIA interrupts
985 * are on */
986 ADB_SET_STATE_IDLE_CUDA(); /* set ADB bus state to idle */
987
988 /* sort of a device reset */
989 i = ADB_SR(); /* clear interrupt */
990 ADB_VIA_INTR_DISABLE(); /* no interrupts while clearing */
991 ADB_SET_STATE_IDLE_CUDA(); /* reset state to idle */
992 delay(ADB_DELAY);
993 ADB_SET_STATE_TIP(); /* signal start of frame */
994 delay(ADB_DELAY);
995 ADB_TOGGLE_STATE_ACK_CUDA();
996 delay(ADB_DELAY);
997 ADB_CLR_STATE_TIP();
998 delay(ADB_DELAY);
999 ADB_SET_STATE_IDLE_CUDA(); /* back to idle state */
1000 i = ADB_SR(); /* clear interrupt */
1001 ADB_VIA_INTR_ENABLE(); /* ints ok now */
1002 break;
1003
1004 case ADB_HW_UNKNOWN:
1005 default:
1006 write_via_reg(VIA1, vIER, 0x04);/* turn interrupts off - TO
1007 * DO: turn PB ints off? */
1008 break;
1009 }
1010 }
1011
1012 /*
1013 * adb_reinit sets up the adb stuff
1014 *
1015 */
1016 void
adb_reinit(struct adb_softc * sc)1017 adb_reinit(struct adb_softc *sc)
1018 {
1019 u_char send_string[ADB_MAX_MSG_LENGTH];
1020 ADBDataBlock data; /* temp. holder for getting device info */
1021 volatile int i, x;
1022 int s;
1023 int command;
1024 int result;
1025 int saveptr; /* point to next free relocation address */
1026 int device;
1027 int nonewtimes; /* times thru loop w/o any new devices */
1028 int ADBNumDevices = 0;
1029
1030 /* Make sure we are not interrupted while building the table. */
1031 if (adbHardware != ADB_HW_PMU) /* ints must be on for PB? */
1032 s = splhigh();
1033
1034 /* Let intr routines know we are running reinit */
1035 adbStarting = 1;
1036
1037 /*
1038 * Initialize the ADB table. For now, we'll always use the same table
1039 * that is defined at the beginning of this file - no mallocs.
1040 */
1041 for (i = 0; i < 16; i++)
1042 sc->sc_devtable[i].handler_id = 0;
1043
1044 adb_hw_setup(); /* init the VIA bits and hard reset ADB */
1045
1046 delay(1000);
1047
1048 /* send an ADB reset first */
1049 adb_op_sync((Ptr)0, (short)0x00);
1050 delay(200000);
1051
1052 /*
1053 * Probe for ADB devices. Probe devices 1-15 quickly to determine
1054 * which device addresses are in use and which are free. For each
1055 * address that is in use, move the device at that address to a higher
1056 * free address. Continue doing this at that address until no device
1057 * responds at that address. Then move the last device that was moved
1058 * back to the original address. Do this for the remaining addresses
1059 * that we determined were in use.
1060 *
1061 * When finished, do this entire process over again with the updated
1062 * list of in use addresses. Do this until no new devices have been
1063 * found in 20 passes though the in use address list. (This probably
1064 * seems long and complicated, but it's the best way to detect multiple
1065 * devices at the same address - sometimes it takes a couple of tries
1066 * before the collision is detected.)
1067 */
1068
1069 /* initial scan through the devices */
1070 for (i = 1; i < 16; i++) {
1071 send_string[0] = 0;
1072 command = ADBTALK(i, 3);
1073 result = adb_op_sync((Ptr)send_string, (short)command);
1074
1075 if (send_string[0] != 0) {
1076 /* check for valid device handler */
1077 switch (send_string[2]) {
1078 case 0:
1079 case 0xfd:
1080 case 0xfe:
1081 case 0xff:
1082 continue; /* invalid, skip */
1083 }
1084
1085 /* found a device */
1086 ++ADBNumDevices;
1087 KASSERT(ADBNumDevices < 16);
1088 sc->sc_devtable[ADBNumDevices].handler_id =
1089 (int)send_string[2];
1090 sc->sc_devtable[ADBNumDevices].orig_addr = i;
1091 sc->sc_devtable[ADBNumDevices].curr_addr = i;
1092 sc->sc_devtable[ADBNumDevices].data = NULL;
1093 sc->sc_devtable[ADBNumDevices].handler = NULL;
1094 }
1095 }
1096
1097 /* find highest unused address */
1098 for (saveptr = 15; saveptr > 0; saveptr--)
1099 if (-1 == get_adb_info(&data, saveptr))
1100 break;
1101
1102 #ifdef ADB_DEBUG
1103 if (adb_debug & 0x80) {
1104 printf_intr("first free is: 0x%02x\n", saveptr);
1105 printf_intr("devices: %i\n", ADBNumDevices);
1106 }
1107 #endif
1108
1109 nonewtimes = 0; /* no loops w/o new devices */
1110 while (saveptr > 0 && nonewtimes++ < 11) {
1111 for (i = 1; i <= ADBNumDevices; i++) {
1112 device = sc->sc_devtable[i].curr_addr;
1113 #ifdef ADB_DEBUG
1114 if (adb_debug & 0x80)
1115 printf_intr("moving device 0x%02x to 0x%02x "
1116 "(index 0x%02x) ", device, saveptr, i);
1117 #endif
1118
1119 /* send TALK R3 to address */
1120 command = ADBTALK(device, 3);
1121 adb_op_sync((Ptr)send_string, (short)command);
1122
1123 /* move device to higher address */
1124 command = ADBLISTEN(device, 3);
1125 send_string[0] = 2;
1126 send_string[1] = (u_char)(saveptr | 0x60);
1127 send_string[2] = 0xfe;
1128 adb_op_sync((Ptr)send_string, (short)command);
1129 delay(500);
1130
1131 /* send TALK R3 - anything at new address? */
1132 command = ADBTALK(saveptr, 3);
1133 adb_op_sync((Ptr)send_string, (short)command);
1134 delay(500);
1135
1136 if (send_string[0] == 0) {
1137 #ifdef ADB_DEBUG
1138 if (adb_debug & 0x80)
1139 printf_intr("failed, continuing\n");
1140 #endif
1141 continue;
1142 }
1143
1144 /* send TALK R3 - anything at old address? */
1145 command = ADBTALK(device, 3);
1146 result = adb_op_sync((Ptr)send_string, (short)command);
1147 if (send_string[0] != 0) {
1148 /* check for valid device handler */
1149 switch (send_string[2]) {
1150 case 0:
1151 case 0xfd:
1152 case 0xfe:
1153 case 0xff:
1154 continue; /* invalid, skip */
1155 }
1156
1157 /* new device found */
1158 /* update data for previously moved device */
1159 sc->sc_devtable[i].curr_addr = saveptr;
1160 #ifdef ADB_DEBUG
1161 if (adb_debug & 0x80)
1162 printf_intr("old device at index %i\n",i);
1163 #endif
1164 /* add new device in table */
1165 #ifdef ADB_DEBUG
1166 if (adb_debug & 0x80)
1167 printf_intr("new device found\n");
1168 #endif
1169 if (saveptr > ADBNumDevices) {
1170 ++ADBNumDevices;
1171 KASSERT(ADBNumDevices < 16);
1172 }
1173 sc->sc_devtable[ADBNumDevices].handler_id =
1174 (int)send_string[2];
1175 sc->sc_devtable[ADBNumDevices].orig_addr = device;
1176 sc->sc_devtable[ADBNumDevices].curr_addr = device;
1177 /* These will be set correctly in adbsys.c */
1178 /* Until then, unsol. data will be ignored. */
1179 sc->sc_devtable[ADBNumDevices].data = NULL;
1180 sc->sc_devtable[ADBNumDevices].handler = NULL;
1181 /* find next unused address */
1182 for (x = saveptr; x > 0; x--) {
1183 if (-1 == get_adb_info(&data, x)) {
1184 saveptr = x;
1185 break;
1186 }
1187 }
1188 if (x == 0)
1189 saveptr = 0;
1190 #ifdef ADB_DEBUG
1191 if (adb_debug & 0x80)
1192 printf_intr("new free is 0x%02x\n",
1193 saveptr);
1194 #endif
1195 nonewtimes = 0;
1196 } else {
1197 #ifdef ADB_DEBUG
1198 if (adb_debug & 0x80)
1199 printf_intr("moving back...\n");
1200 #endif
1201 /* move old device back */
1202 command = ADBLISTEN(saveptr, 3);
1203 send_string[0] = 2;
1204 send_string[1] = (u_char)(device | 0x60);
1205 send_string[2] = 0xfe;
1206 adb_op_sync((Ptr)send_string, (short)command);
1207 delay(1000);
1208 }
1209 }
1210 }
1211
1212 #ifdef ADB_DEBUG
1213 if (adb_debug) {
1214 for (i = 1; i <= ADBNumDevices; i++) {
1215 x = get_ind_adb_info(sc, &data, i);
1216 if (x != -1)
1217 printf_intr("index 0x%x, addr 0x%x, type 0x%x\n",
1218 i, x, data.devType);
1219 }
1220 }
1221 #endif
1222
1223 #ifdef ADB_DEBUG
1224 if (adb_debug) {
1225 if (0 == ADBNumDevices) /* tell user if no devices found */
1226 printf_intr("adb: no devices found\n");
1227 }
1228 #endif
1229
1230 adbStarting = 0; /* not starting anymore */
1231 #ifdef ADB_DEBUG
1232 if (adb_debug)
1233 printf_intr("adb: adb_reinit complete\n");
1234 #endif
1235
1236 if (adbHardware == ADB_HW_CUDA) {
1237 timeout_set(&adb_cuda_timeout, adb_cuda_tickle, NULL);
1238 timeout_add(&adb_cuda_timeout, ADB_TICKLE_TICKS);
1239 }
1240
1241 if (adbHardware != ADB_HW_PMU) /* ints must be on for PB? */
1242 splx(s);
1243 }
1244
1245
1246 /*
1247 * adb_cmd_result
1248 *
1249 * This routine lets the caller know whether the specified adb command string
1250 * should expect a returned result, such as a TALK command.
1251 *
1252 * returns: 0 if a result should be expected
1253 * 1 if a result should NOT be expected
1254 */
1255 int
adb_cmd_result(u_char * in)1256 adb_cmd_result(u_char *in)
1257 {
1258 switch (adbHardware) {
1259 case ADB_HW_CUDA:
1260 /* was it an ADB talk command? */
1261 if ((in[1] == 0x00) && ((in[2] & 0x0c) == 0x0c))
1262 return 0;
1263 /* was it an RTC/PRAM read date/time? */
1264 if ((in[1] == 0x01) && (in[2] == 0x03))
1265 return 0;
1266 return 1;
1267
1268 case ADB_HW_PMU:
1269 return 1;
1270
1271 default:
1272 return 1;
1273 }
1274 }
1275
1276
1277 /*
1278 * adb_op_sync
1279 *
1280 * This routine does exactly what the adb_op routine does, except that after
1281 * the adb_op is called, it waits until the return value is present before
1282 * returning.
1283 */
1284 int
adb_op_sync(Ptr buffer,short command)1285 adb_op_sync(Ptr buffer, short command)
1286 {
1287 int tmout;
1288 int result;
1289 volatile int flag = 0;
1290
1291 result = adb_op(buffer, (void *)adb_op_comprout,
1292 (void *)&flag, command); /* send command */
1293 if (result == 0) { /* send ok? */
1294 /*
1295 * Total time to wait is calculated as follows:
1296 * - Tlt (stop to start time): 260 usec
1297 * - start bit: 100 usec
1298 * - up to 8 data bytes: 64 * 100 usec = 6400 usec
1299 * - stop bit (with SRQ): 140 usec
1300 * Total: 6900 usec
1301 *
1302 * This is the total time allowed by the specification. Any
1303 * device that doesn't conform to this will fail to operate
1304 * properly on some Apple systems. In spite of this we
1305 * double the time to wait; some Cuda-based apparently
1306 * queues some commands and allows the main CPU to continue
1307 * processing (radical concept, eh?). To be safe, allow
1308 * time for two complete ADB transactions to occur.
1309 */
1310 for (tmout = 13800; !flag && tmout >= 10; tmout -= 10)
1311 delay(10);
1312 if (!flag && tmout > 0)
1313 delay(tmout);
1314
1315 if (!flag)
1316 result = -2;
1317 }
1318
1319 return result;
1320 }
1321
1322
1323 /*
1324 * adb_op_comprout
1325 *
1326 * This function is used by the adb_op_sync routine so it knows when the
1327 * function is done.
1328 */
1329 void
adb_op_comprout(caddr_t buffer,caddr_t compdata,int cmd)1330 adb_op_comprout(caddr_t buffer, caddr_t compdata, int cmd)
1331 {
1332 *(int *)compdata = 0x01; /* update flag value */
1333 }
1334
1335 int
count_adbs(struct adb_softc * sc)1336 count_adbs(struct adb_softc *sc)
1337 {
1338 int i;
1339 int found;
1340
1341 found = 0;
1342
1343 for (i = 1; i < 16; i++)
1344 if (0 != sc->sc_devtable[i].handler_id)
1345 found++;
1346
1347 return found;
1348 }
1349
1350 int
get_ind_adb_info(struct adb_softc * sc,ADBDataBlock * info,int index)1351 get_ind_adb_info(struct adb_softc *sc, ADBDataBlock * info, int index)
1352 {
1353 if ((index < 1) || (index > 15)) /* check range 1-15 */
1354 return (-1);
1355
1356 #ifdef ADB_DEBUG
1357 if (adb_debug & 0x80)
1358 printf_intr("index 0x%x handler id 0x%x\n", index,
1359 sc->sc_devtable[index].handler_id);
1360 #endif
1361 if (0 == sc->sc_devtable[index].handler_id) /* make sure it's a valid entry */
1362 return (-1);
1363
1364 info->devType = sc->sc_devtable[index].handler_id;
1365 info->origADBAddr = sc->sc_devtable[index].orig_addr;
1366 info->dbServiceRtPtr = (Ptr)sc->sc_devtable[index].handler;
1367 info->dbDataAreaAddr = (Ptr)sc->sc_devtable[index].data;
1368
1369 return (sc->sc_devtable[index].curr_addr);
1370 }
1371
1372 int
get_adb_info(ADBDataBlock * info,int adbAddr)1373 get_adb_info(ADBDataBlock * info, int adbAddr)
1374 {
1375 struct adb_softc *sc = adb_cd.cd_devs[0];
1376 int i;
1377
1378 if (sc == NULL)
1379 return (-1);
1380
1381 if ((adbAddr < 1) || (adbAddr > 15)) /* check range 1-15 */
1382 return (-1);
1383
1384 for (i = 1; i < 15; i++)
1385 if (sc->sc_devtable[i].curr_addr == adbAddr) {
1386 info->devType = sc->sc_devtable[i].handler_id;
1387 info->origADBAddr = sc->sc_devtable[i].orig_addr;
1388 info->dbServiceRtPtr = (Ptr)sc->sc_devtable[i].handler;
1389 info->dbDataAreaAddr = sc->sc_devtable[i].data;
1390 return 0; /* found */
1391 }
1392
1393 return (-1); /* not found */
1394 }
1395
1396 int
set_adb_info(ADBSetInfoBlock * info,int adbAddr)1397 set_adb_info(ADBSetInfoBlock * info, int adbAddr)
1398 {
1399 struct adb_softc *sc = adb_cd.cd_devs[0];
1400 int i;
1401
1402 if (sc == NULL)
1403 return (-1);
1404
1405 if ((adbAddr < 1) || (adbAddr > 15)) /* check range 1-15 */
1406 return (-1);
1407
1408 for (i = 1; i < 15; i++)
1409 if (sc->sc_devtable[i].curr_addr == adbAddr) {
1410 sc->sc_devtable[i].handler =
1411 (void *)(info->siServiceRtPtr);
1412 sc->sc_devtable[i].data = info->siDataAreaAddr;
1413 return 0; /* found */
1414 }
1415
1416 return (-1); /* not found */
1417
1418 }
1419
1420 /* caller should really use machine-independent version: getPramTime */
1421 /* this version does pseudo-adb access only */
1422 int
adb_read_date_time(time_t * time)1423 adb_read_date_time(time_t *time)
1424 {
1425 u_char output[ADB_MAX_MSG_LENGTH];
1426 int result;
1427 int retcode;
1428 volatile int flag = 0;
1429 u_int32_t t;
1430
1431 switch (adbHardware) {
1432 case ADB_HW_PMU:
1433 pm_read_date_time(time);
1434 retcode = 0;
1435 break;
1436
1437 case ADB_HW_CUDA:
1438 output[0] = 0x02; /* 2 byte message */
1439 output[1] = 0x01; /* to pram/rtc device */
1440 output[2] = 0x03; /* read date/time */
1441 result = send_adb_cuda((u_char *)output, (u_char *)output,
1442 (void *)adb_op_comprout, (void *)&flag, (int)0);
1443 if (result != 0) { /* exit if not sent */
1444 retcode = -1;
1445 break;
1446 }
1447
1448 while (0 == flag) /* wait for result */
1449 ;
1450
1451 delay(20); /* completion occurs too soon? */
1452 memcpy(&t, output + 1, sizeof(t));
1453 *time = (time_t)t;
1454 retcode = 0;
1455 break;
1456
1457 case ADB_HW_UNKNOWN:
1458 default:
1459 retcode = -1;
1460 break;
1461 }
1462 if (retcode == 0) {
1463 #define DIFF19041970 2082844800
1464 *time -= DIFF19041970;
1465
1466 } else {
1467 *time = 0;
1468 }
1469 return retcode;
1470 }
1471
1472 /* caller should really use machine-independent version: setPramTime */
1473 /* this version does pseudo-adb access only */
1474 int
adb_set_date_time(time_t time)1475 adb_set_date_time(time_t time)
1476 {
1477 u_char output[ADB_MAX_MSG_LENGTH];
1478 int result;
1479 volatile int flag = 0;
1480 u_int32_t t;
1481
1482 time += DIFF19041970;
1483 switch (adbHardware) {
1484
1485 case ADB_HW_CUDA:
1486 t = time; /* XXX eventually truncates */
1487
1488 output[0] = 0x06; /* 6 byte message */
1489 output[1] = 0x01; /* to pram/rtc device */
1490 output[2] = 0x09; /* set date/time */
1491 output[3] = (u_char)(t >> 24);
1492 output[4] = (u_char)(t >> 16);
1493 output[5] = (u_char)(t >> 8);
1494 output[6] = (u_char)(t);
1495 result = send_adb_cuda((u_char *)output, NULL,
1496 (void *)adb_op_comprout, (void *)&flag, (int)0);
1497 if (result != 0) /* exit if not sent */
1498 return -1;
1499
1500 while (0 == flag) /* wait for send to finish */
1501 ;
1502
1503 return 0;
1504
1505 case ADB_HW_PMU:
1506 pm_set_date_time(time);
1507 return 0;
1508
1509 default:
1510 return -1;
1511 }
1512 }
1513
1514
1515 int
adb_poweroff(void)1516 adb_poweroff(void)
1517 {
1518 u_char output[ADB_MAX_MSG_LENGTH];
1519 int result;
1520
1521 adb_polling = 1;
1522
1523 switch (adbHardware) {
1524 case ADB_HW_PMU:
1525 /* Clear the wake on AC loss event */
1526 pmu_fileserver_mode(0);
1527 pm_adb_poweroff();
1528
1529 for (;;) /* wait for power off */
1530 ;
1531
1532 return 0;
1533
1534 case ADB_HW_CUDA:
1535 output[0] = 0x02; /* 2 byte message */
1536 output[1] = 0x01; /* to pram/rtc/soft-power device */
1537 output[2] = 0x0a; /* set poweroff */
1538 result = send_adb_cuda((u_char *)output, NULL,
1539 NULL, NULL, (int)0);
1540 if (result != 0) /* exit if not sent */
1541 return -1;
1542
1543 for (;;) /* wait for power off */
1544 ;
1545
1546 return 0;
1547
1548 default:
1549 return -1;
1550 }
1551 }
1552
1553 void
setsoftadb(void)1554 setsoftadb(void)
1555 {
1556 if (!timeout_initialized(&adb_softintr_timeout))
1557 timeout_set(&adb_softintr_timeout, (void *)adb_soft_intr, NULL);
1558 timeout_add(&adb_softintr_timeout, 1);
1559 }
1560
1561 void
adb_cuda_autopoll(void)1562 adb_cuda_autopoll(void)
1563 {
1564 volatile int flag = 0;
1565 int result;
1566 u_char output[16];
1567
1568 output[0] = 0x03; /* 3-byte message */
1569 output[1] = 0x01; /* to pram/rtc/soft-power device */
1570 output[2] = 0x01; /* cuda autopoll */
1571 output[3] = 0x01;
1572 result = send_adb_cuda(output, output, adb_op_comprout,
1573 (void *)&flag, 0);
1574 if (result != 0) /* exit if not sent */
1575 return;
1576
1577 while (flag == 0); /* wait for result */
1578 }
1579
1580 void
adb_cuda_fileserver_mode(void)1581 adb_cuda_fileserver_mode(void)
1582 {
1583 volatile int flag = 0;
1584 int result;
1585 u_char output[16];
1586
1587 output[0] = 0x03; /* 3-byte message */
1588 output[1] = 0x01; /* to pram/rtc device/soft-power device */
1589 output[2] = 0x13; /* cuda file server mode */
1590 output[3] = 0x01; /* True - Turn on after AC loss */
1591
1592 result = send_adb_cuda(output, output, adb_op_comprout,
1593 (void *)&flag, 0);
1594 if (result != 0)
1595 return;
1596
1597 while (flag == 0);
1598 }
1599
1600 void
adb_restart(void)1601 adb_restart(void)
1602 {
1603 int result;
1604 u_char output[16];
1605
1606 adb_polling = 1;
1607
1608 switch (adbHardware) {
1609 case ADB_HW_CUDA:
1610 output[0] = 0x02; /* 2 byte message */
1611 output[1] = 0x01; /* to pram/rtc/soft-power device */
1612 output[2] = 0x11; /* restart */
1613 result = send_adb_cuda((u_char *)output, NULL,
1614 NULL, NULL, (int)0);
1615 if (result != 0) /* exit if not sent */
1616 return;
1617 while (1); /* not return */
1618
1619 case ADB_HW_PMU:
1620 pm_adb_restart();
1621 while (1); /* not return */
1622 }
1623 }
1624
1625 /*
1626 * Driver definition.
1627 */
1628
1629 int adbmatch(struct device *, void *, void *);
1630 void adbattach(struct device *, struct device *, void *);
1631
1632 const struct cfattach adb_ca = {
1633 sizeof(struct adb_softc), adbmatch, adbattach
1634 };
1635
1636 int
adbmatch(struct device * parent,void * cf,void * aux)1637 adbmatch(struct device *parent, void *cf, void *aux)
1638 {
1639 struct confargs *ca = aux;
1640
1641 if (ca->ca_nreg < 8)
1642 return 0;
1643
1644 if (ca->ca_nintr < 4)
1645 return 0;
1646
1647 if (strcmp(ca->ca_name, "via-cuda") == 0)
1648 return 1;
1649
1650 if (strcmp(ca->ca_name, "via-pmu") == 0)
1651 return 1;
1652
1653 return 0;
1654 }
1655
1656 void
adbattach(struct device * parent,struct device * self,void * aux)1657 adbattach(struct device *parent, struct device *self, void *aux)
1658 {
1659 struct adb_softc *sc = (struct adb_softc *)self;
1660 struct confargs *ca = aux;
1661 struct confargs nca;
1662 char name[32];
1663 int node;
1664 ADBDataBlock adbdata;
1665 struct adb_attach_args aa_args;
1666 int totaladbs;
1667 int adbindex, adbaddr;
1668
1669 #if !defined(SMALL_KERNEL) && defined(SUSPEND)
1670 adb_suspendq = taskq_create(sc->sc_dev.dv_xname, 1, IPL_TTY, 0);
1671 if (adb_suspendq == NULL) {
1672 printf(": can't create taskq\n");
1673 return;
1674 }
1675 #endif
1676
1677 ca->ca_reg[0] += ca->ca_baseaddr;
1678
1679 sc->sc_regbase = mapiodev(ca->ca_reg[0], ca->ca_reg[1]);
1680 Via1Base = sc->sc_regbase;
1681
1682 if (strcmp(ca->ca_name, "via-cuda") == 0)
1683 adbHardware = ADB_HW_CUDA;
1684 else if (strcmp(ca->ca_name, "via-pmu") == 0) {
1685 adbHardware = ADB_HW_PMU;
1686 pm_in_adbattach(sc->sc_dev.dv_xname);
1687
1688 /*
1689 * Bus reset can take a long time if no adb devices are
1690 * connected, e.g. on a Mac Mini; so check for an adb
1691 * child in the OF tree to speed up pm_adb_op().
1692 */
1693 adbempty = 1;
1694 for (node = OF_child(ca->ca_node); node; node = OF_peer(node)) {
1695 if (OF_getprop(node, "name", name, sizeof name) <= 0)
1696 continue;
1697 if (strcmp(name, "adb") == 0) {
1698 adbempty = 0;
1699 break;
1700 }
1701 }
1702 }
1703
1704 adb_polling = 1;
1705 if (!adbempty) {
1706 adb_reinit(sc);
1707 totaladbs = count_adbs(sc);
1708 printf(": irq %d, %s, %d target%s", ca->ca_intr[0], ca->ca_name,
1709 totaladbs, (totaladbs == 1) ? "" : "s");
1710 }
1711 printf("\n");
1712
1713 mac_intr_establish(parent, ca->ca_intr[0], IST_LEVEL, IPL_TTY,
1714 adb_intr, sc, sc->sc_dev.dv_xname);
1715
1716 /* init powerpc globals which control RTC functionality */
1717 time_read = adb_read_date_time;
1718 time_write = adb_set_date_time;
1719
1720 #if NAPM > 0
1721 if (adbHardware == ADB_HW_PMU) {
1722 /* Magic for signalling the apm driver to match. */
1723 nca.ca_name = "apm";
1724 nca.ca_node = node;
1725 config_found(self, &nca, NULL);
1726 }
1727 #endif
1728
1729 /* Attach I2C controller. */
1730 for (node = OF_child(ca->ca_node); node; node = OF_peer(node)) {
1731 if (OF_getprop(node, "name", name, sizeof name) <= 0)
1732 continue;
1733 if (strcmp(name, "pmu-i2c") == 0) {
1734 nca.ca_name = "piic";
1735 nca.ca_node = node;
1736 config_found(self, &nca, NULL);
1737 }
1738 }
1739
1740 if (adbHardware == ADB_HW_CUDA)
1741 adb_cuda_fileserver_mode();
1742 if (adbHardware == ADB_HW_PMU) {
1743 wskbd_get_backlight = pmu_get_backlight;
1744 wskbd_set_backlight = pmu_set_backlight;
1745 pmu_fileserver_mode(1);
1746 }
1747
1748 /*
1749 * XXX If the machine doesn't have an ADB bus (PowerBook5,6+)
1750 * yes it sounds stupid to attach adb(4), but don't try to send
1751 * ADB commands otherwise the PMU may shutdown the machine...
1752 */
1753 if (adbempty)
1754 return;
1755
1756 /* for each ADB device */
1757 for (adbindex = 1; adbindex <= totaladbs; adbindex++) {
1758 /* Get the ADB information */
1759 adbaddr = get_ind_adb_info(sc, &adbdata, adbindex);
1760
1761 aa_args.name = adb_device_name;
1762 aa_args.origaddr = adbdata.origADBAddr;
1763 aa_args.adbaddr = adbaddr;
1764 aa_args.handler_id = adbdata.devType;
1765
1766 (void)config_found(self, &aa_args, adbprint);
1767 }
1768
1769 if (adbHardware == ADB_HW_CUDA)
1770 adb_cuda_autopoll();
1771 adb_polling = 0;
1772 }
1773
1774 int
pmu_get_backlight(struct wskbd_backlight * kbl)1775 pmu_get_backlight(struct wskbd_backlight *kbl)
1776 {
1777 kbl->min = 0;
1778 kbl->max = 0xff;
1779 kbl->curval = pmu_backlight;
1780 return 0;
1781 }
1782
1783 int
pmu_set_backlight(struct wskbd_backlight * kbl)1784 pmu_set_backlight(struct wskbd_backlight *kbl)
1785 {
1786 pmu_backlight = kbl->curval;
1787 return pmu_set_kbl(pmu_backlight);
1788 }
1789