Annotation of sys/arch/sparc64/dev/auxio.c, Revision 1.1
1.1 ! nbrk 1: /* $OpenBSD: auxio.c,v 1.7 2005/03/09 18:41:48 miod Exp $ */
! 2: /* $NetBSD: auxio.c,v 1.1 2000/04/15 03:08:13 mrg Exp $ */
! 3:
! 4: /*
! 5: * Copyright (c) 2000 Matthew R. Green
! 6: * All rights reserved.
! 7: *
! 8: * Redistribution and use in source and binary forms, with or without
! 9: * modification, are permitted provided that the following conditions
! 10: * are met:
! 11: * 1. Redistributions of source code must retain the above copyright
! 12: * notice, this list of conditions and the following disclaimer.
! 13: * 2. Redistributions in binary form must reproduce the above copyright
! 14: * notice, this list of conditions and the following disclaimer in the
! 15: * documentation and/or other materials provided with the distribution.
! 16: * 3. The name of the author may not be used to endorse or promote products
! 17: * derived from this software without specific prior written permission.
! 18: *
! 19: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
! 20: * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
! 21: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
! 22: * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
! 23: * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
! 24: * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
! 25: * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
! 26: * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
! 27: * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
! 28: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
! 29: * SUCH DAMAGE.
! 30: */
! 31:
! 32: /*
! 33: * AUXIO registers support on the sbus & ebus2.
! 34: */
! 35:
! 36: #include <sys/param.h>
! 37: #include <sys/systm.h>
! 38: #include <sys/errno.h>
! 39: #include <sys/device.h>
! 40: #include <sys/timeout.h>
! 41: #include <sys/kernel.h>
! 42:
! 43: #include <machine/autoconf.h>
! 44: #include <machine/cpu.h>
! 45:
! 46: #include <sparc64/dev/ebusreg.h>
! 47: #include <sparc64/dev/ebusvar.h>
! 48: #include <sparc64/dev/sbusvar.h>
! 49: #include <sparc64/dev/auxioreg.h>
! 50: #include <sparc64/dev/auxiovar.h>
! 51:
! 52: #define AUXIO_ROM_NAME "auxio"
! 53:
! 54: /*
! 55: * ebus code.
! 56: */
! 57: int auxio_ebus_match(struct device *, void *, void *);
! 58: void auxio_ebus_attach(struct device *, struct device *, void *);
! 59: int auxio_sbus_match(struct device *, void *, void *);
! 60: void auxio_sbus_attach(struct device *, struct device *, void *);
! 61: void auxio_attach_common(struct auxio_softc *);
! 62:
! 63: struct cfattach auxio_ebus_ca = {
! 64: sizeof(struct auxio_softc), auxio_ebus_match, auxio_ebus_attach
! 65: };
! 66:
! 67: struct cfattach auxio_sbus_ca = {
! 68: sizeof(struct auxio_softc), auxio_sbus_match, auxio_sbus_attach
! 69: };
! 70:
! 71: struct cfdriver auxio_cd = {
! 72: NULL, "auxio", DV_DULL
! 73: };
! 74:
! 75: void auxio_led_blink(void *, int);
! 76:
! 77: int
! 78: auxio_ebus_match(parent, cf, aux)
! 79: struct device *parent;
! 80: void *cf;
! 81: void *aux;
! 82: {
! 83: struct ebus_attach_args *ea = aux;
! 84:
! 85: return (strcmp(AUXIO_ROM_NAME, ea->ea_name) == 0);
! 86: }
! 87:
! 88: void
! 89: auxio_ebus_attach(parent, self, aux)
! 90: struct device *parent, *self;
! 91: void *aux;
! 92: {
! 93: struct auxio_softc *sc = (struct auxio_softc *)self;
! 94: struct ebus_attach_args *ea = aux;
! 95:
! 96: if (ea->ea_nregs < 1 || ea->ea_nvaddrs < 1) {
! 97: printf(": no registers??\n");
! 98: return;
! 99: }
! 100:
! 101: sc->sc_tag = ea->ea_memtag;
! 102:
! 103: if (ea->ea_nregs != 5 || ea->ea_nvaddrs != 5) {
! 104: printf(": not 5 (%d) registers, only setting led",
! 105: ea->ea_nregs);
! 106: sc->sc_flags = AUXIO_LEDONLY|AUXIO_EBUS;
! 107: } else {
! 108: sc->sc_flags = AUXIO_EBUS;
! 109: if (bus_space_map(sc->sc_tag, ea->ea_vaddrs[2],
! 110: sizeof(u_int32_t), BUS_SPACE_MAP_PROMADDRESS,
! 111: &sc->sc_freq)) {
! 112: printf(": unable to map freq\n");
! 113: return;
! 114: }
! 115: if (bus_space_map(sc->sc_tag, ea->ea_vaddrs[3],
! 116: sizeof(u_int32_t), BUS_SPACE_MAP_PROMADDRESS,
! 117: &sc->sc_scsi)) {
! 118: printf(": unable to map SCSI\n");
! 119: return;
! 120: }
! 121: if (bus_space_map(sc->sc_tag, ea->ea_vaddrs[4],
! 122: sizeof(u_int32_t), BUS_SPACE_MAP_PROMADDRESS,
! 123: &sc->sc_temp)) {
! 124: printf(": unable to map temp\n");
! 125: return;
! 126: }
! 127: }
! 128:
! 129: if (bus_space_map(sc->sc_tag, ea->ea_vaddrs[0], sizeof(u_int32_t),
! 130: BUS_SPACE_MAP_PROMADDRESS, &sc->sc_led)) {
! 131: printf(": unable to map LED\n");
! 132: return;
! 133: }
! 134:
! 135: auxio_attach_common(sc);
! 136: }
! 137:
! 138: int
! 139: auxio_sbus_match(parent, cf, aux)
! 140: struct device *parent;
! 141: void *cf;
! 142: void *aux;
! 143: {
! 144: struct sbus_attach_args *sa = aux;
! 145:
! 146: return (strcmp(AUXIO_ROM_NAME, sa->sa_name) == 0);
! 147: }
! 148:
! 149: void
! 150: auxio_sbus_attach(parent, self, aux)
! 151: struct device *parent, *self;
! 152: void *aux;
! 153: {
! 154: struct auxio_softc *sc = (struct auxio_softc *)self;
! 155: struct sbus_attach_args *sa = aux;
! 156:
! 157: sc->sc_tag = sa->sa_bustag;
! 158:
! 159: if (sa->sa_nreg < 1 || sa->sa_npromvaddrs < 1) {
! 160: printf(": no registers??\n");
! 161: return;
! 162: }
! 163:
! 164: if (sa->sa_nreg != 1 || sa->sa_npromvaddrs != 1) {
! 165: printf(": not 1 (%d/%d) registers??", sa->sa_nreg, sa->sa_npromvaddrs);
! 166: return;
! 167: }
! 168:
! 169: /* sbus auxio only has one set of registers */
! 170: sc->sc_flags = AUXIO_LEDONLY|AUXIO_SBUS;
! 171: if (bus_space_map(sc->sc_tag, sa->sa_promvaddr, 1,
! 172: BUS_SPACE_MAP_PROMADDRESS, &sc->sc_led)) {
! 173: printf(": couldn't map registers\n");
! 174: return;
! 175: }
! 176:
! 177: auxio_attach_common(sc);
! 178: }
! 179:
! 180: void
! 181: auxio_attach_common(sc)
! 182: struct auxio_softc *sc;
! 183: {
! 184: sc->sc_blink.bl_func = auxio_led_blink;
! 185: sc->sc_blink.bl_arg = sc;
! 186: blink_led_register(&sc->sc_blink);
! 187: printf("\n");
! 188: }
! 189:
! 190: void
! 191: auxio_led_blink(void *vsc, int on)
! 192: {
! 193: struct auxio_softc *sc = vsc;
! 194: u_int32_t led;
! 195: int s;
! 196:
! 197: s = splhigh();
! 198:
! 199: if (sc->sc_flags & AUXIO_EBUS)
! 200: led = letoh32(bus_space_read_4(sc->sc_tag, sc->sc_led, 0));
! 201: else
! 202: led = bus_space_read_1(sc->sc_tag, sc->sc_led, 0);
! 203:
! 204: if (on)
! 205: led |= AUXIO_LED_LED;
! 206: else
! 207: led &= ~AUXIO_LED_LED;
! 208:
! 209: if (sc->sc_flags & AUXIO_EBUS)
! 210: bus_space_write_4(sc->sc_tag, sc->sc_led, 0, htole32(led));
! 211: else
! 212: bus_space_write_1(sc->sc_tag, sc->sc_led, 0, led);
! 213:
! 214: splx(s);
! 215: }
! 216:
! 217: int
! 218: auxio_fd_control(u_int32_t bits)
! 219: {
! 220: struct auxio_softc *sc;
! 221: u_int32_t led;
! 222:
! 223: if (auxio_cd.cd_ndevs == 0) {
! 224: return ENXIO;
! 225: }
! 226:
! 227: /*
! 228: * XXX This does not handle > 1 auxio correctly.
! 229: * We'll assume the floppy drive is tied to first auxio found.
! 230: */
! 231: sc = (struct auxio_softc *)auxio_cd.cd_devs[0];
! 232: if (sc->sc_flags & AUXIO_EBUS)
! 233: led = letoh32(bus_space_read_4(sc->sc_tag, sc->sc_led, 0));
! 234: else
! 235: led = bus_space_read_1(sc->sc_tag, sc->sc_led, 0);
! 236:
! 237: led = (led & ~AUXIO_LED_FLOPPY_MASK) | bits;
! 238:
! 239: if (sc->sc_flags & AUXIO_EBUS)
! 240: bus_space_write_4(sc->sc_tag, sc->sc_led, 0, htole32(led));
! 241: else
! 242: bus_space_write_1(sc->sc_tag, sc->sc_led, 0, led);
! 243:
! 244: return 0;
! 245: }
CVSweb