1 /* $NetBSD: adb.c,v 1.41 2001/11/20 03:19:41 chs Exp $ */ 2 3 /* 4 * Copyright (C) 1994 Bradley A. Grantham 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. All advertising materials mentioning features or use of this software 16 * must display the following acknowledgement: 17 * This product includes software developed by Bradley A. Grantham. 18 * 4. The name of the author may not be used to endorse or promote products 19 * derived from this software without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 22 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 23 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 24 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 26 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 */ 32 33 #include "opt_adb.h" 34 35 #include <sys/param.h> 36 #include <sys/device.h> 37 #include <sys/fcntl.h> 38 #include <sys/poll.h> 39 #include <sys/select.h> 40 #include <sys/proc.h> 41 #include <sys/signalvar.h> 42 #include <sys/systm.h> 43 44 #include <machine/autoconf.h> 45 #include <machine/cpu.h> 46 47 #include <mac68k/mac68k/macrom.h> 48 #include <mac68k/dev/adbvar.h> 49 #include <mac68k/dev/akbdvar.h> 50 51 #include "aed.h" /* ADB Event Device for compatibility */ 52 53 /* 54 * Function declarations. 55 */ 56 static int adbmatch __P((struct device *, struct cfdata *, void *)); 57 static void adbattach __P((struct device *, struct device *, void *)); 58 static int adbprint __P((void *, const char *)); 59 void adb_config_interrupts __P((struct device *)); 60 61 extern void adb_jadbproc __P((void)); 62 63 /* 64 * Global variables. 65 */ 66 int adb_polling = 0; /* Are we polling? (Debugger mode) */ 67 #ifdef ADB_DEBUG 68 int adb_debug = 0; /* Output debugging messages */ 69 #endif /* ADB_DEBUG */ 70 71 extern struct mac68k_machine_S mac68k_machine; 72 extern int adbHardware; 73 extern char *adbHardwareDescr[]; 74 75 /* 76 * Driver definition. 77 */ 78 struct cfattach adb_ca = { 79 sizeof(struct device), adbmatch, adbattach 80 }; 81 82 static int 83 adbmatch(parent, cf, aux) 84 struct device *parent; 85 struct cfdata *cf; 86 void *aux; 87 { 88 static int adb_matched = 0; 89 90 /* Allow only one instance. */ 91 if (adb_matched) 92 return (0); 93 94 adb_matched = 1; 95 return (1); 96 } 97 98 static void 99 adbattach(parent, self, aux) 100 struct device *parent, *self; 101 void *aux; 102 { 103 printf("\n"); 104 105 /* 106 * Defer configuration until interrupts are enabled. 107 */ 108 config_interrupts(self, adb_config_interrupts); 109 } 110 111 void 112 adb_config_interrupts(self) 113 struct device *self; 114 { 115 ADBDataBlock adbdata; 116 struct adb_attach_args aa_args; 117 int totaladbs; 118 int adbindex, adbaddr; 119 120 printf("%s", self->dv_xname); 121 adb_polling = 1; 122 123 #ifdef MRG_ADB 124 if (!mrg_romready()) { 125 printf(": no ROM ADB driver in this kernel for this machine\n"); 126 return; 127 } 128 129 #ifdef ADB_DEBUG 130 if (adb_debug) 131 printf("adb: call mrg_initadbintr\n"); 132 #endif 133 134 mrg_initadbintr(); /* Mac ROM Glue okay to do ROM intr */ 135 #ifdef ADB_DEBUG 136 if (adb_debug) 137 printf("adb: returned from mrg_initadbintr\n"); 138 #endif 139 140 /* ADBReInit pre/post-processing */ 141 JADBProc = adb_jadbproc; 142 143 /* Initialize ADB */ 144 #ifdef ADB_DEBUG 145 if (adb_debug) 146 printf("adb: calling ADBAlternateInit.\n"); 147 #endif 148 149 printf(" (mrg)"); 150 ADBAlternateInit(); 151 #else 152 ADBReInit(); 153 printf(" (direct, %s)", adbHardwareDescr[adbHardware]); 154 #endif /* MRG_ADB */ 155 156 #ifdef ADB_DEBUG 157 if (adb_debug) 158 printf("adb: done with ADBReInit\n"); 159 #endif 160 161 totaladbs = CountADBs(); 162 163 printf(": %d target%s\n", totaladbs, (totaladbs == 1) ? "" : "s"); 164 165 #if NAED > 0 166 /* ADB event device for compatibility */ 167 aa_args.origaddr = 0; 168 aa_args.adbaddr = 0; 169 aa_args.handler_id = 0; 170 (void)config_found(self, &aa_args, adbprint); 171 #endif 172 173 /* for each ADB device */ 174 for (adbindex = 1; adbindex <= totaladbs; adbindex++) { 175 /* Get the ADB information */ 176 adbaddr = GetIndADB(&adbdata, adbindex); 177 178 aa_args.origaddr = (int)(adbdata.origADBAddr); 179 aa_args.adbaddr = adbaddr; 180 aa_args.handler_id = (int)(adbdata.devType); 181 182 (void)config_found(self, &aa_args, adbprint); 183 } 184 adb_polling = 0; 185 } 186 187 188 int 189 adbprint(args, name) 190 void *args; 191 const char *name; 192 { 193 struct adb_attach_args *aa_args = (struct adb_attach_args *)args; 194 int rv = UNCONF; 195 196 if (name) { /* no configured device matched */ 197 rv = UNSUPP; /* most ADB device types are unsupported */ 198 199 /* print out what kind of ADB device we have found */ 200 printf("%s addr %d: ", name, aa_args->adbaddr); 201 switch(aa_args->origaddr) { 202 #ifdef DIAGNOSTIC 203 case 0: 204 printf("ADB event device"); 205 rv = UNCONF; 206 break; 207 case ADBADDR_SECURE: 208 printf("security dongle (%d)", aa_args->handler_id); 209 break; 210 #endif 211 case ADBADDR_MAP: 212 printf("mapped device (%d)", aa_args->handler_id); 213 rv = UNCONF; 214 break; 215 case ADBADDR_REL: 216 printf("relative positioning device (%d)", 217 aa_args->handler_id); 218 rv = UNCONF; 219 break; 220 #ifdef DIAGNOSTIC 221 case ADBADDR_ABS: 222 switch (aa_args->handler_id) { 223 case ADB_ARTPAD: 224 printf("WACOM ArtPad II"); 225 break; 226 default: 227 printf("absolute positioning device (%d)", 228 aa_args->handler_id); 229 break; 230 } 231 break; 232 case ADBADDR_DATATX: 233 printf("data transfer device (modem?) (%d)", 234 aa_args->handler_id); 235 break; 236 case ADBADDR_MISC: 237 switch (aa_args->handler_id) { 238 case ADB_POWERKEY: 239 printf("Sophisticated Circuits PowerKey"); 240 break; 241 default: 242 printf("misc. device (remote control?) (%d)", 243 aa_args->handler_id); 244 break; 245 } 246 break; 247 default: 248 printf("unknown type device, (handler %d)", 249 aa_args->handler_id); 250 break; 251 #endif /* DIAGNOSTIC */ 252 } 253 } else /* a device matched and was configured */ 254 printf(" addr %d: ", aa_args->adbaddr); 255 256 return (rv); 257 } 258 259 260 /* 261 * adb_op_sync 262 * 263 * This routine does exactly what the adb_op routine does, except that after 264 * the adb_op is called, it waits until the return value is present before 265 * returning. 266 * 267 * NOTE: The user specified compRout is ignored, since this routine specifies 268 * it's own to adb_op, which is why you really called this in the first place 269 * anyway. 270 */ 271 int 272 adb_op_sync(Ptr buffer, Ptr compRout, Ptr data, short command) 273 { 274 int tmout; 275 int result; 276 volatile int flag = 0; 277 278 result = ADBOp(buffer, (void *)adb_op_comprout, 279 (void *)&flag, command); /* send command */ 280 if (result == 0) { /* send ok? */ 281 /* 282 * Total time to wait is calculated as follows: 283 * - Tlt (stop to start time): 260 usec 284 * - start bit: 100 usec 285 * - up to 8 data bytes: 64 * 100 usec = 6400 usec 286 * - stop bit (with SRQ): 140 usec 287 * Total: 6900 usec 288 * 289 * This is the total time allowed by the specification. Any 290 * device that doesn't conform to this will fail to operate 291 * properly on some Apple systems. In spite of this we 292 * double the time to wait; some Cuda-based apparently 293 * queues some commands and allows the main CPU to continue 294 * processing (radical concept, eh?). To be safe, allow 295 * time for two complete ADB transactions to occur. 296 */ 297 for (tmout = 13800; !flag && tmout >= 10; tmout -= 10) 298 delay(10); 299 if (!flag && tmout > 0) 300 delay(tmout); 301 302 if (!flag) 303 result = -2; 304 } 305 306 return result; 307 } 308 309 310 /* 311 * adb_op_comprout 312 * 313 * This function is used by the adb_op_sync routine so it knows when the 314 * function is done. 315 */ 316 void 317 adb_op_comprout(void) 318 { 319 #ifdef __NetBSD__ 320 asm("movw #1,%a2@ | update flag value"); 321 #else /* for macos based testing */ 322 asm { 323 move.w #1,(a2) } /* update flag value */ 324 #endif 325 } 326