[BACK]Return to gus_isa.c CVS log [TXT][DIR] Up to [local] / sys / dev / isa

Annotation of sys/dev/isa/gus_isa.c, Revision 1.1

1.1     ! nbrk        1: /*     $OpenBSD: gus_isa.c,v 1.4 2004/06/13 21:49:24 niklas Exp $      */
        !             2: /*     $NetBSD: gus.c,v 1.51 1998/01/25 23:48:06 mycroft Exp $ */
        !             3:
        !             4: /*-
        !             5:  * Copyright (c) 1996 The NetBSD Foundation, Inc.
        !             6:  * All rights reserved.
        !             7:  *
        !             8:  * This code is derived from software contributed to The NetBSD Foundation
        !             9:  * by Ken Hornstein and John Kohl.
        !            10:  *
        !            11:  * Redistribution and use in source and binary forms, with or without
        !            12:  * modification, are permitted provided that the following conditions
        !            13:  * are met:
        !            14:  * 1. Redistributions of source code must retain the above copyright
        !            15:  *    notice, this list of conditions and the following disclaimer.
        !            16:  * 2. Redistributions in binary form must reproduce the above copyright
        !            17:  *    notice, this list of conditions and the following disclaimer in the
        !            18:  *    documentation and/or other materials provided with the distribution.
        !            19:  * 3. All advertising materials mentioning features or use of this software
        !            20:  *    must display the following acknowledgement:
        !            21:  *        This product includes software developed by the NetBSD
        !            22:  *       Foundation, Inc. and its contributors.
        !            23:  * 4. Neither the name of The NetBSD Foundation nor the names of its
        !            24:  *    contributors may be used to endorse or promote products derived
        !            25:  *    from this software without specific prior written permission.
        !            26:  *
        !            27:  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
        !            28:  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
        !            29:  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
        !            30:  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
        !            31:  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
        !            32:  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
        !            33:  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
        !            34:  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
        !            35:  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
        !            36:  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
        !            37:  * POSSIBILITY OF SUCH DAMAGE.
        !            38:  */
        !            39:
        !            40: /*
        !            41:  *
        !            42:  * TODO:
        !            43:  *     . figure out why mixer activity while sound is playing causes problems
        !            44:  *       (phantom interrupts?)
        !            45:  *     . figure out a better deinterleave strategy that avoids sucking up
        !            46:  *       CPU, memory and cache bandwidth.  (Maybe a special encoding?
        !            47:  *       Maybe use the double-speed sampling/hardware deinterleave trick
        !            48:  *       from the GUS SDK?)  A 486/33 isn't quite fast enough to keep
        !            49:  *       up with 44.1kHz 16-bit stereo output without some drop-outs.
        !            50:  *     . use CS4231 for 16-bit sampling, for a-law and mu-law playback.
        !            51:  *     . actually test full-duplex sampling(recording) and playback.
        !            52:  */
        !            53:
        !            54: /*
        !            55:  * Gravis UltraSound driver
        !            56:  *
        !            57:  * For more detailed information, see the GUS developers' kit
        !            58:  * available on the net at:
        !            59:  *
        !            60:  * ftp://freedom.nmsu.edu/pub/ultrasound/gravis/util/
        !            61:  *     gusdkXXX.zip (developers' kit--get rev 2.22 or later)
        !            62:  *             See ultrawrd.doc inside--it's MS Word (ick), but it's the bible
        !            63:  *
        !            64:  */
        !            65:
        !            66: /*
        !            67:  * The GUS Max has a slightly strange set of connections between the CS4231
        !            68:  * and the GF1 and the DMA interconnects.  It's set up so that the CS4231 can
        !            69:  * be playing while the GF1 is loading patches from the system.
        !            70:  *
        !            71:  * Here's a recreation of the DMA interconnect diagram:
        !            72:  *
        !            73:  *       GF1
        !            74:  *   +---------+                                digital
        !            75:  *   |         |  record                        ASIC
        !            76:  *   |         |--------------+
        !            77:  *   |         |              |                       +--------+
        !            78:  *   |         | play (dram)  |      +----+    |       |
        !            79:  *   |         |--------------(------|-\  |    |   +-+  |
        !            80:  *   +---------+              |      |  >-|----|---|C|--|------  dma chan 1
        !            81:  *                            |  +---|-/  |    |   +-+ |
        !            82:  *                            |  |   +----+    |    |   |
        !            83:  *                            |         |   +----+    |    |   |
        !            84:  *   +---------+        +-+   +--(---|-\  |    |    |   |
        !            85:  *   |         | play   |8|      |   |  >-|----|----+---|------  dma chan 2
        !            86:  *   | ---C----|--------|/|------(---|-/  |    |        |
        !            87:  *   |    ^    |record  |1|      |   +----+    |       |
        !            88:  *   |    |    |   /----|6|------+            +--------+
        !            89:  *   | ---+----|--/     +-+
        !            90:  *   +---------+
        !            91:  *     CS4231  8-to-16 bit bus conversion, if needed
        !            92:  *
        !            93:  *
        !            94:  * "C" is an optional combiner.
        !            95:  *
        !            96:  */
        !            97:
        !            98: #include <sys/param.h>
        !            99: #include <sys/systm.h>
        !           100: #include <sys/errno.h>
        !           101: #include <sys/ioctl.h>
        !           102: #include <sys/syslog.h>
        !           103: #include <sys/device.h>
        !           104: #include <sys/proc.h>
        !           105: #include <sys/buf.h>
        !           106: #include <sys/fcntl.h>
        !           107: #include <sys/malloc.h>
        !           108: #include <sys/kernel.h>
        !           109: #include <sys/timeout.h>
        !           110:
        !           111: #include <machine/cpu.h>
        !           112: #include <machine/intr.h>
        !           113: #include <machine/bus.h>
        !           114: #include <machine/cpufunc.h>
        !           115: #include <sys/audioio.h>
        !           116: #include <dev/audio_if.h>
        !           117: #include <dev/mulaw.h>
        !           118: #include <dev/auconv.h>
        !           119:
        !           120: #include <dev/isa/isavar.h>
        !           121: #include <dev/isa/isadmavar.h>
        !           122:
        !           123: #include <dev/ic/ics2101reg.h>
        !           124: #include <dev/ic/cs4231reg.h>
        !           125: #include <dev/ic/ad1848reg.h>
        !           126: #include <dev/isa/ics2101var.h>
        !           127: #include <dev/isa/ad1848var.h>
        !           128: #include <dev/isa/cs4231var.h>
        !           129: #include "gusreg.h"
        !           130: #include "gusvar.h"
        !           131:
        !           132: /*
        !           133:  * ISA bus driver routines
        !           134:  */
        !           135:
        !           136: int    gus_isa_match(struct device *, void *, void *);
        !           137: void   gus_isa_attach(struct device *, struct device *, void *);
        !           138:
        !           139: struct cfattach gus_isa_ca = {
        !           140:        sizeof(struct gus_softc), gus_isa_match, gus_isa_attach,
        !           141: };
        !           142:
        !           143: int
        !           144: gus_isa_match(parent, match, aux)
        !           145:        struct device *parent;
        !           146:        void *match;
        !           147:        void *aux;
        !           148: {
        !           149:        struct isa_attach_args *ia = aux;
        !           150:        int iobase = ia->ia_iobase;
        !           151:        int recdrq = ia->ia_drq2;
        !           152:
        !           153:        /*
        !           154:         * Before we do anything else, make sure requested IRQ and DRQ are
        !           155:         * valid for this card.
        !           156:         */
        !           157:
        !           158:        /* XXX range check before indexing!! */
        !           159:        if (ia->ia_irq == IRQUNK || gus_irq_map[ia->ia_irq] == IRQUNK) {
        !           160:                DPRINTF(("gus: invalid irq %d, card not probed\n", ia->ia_irq));
        !           161:                return 0;
        !           162:        }
        !           163:
        !           164:        if (ia->ia_drq == DRQUNK || gus_drq_map[ia->ia_drq] == DRQUNK) {
        !           165:                DPRINTF(("gus: invalid drq %d, card not probed\n", ia->ia_drq));
        !           166:                return 0;
        !           167:        }
        !           168:
        !           169:        if (recdrq != DRQUNK) {
        !           170:                if (recdrq > 7 || gus_drq_map[recdrq] == DRQUNK) {
        !           171:                   DPRINTF(("gus: invalid second DMA channel (%d), card not probed\n", recdrq));
        !           172:                   return 0;
        !           173:                }
        !           174:        } else
        !           175:                recdrq = ia->ia_drq;
        !           176:
        !           177:        if (iobase == IOBASEUNK) {
        !           178:                int i;
        !           179:                for(i = 0; i < gus_addrs; i++)
        !           180:                        if (gus_test_iobase(ia->ia_iot, gus_base_addrs[i])) {
        !           181:                                iobase = gus_base_addrs[i];
        !           182:                                goto done;
        !           183:                        }
        !           184:                return 0;
        !           185:        } else if (!gus_test_iobase(ia->ia_iot, iobase))
        !           186:                        return 0;
        !           187:
        !           188: done:
        !           189:        if ((ia->ia_drq    != -1 && !isa_drq_isfree(parent, ia->ia_drq)) ||
        !           190:            (recdrq != -1 && !isa_drq_isfree(parent, recdrq)))
        !           191:                return 0;
        !           192:
        !           193:        ia->ia_iobase = iobase;
        !           194:        ia->ia_iosize = GUS_NPORT1;
        !           195:        return 1;
        !           196: }
        !           197:
        !           198:
        !           199: /*
        !           200:  * Setup the GUS for use; called shortly after probe
        !           201:  */
        !           202:
        !           203: void
        !           204: gus_isa_attach(parent, self, aux)
        !           205:        struct device *parent, *self;
        !           206:        void *aux;
        !           207: {
        !           208:        struct gus_softc *sc = (void *) self;
        !           209:        struct isa_attach_args *ia = aux;
        !           210:
        !           211:        sc->sc_iot = ia->ia_iot;
        !           212:        sc->sc_iobase = ia->ia_iobase;
        !           213:
        !           214:        /* Map i/o space */
        !           215:        if (bus_space_map(sc->sc_iot, sc->sc_iobase, GUS_NPORT1, 0, &sc->sc_ioh1))
        !           216:                panic("%s: can't map io port range 1", self->dv_xname);
        !           217:        if (bus_space_map(sc->sc_iot, sc->sc_iobase+GUS_IOH2_OFFSET, GUS_NPORT2, 0,
        !           218:            &sc->sc_ioh2))
        !           219:                panic("%s: can't map io port range 2", self->dv_xname);
        !           220:
        !           221:        /* XXX Maybe we shouldn't fail on mapping this, but just assume
        !           222:         * the card is of revision 0? */
        !           223:        if (bus_space_map(sc->sc_iot, sc->sc_iobase+GUS_IOH3_OFFSET, GUS_NPORT3, 0,
        !           224:            &sc->sc_ioh3))
        !           225:                panic("%s: can't map io port range 3", self->dv_xname);
        !           226:
        !           227:        if (bus_space_map(sc->sc_iot, sc->sc_iobase+GUS_IOH4_OFFSET, GUS_NPORT4, 0,
        !           228:            &sc->sc_ioh4))
        !           229:                panic("%s: can't map io port range 4", self->dv_xname);
        !           230:
        !           231:        sc->sc_irq = ia->ia_irq;
        !           232:        sc->sc_drq = ia->ia_drq;
        !           233:        sc->sc_recdrq = ia->ia_drq2;
        !           234:        sc->sc_isa = parent;
        !           235:
        !           236:        gus_subattach(sc, aux);
        !           237: }

CVSweb