1 /* $NetBSD: adb.c,v 1.15 2003/07/15 02:43:26 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.15 2003/07/15 02:43:26 lukem Exp $"); 35 36 #include <sys/param.h> 37 #include <sys/device.h> 38 #include <sys/fcntl.h> 39 #include <sys/poll.h> 40 #include <sys/select.h> 41 #include <sys/proc.h> 42 #include <sys/signalvar.h> 43 #include <sys/systm.h> 44 45 #include <machine/autoconf.h> 46 47 #include <macppc/dev/adbvar.h> 48 #include <macppc/dev/akbdvar.h> 49 #include <macppc/dev/viareg.h> 50 51 #include <dev/ofw/openfirm.h> 52 53 #include "aed.h" 54 #include "apm.h" 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 63 /* 64 * Global variables. 65 */ 66 int adb_polling = 0; /* Are we polling? (Debugger mode) */ 67 int adb_initted = 0; /* adb_init() has completed successfully */ 68 #ifdef ADB_DEBUG 69 int adb_debug = 0; /* Output debugging messages */ 70 #endif /* ADB_DEBUG */ 71 72 /* 73 * Driver definition. 74 */ 75 CFATTACH_DECL(adb, sizeof(struct adb_softc), 76 adbmatch, adbattach, NULL, NULL); 77 78 static int 79 adbmatch(parent, cf, aux) 80 struct device *parent; 81 struct cfdata *cf; 82 void *aux; 83 { 84 struct confargs *ca = aux; 85 86 if (ca->ca_nreg < 8) 87 return 0; 88 89 if (ca->ca_nintr < 4) 90 return 0; 91 92 if (strcmp(ca->ca_name, "via-cuda") == 0) 93 return 1; 94 95 if (strcmp(ca->ca_name, "via-pmu") == 0) 96 return 1; 97 98 return 0; 99 } 100 101 static void 102 adbattach(parent, self, aux) 103 struct device *parent, *self; 104 void *aux; 105 { 106 struct adb_softc *sc = (struct adb_softc *)self; 107 struct confargs *ca = aux; 108 int irq = ca->ca_intr[0]; 109 int node; 110 ADBDataBlock adbdata; 111 struct adb_attach_args aa_args; 112 int totaladbs; 113 int adbindex, adbaddr; 114 115 extern volatile u_char *Via1Base; 116 117 ca->ca_reg[0] += ca->ca_baseaddr; 118 119 sc->sc_regbase = mapiodev(ca->ca_reg[0], ca->ca_reg[1]); 120 Via1Base = sc->sc_regbase; 121 122 if (strcmp(ca->ca_name, "via-cuda") == 0) 123 adbHardware = ADB_HW_CUDA; 124 else if (strcmp(ca->ca_name, "via-pmu") == 0) 125 adbHardware = ADB_HW_PB; 126 127 node = getnodebyname(OF_parent(ca->ca_node), "extint-gpio1"); 128 if (node) 129 OF_getprop(node, "interrupts", &irq, 4); 130 131 printf(" irq %d: ", irq); 132 133 adb_polling = 1; 134 ADBReInit(); 135 136 intr_establish(irq, IST_LEVEL, IPL_HIGH, (int (*)(void *))adb_intr, sc); 137 138 #ifdef ADB_DEBUG 139 if (adb_debug) 140 printf("adb: done with ADBReInit\n"); 141 #endif 142 totaladbs = CountADBs(); 143 144 printf("%d targets\n", totaladbs); 145 146 #if NAED > 0 147 /* ADB event device for compatibility */ 148 aa_args.origaddr = 0; 149 aa_args.adbaddr = 0; 150 aa_args.handler_id = 0; 151 (void)config_found(self, &aa_args, adbprint); 152 #endif 153 154 /* for each ADB device */ 155 for (adbindex = 1; adbindex <= totaladbs; adbindex++) { 156 /* Get the ADB information */ 157 adbaddr = GetIndADB(&adbdata, adbindex); 158 159 aa_args.origaddr = adbdata.origADBAddr; 160 aa_args.adbaddr = adbaddr; 161 aa_args.handler_id = adbdata.devType; 162 163 (void)config_found(self, &aa_args, adbprint); 164 } 165 166 #if NAPM > 0 167 /* Magic for signalling the apm driver to match. */ 168 aa_args.origaddr = ADBADDR_APM; 169 aa_args.adbaddr = ADBADDR_APM; 170 aa_args.handler_id = ADBADDR_APM; 171 172 (void)config_found(self, &aa_args, NULL); 173 #endif 174 175 if (adbHardware == ADB_HW_CUDA) 176 adb_cuda_autopoll(); 177 adb_polling = 0; 178 } 179 180 int 181 adbprint(args, name) 182 void *args; 183 const char *name; 184 { 185 struct adb_attach_args *aa_args = (struct adb_attach_args *)args; 186 int rv = UNCONF; 187 188 if (name) { /* no configured device matched */ 189 rv = UNSUPP; /* most ADB device types are unsupported */ 190 191 /* print out what kind of ADB device we have found */ 192 aprint_normal("%s addr %d: ", name, aa_args->adbaddr); 193 switch(aa_args->origaddr) { 194 #ifdef DIAGNOSTIC 195 case 0: 196 aprint_normal("ADB event device"); 197 rv = UNCONF; 198 break; 199 case ADBADDR_SECURE: 200 aprint_normal("security dongle (%d)", 201 aa_args->handler_id); 202 break; 203 #endif 204 case ADBADDR_MAP: 205 aprint_normal("mapped device (%d)", 206 aa_args->handler_id); 207 rv = UNCONF; 208 break; 209 case ADBADDR_REL: 210 aprint_normal("relative positioning device (%d)", 211 aa_args->handler_id); 212 rv = UNCONF; 213 break; 214 #ifdef DIAGNOSTIC 215 case ADBADDR_ABS: 216 switch (aa_args->handler_id) { 217 case ADB_ARTPAD: 218 aprint_normal("WACOM ArtPad II"); 219 break; 220 default: 221 aprint_normal("absolute positioning device (%d)", 222 aa_args->handler_id); 223 break; 224 } 225 break; 226 case ADBADDR_DATATX: 227 aprint_normal("data transfer device (modem?) (%d)", 228 aa_args->handler_id); 229 break; 230 case ADBADDR_MISC: 231 switch (aa_args->handler_id) { 232 case ADB_POWERKEY: 233 aprint_normal("Sophisticated Circuits PowerKey"); 234 break; 235 default: 236 aprint_normal("misc. device (remote control?) (%d)", 237 aa_args->handler_id); 238 break; 239 } 240 break; 241 default: 242 aprint_normal("unknown type device, (handler %d)", 243 aa_args->handler_id); 244 break; 245 #endif /* DIAGNOSTIC */ 246 } 247 } else /* a device matched and was configured */ 248 aprint_normal(" addr %d: ", aa_args->adbaddr); 249 250 return rv; 251 } 252