1 /* $NetBSD: adb.c,v 1.28 2009/11/01 01:51:35 snj Exp $ */
4 * Copyright (C) 1994 Bradley A. Grantham
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
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.
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 #include <sys/cdefs.h>
29 __KERNEL_RCSID(0, "$NetBSD: adb.c,v 1.28 2009/11/01 01:51:35 snj Exp $");
31 #include <sys/param.h>
32 #include <sys/device.h>
33 #include <sys/fcntl.h>
35 #include <sys/select.h>
37 #include <sys/signalvar.h>
38 #include <sys/systm.h>
40 #include <machine/bus.h>
41 #include <machine/autoconf.h>
42 #include <machine/pio.h>
44 #include <macppc/dev/adbvar.h>
45 #include <macppc/dev/akbdvar.h>
46 #include <macppc/dev/pm_direct.h>
47 #include <macppc/dev/viareg.h>
49 #include <dev/clock_subr.h>
50 #include <dev/ofw/openfirm.h>
56 * Function declarations.
58 static int adbmatch(struct device
*, struct cfdata
*, void *);
59 static void adbattach(struct device
*, struct device
*, void *);
60 static int adbprint(void *, const char *);
61 static void adb_todr_init(void);
66 int adb_polling
= 0; /* Are we polling? (Debugger mode) */
67 int adb_initted
= 0; /* adb_init() has completed successfully */
69 int adb_debug
= 0; /* Output debugging messages */
70 #endif /* ADB_DEBUG */
75 CFATTACH_DECL(adb
, sizeof(struct adb_softc
),
76 adbmatch
, adbattach
, NULL
, NULL
);
79 adbmatch(struct device
*parent
, struct cfdata
*cf
, void *aux
)
81 struct confargs
*ca
= aux
;
89 if (strcmp(ca
->ca_name
, "via-cuda") == 0)
92 if (strcmp(ca
->ca_name
, "via-pmu") == 0)
99 adbattach(struct device
*parent
, struct device
*self
, void *aux
)
101 struct adb_softc
*sc
= (struct adb_softc
*)self
;
102 struct confargs
*ca
= aux
;
103 int irq
= ca
->ca_intr
[0];
105 ADBDataBlock adbdata
;
106 struct adb_attach_args aa_args
;
108 int adbindex
, adbaddr
, adb_node
;
110 extern volatile u_char
*Via1Base
;
112 ca
->ca_reg
[0] += ca
->ca_baseaddr
;
114 sc
->sc_regbase
= mapiodev(ca
->ca_reg
[0], ca
->ca_reg
[1]);
115 Via1Base
= sc
->sc_regbase
;
117 if (strcmp(ca
->ca_name
, "via-cuda") == 0)
118 adbHardware
= ADB_HW_CUDA
;
119 else if (strcmp(ca
->ca_name
, "via-pmu") == 0)
120 adbHardware
= ADB_HW_PMU
;
122 node
= of_getnode_byname(OF_parent(ca
->ca_node
), "extint-gpio1");
124 OF_getprop(node
, "interrupts", &irq
, 4);
126 printf(" irq %d: ", irq
);
129 adb_node
= of_getnode_byname(ca
->ca_node
, "adb");
133 switch (adbHardware
) {
135 intr_establish(irq
, IST_LEVEL
, IPL_TTY
, adb_intr_cuda
, sc
);
138 intr_establish(irq
, IST_LEVEL
, IPL_TTY
, pm_intr
, sc
);
146 /* Magic for signalling the apm driver to match. */
147 aa_args
.origaddr
= ADBADDR_APM
;
148 aa_args
.adbaddr
= ADBADDR_APM
;
149 aa_args
.handler_id
= ADBADDR_APM
;
151 (void)config_found(self
, &aa_args
, NULL
);
155 * see if we're supposed to have an ADB bus
156 * since some PowerBooks don't have one and their PMUs barf on ADB
157 * commands we bail here if there's no adb node
164 printf("adb: done with ADBReInit\n");
166 totaladbs
= CountADBs();
168 printf("%d targets\n", totaladbs
);
171 /* ADB event device for compatibility */
172 aa_args
.origaddr
= 0;
174 aa_args
.handler_id
= 0;
175 (void)config_found(self
, &aa_args
, adbprint
);
178 /* for each ADB device */
179 for (adbindex
= 1; adbindex
<= totaladbs
; adbindex
++) {
180 /* Get the ADB information */
181 adbaddr
= GetIndADB(&adbdata
, adbindex
);
183 aa_args
.origaddr
= adbdata
.origADBAddr
;
184 aa_args
.adbaddr
= adbaddr
;
185 aa_args
.handler_id
= adbdata
.devType
;
187 (void)config_found(self
, &aa_args
, adbprint
);
190 if (adbHardware
== ADB_HW_CUDA
)
197 adbprint(void *args
, const char *name
)
199 struct adb_attach_args
*aa_args
= (struct adb_attach_args
*)args
;
202 if (name
) { /* no configured device matched */
203 rv
= UNSUPP
; /* most ADB device types are unsupported */
205 /* print out what kind of ADB device we have found */
206 aprint_normal("%s addr %d: ", name
, aa_args
->adbaddr
);
207 switch(aa_args
->origaddr
) {
210 aprint_normal("ADB event device");
214 aprint_normal("security dongle (%d)",
215 aa_args
->handler_id
);
219 aprint_normal("mapped device (%d)",
220 aa_args
->handler_id
);
224 aprint_normal("relative positioning device (%d)",
225 aa_args
->handler_id
);
230 switch (aa_args
->handler_id
) {
232 aprint_normal("WACOM ArtPad II");
235 aprint_normal("absolute positioning device (%d)",
236 aa_args
->handler_id
);
241 aprint_normal("data transfer device (modem?) (%d)",
242 aa_args
->handler_id
);
245 switch (aa_args
->handler_id
) {
247 aprint_normal("Sophisticated Circuits PowerKey");
250 aprint_normal("misc. device (remote control?) (%d)",
251 aa_args
->handler_id
);
256 aprint_normal("unknown type device, (handler %d)",
257 aa_args
->handler_id
);
259 #endif /* DIAGNOSTIC */
261 } else /* a device matched and was configured */
262 aprint_normal(" addr %d: ", aa_args
->adbaddr
);
267 #define DIFF19041970 2082844800
270 adb_todr_get(todr_chip_handle_t tch
, struct timeval
*tvp
)
274 if (adb_read_date_time(&sec
) != 0)
276 tvp
->tv_sec
= sec
- DIFF19041970
;
282 adb_todr_set(todr_chip_handle_t tch
, struct timeval
*tvp
)
286 sec
= tvp
->tv_sec
+ DIFF19041970
;
287 return adb_set_date_time(sec
) ? EIO
: 0;
293 static struct todr_chip_handle tch
= {
294 .todr_gettime
= adb_todr_get
,
295 .todr_settime
= adb_todr_set