1 /* $NetBSD: adb.c,v 1.45 2003/07/15 02:43:15 lukem 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 <sys/cdefs.h> 34 __KERNEL_RCSID(0, "$NetBSD: adb.c,v 1.45 2003/07/15 02:43:15 lukem Exp $"); 35 36 #include "opt_adb.h" 37 38 #include <sys/param.h> 39 #include <sys/device.h> 40 #include <sys/fcntl.h> 41 #include <sys/poll.h> 42 #include <sys/select.h> 43 #include <sys/proc.h> 44 #include <sys/signalvar.h> 45 #include <sys/systm.h> 46 47 #include <machine/autoconf.h> 48 #include <machine/cpu.h> 49 50 #include <mac68k/mac68k/macrom.h> 51 #include <mac68k/dev/adbvar.h> 52 #include <mac68k/dev/akbdvar.h> 53 54 #include "aed.h" /* ADB Event Device for compatibility */ 55 56 /* 57 * Function declarations. 58 */ 59 static int adbmatch __P((struct device *, struct cfdata *, void *)); 60 static void adbattach __P((struct device *, struct device *, void *)); 61 static int adbprint __P((void *, const char *)); 62 void adb_config_interrupts __P((struct device *)); 63 64 extern void adb_jadbproc __P((void)); 65 66 /* 67 * Global variables. 68 */ 69 int adb_polling = 0; /* Are we polling? (Debugger mode) */ 70 #ifdef ADB_DEBUG 71 int adb_debug = 0; /* Output debugging messages */ 72 #endif /* ADB_DEBUG */ 73 74 extern struct mac68k_machine_S mac68k_machine; 75 extern int adbHardware; 76 extern char *adbHardwareDescr[]; 77 78 /* 79 * Driver definition. 80 */ 81 CFATTACH_DECL(adb, sizeof(struct device), 82 adbmatch, adbattach, NULL, NULL); 83 84 static int 85 adbmatch(parent, cf, aux) 86 struct device *parent; 87 struct cfdata *cf; 88 void *aux; 89 { 90 static int adb_matched = 0; 91 92 /* Allow only one instance. */ 93 if (adb_matched) 94 return (0); 95 96 adb_matched = 1; 97 return (1); 98 } 99 100 static void 101 adbattach(parent, self, aux) 102 struct device *parent, *self; 103 void *aux; 104 { 105 printf("\n"); 106 107 /* 108 * Defer configuration until interrupts are enabled. 109 */ 110 config_interrupts(self, adb_config_interrupts); 111 } 112 113 void 114 adb_config_interrupts(self) 115 struct device *self; 116 { 117 ADBDataBlock adbdata; 118 struct adb_attach_args aa_args; 119 int totaladbs; 120 int adbindex, adbaddr; 121 122 printf("%s", self->dv_xname); 123 adb_polling = 1; 124 125 #ifdef MRG_ADB 126 if (!mrg_romready()) { 127 printf(": no ROM ADB driver in this kernel for this machine\n"); 128 return; 129 } 130 131 #ifdef ADB_DEBUG 132 if (adb_debug) 133 printf("adb: call mrg_initadbintr\n"); 134 #endif 135 136 mrg_initadbintr(); /* Mac ROM Glue okay to do ROM intr */ 137 #ifdef ADB_DEBUG 138 if (adb_debug) 139 printf("adb: returned from mrg_initadbintr\n"); 140 #endif 141 142 /* ADBReInit pre/post-processing */ 143 JADBProc = adb_jadbproc; 144 145 /* Initialize ADB */ 146 #ifdef ADB_DEBUG 147 if (adb_debug) 148 printf("adb: calling ADBAlternateInit.\n"); 149 #endif 150 151 printf(" (mrg)"); 152 ADBAlternateInit(); 153 #else 154 ADBReInit(); 155 printf(" (direct, %s)", adbHardwareDescr[adbHardware]); 156 #endif /* MRG_ADB */ 157 158 #ifdef ADB_DEBUG 159 if (adb_debug) 160 printf("adb: done with ADBReInit\n"); 161 #endif 162 163 totaladbs = CountADBs(); 164 165 printf(": %d target%s\n", totaladbs, (totaladbs == 1) ? "" : "s"); 166 167 #if NAED > 0 168 /* ADB event device for compatibility */ 169 aa_args.origaddr = 0; 170 aa_args.adbaddr = 0; 171 aa_args.handler_id = 0; 172 (void)config_found(self, &aa_args, adbprint); 173 #endif 174 175 /* for each ADB device */ 176 for (adbindex = 1; adbindex <= totaladbs; adbindex++) { 177 /* Get the ADB information */ 178 adbaddr = GetIndADB(&adbdata, adbindex); 179 180 aa_args.origaddr = (int)(adbdata.origADBAddr); 181 aa_args.adbaddr = adbaddr; 182 aa_args.handler_id = (int)(adbdata.devType); 183 184 (void)config_found(self, &aa_args, adbprint); 185 } 186 adb_polling = 0; 187 } 188 189 190 int 191 adbprint(args, name) 192 void *args; 193 const char *name; 194 { 195 struct adb_attach_args *aa_args = (struct adb_attach_args *)args; 196 int rv = UNCONF; 197 198 if (name) { /* no configured device matched */ 199 rv = UNSUPP; /* most ADB device types are unsupported */ 200 201 /* print out what kind of ADB device we have found */ 202 aprint_normal("%s addr %d: ", name, aa_args->adbaddr); 203 switch(aa_args->origaddr) { 204 #ifdef DIAGNOSTIC 205 case 0: 206 aprint_normal("ADB event device"); 207 rv = UNCONF; 208 break; 209 case ADBADDR_SECURE: 210 aprint_normal("security dongle (%d)", 211 aa_args->handler_id); 212 break; 213 #endif 214 case ADBADDR_MAP: 215 aprint_normal("mapped device (%d)", 216 aa_args->handler_id); 217 rv = UNCONF; 218 break; 219 case ADBADDR_REL: 220 aprint_normal("relative positioning device (%d)", 221 aa_args->handler_id); 222 rv = UNCONF; 223 break; 224 #ifdef DIAGNOSTIC 225 case ADBADDR_ABS: 226 switch (aa_args->handler_id) { 227 case ADB_ARTPAD: 228 aprint_normal("WACOM ArtPad II"); 229 break; 230 default: 231 aprint_normal("absolute positioning device (%d)", 232 aa_args->handler_id); 233 break; 234 } 235 break; 236 case ADBADDR_DATATX: 237 aprint_normal("data transfer device (modem?) (%d)", 238 aa_args->handler_id); 239 break; 240 case ADBADDR_MISC: 241 switch (aa_args->handler_id) { 242 case ADB_POWERKEY: 243 aprint_normal("Sophisticated Circuits PowerKey"); 244 break; 245 default: 246 aprint_normal("misc. device (remote control?) (%d)", 247 aa_args->handler_id); 248 break; 249 } 250 break; 251 default: 252 aprint_normal("unknown type device, (handler %d)", 253 aa_args->handler_id); 254 break; 255 #endif /* DIAGNOSTIC */ 256 } 257 } else /* a device matched and was configured */ 258 aprint_normal(" addr %d: ", aa_args->adbaddr); 259 260 return (rv); 261 } 262 263 264 /* 265 * adb_op_sync 266 * 267 * This routine does exactly what the adb_op routine does, except that after 268 * the adb_op is called, it waits until the return value is present before 269 * returning. 270 * 271 * NOTE: The user specified compRout is ignored, since this routine specifies 272 * it's own to adb_op, which is why you really called this in the first place 273 * anyway. 274 */ 275 int 276 adb_op_sync(Ptr buffer, Ptr compRout, Ptr data, short command) 277 { 278 int tmout; 279 int result; 280 volatile int flag = 0; 281 282 result = ADBOp(buffer, (void *)adb_op_comprout, 283 (void *)&flag, command); /* send command */ 284 if (result == 0) { /* send ok? */ 285 /* 286 * Total time to wait is calculated as follows: 287 * - Tlt (stop to start time): 260 usec 288 * - start bit: 100 usec 289 * - up to 8 data bytes: 64 * 100 usec = 6400 usec 290 * - stop bit (with SRQ): 140 usec 291 * Total: 6900 usec 292 * 293 * This is the total time allowed by the specification. Any 294 * device that doesn't conform to this will fail to operate 295 * properly on some Apple systems. In spite of this we 296 * double the time to wait; some Cuda-based apparently 297 * queues some commands and allows the main CPU to continue 298 * processing (radical concept, eh?). To be safe, allow 299 * time for two complete ADB transactions to occur. 300 */ 301 for (tmout = 13800; !flag && tmout >= 10; tmout -= 10) 302 delay(10); 303 if (!flag && tmout > 0) 304 delay(tmout); 305 306 if (!flag) 307 result = -2; 308 } 309 310 return result; 311 } 312 313 314 /* 315 * adb_op_comprout 316 * 317 * This function is used by the adb_op_sync routine so it knows when the 318 * function is done. 319 */ 320 void 321 adb_op_comprout(void) 322 { 323 #ifdef __NetBSD__ 324 asm("movw #1,%a2@ | update flag value"); 325 #else /* for macos based testing */ 326 asm { 327 move.w #1,(a2) } /* update flag value */ 328 #endif 329 } 330