Annotation of sys/arch/sparc64/dev/pckbc_ebus.c, Revision 1.1.1.1
1.1 nbrk 1: /* $OpenBSD: pckbc_ebus.c,v 1.7 2004/11/02 21:17:39 miod Exp $ */
2:
3: /*
4: * Copyright (c) 2002 Jason L. Wright (jason@thought.net)
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: *
16: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17: * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18: * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19: * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
20: * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21: * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
22: * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
24: * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
25: * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26: * POSSIBILITY OF SUCH DAMAGE.
27: */
28:
29: /*
30: * Driver for i8042 keyboard controller found on some PCI based
31: * UltraSPARCs
32: *
33: * Effort sponsored in part by the Defense Advanced Research Projects
34: * Agency (DARPA) and Air Force Research Laboratory, Air Force
35: * Materiel Command, USAF, under agreement number F30602-01-2-0537.
36: *
37: */
38:
39: #include <sys/types.h>
40: #include <sys/param.h>
41: #include <sys/systm.h>
42: #include <sys/device.h>
43: #include <sys/conf.h>
44: #include <sys/malloc.h>
45:
46: #include <machine/bus.h>
47: #include <machine/autoconf.h>
48: #include <machine/openfirm.h>
49:
50: #include <sparc64/dev/ebusreg.h>
51: #include <sparc64/dev/ebusvar.h>
52:
53: #include <dev/ic/i8042reg.h>
54: #include <dev/ic/pckbcvar.h>
55:
56: struct pckbc_ebus_softc {
57: struct pckbc_softc sc_pckbc;
58: bus_space_tag_t sc_iot;
59: bus_space_handle_t sc_ioh;
60: bus_space_handle_t sc_ioh_c;
61: bus_space_handle_t sc_ioh_d;
62: void *sc_irq[2];
63: int sc_node;
64: };
65:
66: int pckbc_ebus_match(struct device *, void *, void *);
67: void pckbc_ebus_attach(struct device *, struct device *, void *);
68:
69: struct cfattach pckbc_ebus_ca = {
70: sizeof(struct pckbc_ebus_softc), pckbc_ebus_match, pckbc_ebus_attach
71: };
72:
73: void pckbc_ebus_intr_establish(struct pckbc_softc *, pckbc_slot_t);
74: int pckbc_ebus_is_console(struct pckbc_ebus_softc *);
75:
76: int
77: pckbc_ebus_match(parent, match, aux)
78: struct device *parent;
79: void *match;
80: void *aux;
81: {
82: struct ebus_attach_args *ea = aux;
83:
84: if (strcmp(ea->ea_name, "8042") == 0)
85: return (1);
86: return (0);
87: }
88:
89: void
90: pckbc_ebus_attach(parent, self, aux)
91: struct device *parent, *self;
92: void *aux;
93: {
94: struct pckbc_ebus_softc *sc = (void *)self;
95: struct pckbc_softc *psc = &sc->sc_pckbc;
96: struct ebus_attach_args *ea = aux;
97: struct pckbc_internal *t = NULL;
98: int console;
99:
100: sc->sc_node = ea->ea_node;
101: console = pckbc_ebus_is_console(sc);
102:
103: /* Use prom address if available, otherwise map it. */
104: if (ea->ea_nvaddrs && bus_space_map(ea->ea_iotag, ea->ea_vaddrs[0], 0,
105: 0, &sc->sc_ioh) == 0) {
106: sc->sc_iot = ea->ea_iotag;
107: } else if (ebus_bus_map(ea->ea_iotag, 0,
108: EBUS_PADDR_FROM_REG(&ea->ea_regs[0]), ea->ea_regs[0].size,
109: 0, 0, &sc->sc_ioh) == 0) {
110: sc->sc_iot = ea->ea_iotag;
111: } else if (ebus_bus_map(ea->ea_memtag, 0,
112: EBUS_PADDR_FROM_REG(&ea->ea_regs[0]), ea->ea_regs[0].size,
113: 0, 0, &sc->sc_ioh) == 0) {
114: sc->sc_iot = ea->ea_memtag;
115: } else {
116: printf(": can't map register space\n");
117: return;
118: }
119:
120: if (console) {
121: if (pckbc_cnattach(sc->sc_iot,
122: EBUS_PADDR_FROM_REG(&ea->ea_regs[0]), KBCMDP,
123: PCKBC_KBD_SLOT) == 0) {
124: t = &pckbc_consdata;
125: pckbc_console_attached = 1;
126: sc->sc_ioh_c = t->t_ioh_c;
127: sc->sc_ioh_d = t->t_ioh_d;
128: } else
129: console = 0;
130: }
131:
132: if (console == 0) {
133: if (bus_space_subregion(sc->sc_iot, sc->sc_ioh,
134: KBCMDP, sizeof(u_int32_t), &sc->sc_ioh_c) != 0) {
135: printf(": couldn't get cmd subregion\n");
136: return;
137: }
138: if (bus_space_subregion(sc->sc_iot, sc->sc_ioh,
139: KBDATAP, sizeof(u_int32_t), &sc->sc_ioh_d) != 0) {
140: printf(": couldn't get data subregion\n");
141: return;
142: }
143:
144: t = malloc(sizeof(struct pckbc_internal), M_DEVBUF, M_NOWAIT);
145: bzero(t, sizeof(struct pckbc_internal));
146: }
147:
148: psc->intr_establish = pckbc_ebus_intr_establish;
149:
150: sc->sc_irq[0] = bus_intr_establish(sc->sc_iot, ea->ea_intrs[0],
151: IPL_TTY, 0, pckbcintr, psc, self->dv_xname);
152: if (sc->sc_irq[0] == NULL) {
153: printf(": couldn't get intr0\n");
154: return;
155: }
156:
157: sc->sc_irq[1] = bus_intr_establish(sc->sc_iot, ea->ea_intrs[1],
158: IPL_TTY, 0, pckbcintr, psc, self->dv_xname);
159: if (sc->sc_irq[1] == NULL) {
160: printf(": couldn't get intr1\n");
161: return;
162: }
163:
164: t->t_iot = sc->sc_iot;
165: t->t_ioh_c = sc->sc_ioh_c;
166: t->t_ioh_d = sc->sc_ioh_d;
167: t->t_cmdbyte = KC8_CPU;
168: t->t_sc = psc;
169: psc->id = t;
170:
171: printf("\n");
172: pckbc_attach(psc);
173:
174: }
175:
176: int
177: pckbc_ebus_is_console(sc)
178: struct pckbc_ebus_softc *sc;
179: {
180: char *name;
181: int node;
182:
183: /*
184: * Loop through the children of 8042 and see if the keyboard
185: * exists, and further, whether it is the console input device.
186: * This is almost redundant because 8042 doesn't show up in
187: * device tree unless a keyboard is in fact attached.
188: */
189: for (node = OF_child(sc->sc_node); node; node = OF_peer(node)) {
190: name = getpropstring(node, "name");
191: if (name == NULL)
192: continue;
193: if (strcmp("kb_ps2", name) == 0 ||
194: strcmp("keyboard", name) == 0) {
195: if (node == OF_instance_to_package(OF_stdin()))
196: return (1);
197: }
198: }
199: return (0);
200: }
201:
202: void
203: pckbc_ebus_intr_establish(psc, slot)
204: struct pckbc_softc *psc;
205: pckbc_slot_t slot;
206: {
207: /* Nothing to do, interrupts were mapped in attach. */
208: }
CVSweb