1 /* $NetBSD: adb.c,v 1.52 2008/04/03 05:03:23 scottr 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.52 2008/04/03 05:03:23 scottr 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 #include <sys/cpu.h> 47 #include <sys/intr.h> 48 49 #include <machine/autoconf.h> 50 51 #include <mac68k/mac68k/macrom.h> 52 #include <mac68k/dev/adbvar.h> 53 #include <mac68k/dev/akbdvar.h> 54 55 #include "aed.h" /* ADB Event Device for compatibility */ 56 57 /* 58 * Function declarations. 59 */ 60 static int adbmatch(struct device *, struct cfdata *, void *); 61 static void adbattach(struct device *, struct device *, void *); 62 static int adbprint(void *, const char *); 63 void adb_config_interrupts(struct device *); 64 65 extern void adb_jadbproc(void); 66 67 /* 68 * Global variables. 69 */ 70 int adb_polling = 0; /* Are we polling? (Debugger mode) */ 71 #ifdef ADB_DEBUG 72 int adb_debug = 0; /* Output debugging messages */ 73 #endif /* ADB_DEBUG */ 74 75 extern struct mac68k_machine_S mac68k_machine; 76 extern int adbHardware; 77 extern char *adbHardwareDescr[]; 78 79 /* 80 * Driver definition. 81 */ 82 CFATTACH_DECL(adb, sizeof(struct device), 83 adbmatch, adbattach, NULL, NULL); 84 85 static int 86 adbmatch(struct device *parent, struct cfdata *cf, 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(struct device *parent, struct device *self, void *aux) 100 { 101 102 adb_softintr_cookie = softint_establish(SOFTINT_SERIAL, 103 (void (*)(void *))adb_soft_intr, NULL); 104 printf("\n"); 105 106 /* 107 * Defer configuration until interrupts are enabled. 108 */ 109 config_interrupts(self, adb_config_interrupts); 110 } 111 112 void 113 adb_config_interrupts(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(void *args, const char *name) 190 { 191 struct adb_attach_args *aa_args = (struct adb_attach_args *)args; 192 int rv = UNCONF; 193 194 if (name) { /* no configured device matched */ 195 rv = UNSUPP; /* most ADB device types are unsupported */ 196 197 /* print out what kind of ADB device we have found */ 198 aprint_normal("%s addr %d: ", name, aa_args->adbaddr); 199 switch(aa_args->origaddr) { 200 #ifdef DIAGNOSTIC 201 case 0: 202 aprint_normal("ADB event device"); 203 rv = UNCONF; 204 break; 205 case ADBADDR_SECURE: 206 aprint_normal("security dongle (%d)", 207 aa_args->handler_id); 208 break; 209 #endif 210 case ADBADDR_MAP: 211 aprint_normal("mapped device (%d)", 212 aa_args->handler_id); 213 rv = UNCONF; 214 break; 215 case ADBADDR_REL: 216 aprint_normal("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 aprint_normal("WACOM ArtPad II"); 225 break; 226 default: 227 aprint_normal("absolute positioning device (%d)", 228 aa_args->handler_id); 229 break; 230 } 231 break; 232 case ADBADDR_DATATX: 233 aprint_normal("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 aprint_normal("Sophisticated Circuits PowerKey"); 240 break; 241 default: 242 aprint_normal("misc. device (remote control?) (%d)", 243 aa_args->handler_id); 244 break; 245 } 246 break; 247 default: 248 aprint_normal("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 aprint_normal(" 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 result; 275 volatile int flag = 0; 276 277 result = ADBOp(buffer, (void *)adb_op_comprout, __UNVOLATILE(&flag), 278 command); /* send command */ 279 if (result == 0) { /* send ok? */ 280 adb_spin(&flag); 281 if (!flag) 282 result = -2; 283 } 284 285 return result; 286 } 287 288 /* 289 * adb_spin 290 * 291 * Implements a spin-wait with timeout to be used for synchronous 292 * operations on the ADB bus. 293 * 294 * Total time to wait is calculated as follows: 295 * - Tlt (stop to start time): 260 usec 296 * - start bit: 100 usec 297 * - up to 8 data bytes: 64 * 100 usec = 6400 usec 298 * - stop bit (with SRQ): 140 usec 299 * Total: 6900 usec 300 * 301 * This is the total time allowed by the specification. Any device that 302 * doesn't conform to this will fail to operate properly on some Apple 303 * systems. In spite of this we double the time to wait; Cuda-based 304 * systems apparently queue commands and allow the main CPU to continue 305 * processing (how radical!). To be safe, allow time for two complete 306 * ADB transactions to occur. 307 */ 308 void 309 adb_spin(volatile int *fp) 310 { 311 int tmout; 312 313 for (tmout = 13800; *fp == 0 && tmout >= 10; tmout -= 10) 314 delay(10); 315 if (*fp == 0 && tmout > 0) 316 delay(tmout); 317 } 318 319 320 /* 321 * adb_op_comprout 322 * 323 * This function is used by the adb_op_sync routine so it knows when the 324 * function is done. 325 */ 326 void 327 adb_op_comprout(void) 328 { 329 __asm("movw #1,%a2@ | update flag value"); 330 } 331