[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

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