[BACK]Return to pckbc_ebus.c CVS log [TXT][DIR] Up to [local] / sys / arch / sparc64 / dev

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