The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/isa/gus.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*      $OpenBSD: gus.c,v 1.55 2022/11/02 10:41:34 kn 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  *
   20  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
   21  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
   22  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
   23  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
   24  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   25  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   26  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   27  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   28  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   29  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   30  * POSSIBILITY OF SUCH DAMAGE.
   31  */
   32 
   33 /*
   34  *
   35  * TODO:
   36  *      . figure out why mixer activity while sound is playing causes problems
   37  *        (phantom interrupts?)
   38  *      . figure out a better deinterleave strategy that avoids sucking up
   39  *        CPU, memory and cache bandwidth.  (Maybe a special encoding?
   40  *        Maybe use the double-speed sampling/hardware deinterleave trick
   41  *        from the GUS SDK?)  A 486/33 isn't quite fast enough to keep
   42  *        up with 44.1kHz 16-bit stereo output without some drop-outs.
   43  *      . use CS4231 for 16-bit sampling, for a-law and mu-law playback.
   44  *      . actually test full-duplex sampling(recording) and playback.
   45  */
   46 
   47 /*
   48  * Gravis UltraSound driver
   49  *
   50  * For more detailed information, see the GUS developers' kit
   51  * available on the net at:
   52  *
   53  * http://www.gravis.com/Public/sdk/GUSDK222.ZIP
   54  *
   55  *              See ultrawrd.doc inside--it's MS Word (ick), but it's the bible
   56  *
   57  */
   58 
   59 /*
   60  * The GUS Max has a slightly strange set of connections between the CS4231
   61  * and the GF1 and the DMA interconnects.  It's set up so that the CS4231 can
   62  * be playing while the GF1 is loading patches from the system.
   63  *
   64  * Here's a recreation of the DMA interconnect diagram:
   65  *
   66  *       GF1
   67  *   +---------+                                 digital
   68  *   |         |  record                         ASIC
   69  *   |         |--------------+
   70  *   |         |              |                +--------+
   71  *   |         | play (dram)  |      +----+    |        |
   72  *   |         |--------------(------|-\  |    |   +-+  |
   73  *   +---------+              |      |  >-|----|---|C|--|------  dma chan 1
   74  *                            |  +---|-/  |    |   +-+  |
   75  *                            |  |   +----+    |    |   |
   76  *                            |  |   +----+    |    |   |
   77  *   +---------+        +-+   +--(---|-\  |    |    |   |
   78  *   |         | play   |8|      |   |  >-|----|----+---|------  dma chan 2
   79  *   | ---C----|--------|/|------(---|-/  |    |        |
   80  *   |    ^    |record  |1|      |   +----+    |        |
   81  *   |    |    |   /----|6|------+             +--------+
   82  *   | ---+----|--/     +-+
   83  *   +---------+
   84  *     CS4231   8-to-16 bit bus conversion, if needed
   85  *
   86  *
   87  * "C" is an optional combiner.
   88  *
   89  */
   90 
   91 #include <sys/param.h>
   92 #include <sys/systm.h>
   93 #include <sys/errno.h>
   94 #include <sys/ioctl.h>
   95 #include <sys/syslog.h>
   96 #include <sys/device.h>
   97 #include <sys/buf.h>
   98 #include <sys/fcntl.h>
   99 #include <sys/malloc.h>
  100 #include <sys/kernel.h>
  101 #include <sys/timeout.h>
  102 
  103 #include <machine/cpu.h>
  104 #include <machine/intr.h>
  105 #include <machine/bus.h>
  106 #include <machine/cpufunc.h>
  107 #include <sys/audioio.h>
  108 #include <dev/audio_if.h>
  109 
  110 #include <dev/isa/isavar.h>
  111 #include <dev/isa/isadmavar.h>
  112 
  113 #include <dev/ic/ics2101reg.h>
  114 #include <dev/ic/cs4231reg.h>
  115 #include <dev/ic/ad1848reg.h>
  116 #include <dev/isa/ics2101var.h>
  117 #include <dev/isa/ad1848var.h>
  118 #include <dev/isa/cs4231var.h>
  119 #include "gusreg.h"
  120 #include "gusvar.h"
  121 
  122 #ifdef AUDIO_DEBUG
  123 #define GUSPLAYDEBUG    /*XXX*/
  124 #define DPRINTF(x)      if (gusdebug) printf x
  125 #define DMAPRINTF(x)    if (gusdmadebug) printf x
  126 int     gusdebug = 0;
  127 int     gusdmadebug = 0;
  128 #else
  129 #define DPRINTF(x)
  130 #define DMAPRINTF(x)
  131 #endif
  132 int     gus_dostereo = 1;
  133 
  134 #define NDMARECS 2048
  135 #ifdef GUSPLAYDEBUG
  136 int     gusstats = 0;
  137 
  138 struct dma_record dmarecords[NDMARECS];
  139 
  140 int dmarecord_index = 0;
  141 #endif
  142 
  143 struct cfdriver gus_cd = {
  144         NULL, "gus", DV_DULL
  145 };
  146 
  147 /*
  148  * A mapping from IRQ/DRQ values to the values used in the GUS's internal
  149  * registers.  A zero means that the referenced IRQ/DRQ is invalid
  150  */
  151 const int gus_irq_map[] = {
  152         IRQUNK, IRQUNK, 1, 3, IRQUNK, 2, IRQUNK, 4, IRQUNK, 1, IRQUNK, 5, 6,
  153         IRQUNK, IRQUNK, 7
  154 };
  155 const int gus_drq_map[] = {
  156         DRQUNK, 1, DRQUNK, 2, DRQUNK, 3, 4, 5
  157 };
  158 
  159 /*
  160  * A list of valid base addresses for the GUS
  161  */
  162 
  163 const int gus_base_addrs[] = {
  164         0x210, 0x220, 0x230, 0x240, 0x250, 0x260
  165 };
  166 const int gus_addrs = sizeof(gus_base_addrs) / sizeof(gus_base_addrs[0]);
  167 
  168 /*
  169  * Maximum frequency values of the GUS based on the number of currently active
  170  * voices.  Since the GUS samples a voice every 1.6 us, the maximum frequency
  171  * is dependent on the number of active voices.  Yes, it is pretty weird.
  172  */
  173 
  174 static const int gus_max_frequency[] = {
  175                 44100,          /* 14 voices */
  176                 41160,          /* 15 voices */
  177                 38587,          /* 16 voices */
  178                 36317,          /* 17 voices */
  179                 34300,          /* 18 voices */
  180                 32494,          /* 19 voices */
  181                 30870,          /* 20 voices */
  182                 29400,          /* 21 voices */
  183                 28063,          /* 22 voices */
  184                 26843,          /* 23 voices */
  185                 25725,          /* 24 voices */
  186                 24696,          /* 25 voices */
  187                 23746,          /* 26 voices */
  188                 22866,          /* 27 voices */
  189                 22050,          /* 28 voices */
  190                 21289,          /* 29 voices */
  191                 20580,          /* 30 voices */
  192                 19916,          /* 31 voices */
  193                 19293           /* 32 voices */
  194 };
  195 /*
  196  * A mapping of linear volume levels to the logarithmic volume values used
  197  * by the GF1 chip on the GUS.  From GUS SDK vol1.c.
  198  */
  199 
  200 static const unsigned short gus_log_volumes[512] = {
  201  0x0000,
  202  0x0700, 0x07ff, 0x0880, 0x08ff, 0x0940, 0x0980, 0x09c0, 0x09ff, 0x0a20,
  203  0x0a40, 0x0a60, 0x0a80, 0x0aa0, 0x0ac0, 0x0ae0, 0x0aff, 0x0b10, 0x0b20,
  204  0x0b30, 0x0b40, 0x0b50, 0x0b60, 0x0b70, 0x0b80, 0x0b90, 0x0ba0, 0x0bb0,
  205  0x0bc0, 0x0bd0, 0x0be0, 0x0bf0, 0x0bff, 0x0c08, 0x0c10, 0x0c18, 0x0c20,
  206  0x0c28, 0x0c30, 0x0c38, 0x0c40, 0x0c48, 0x0c50, 0x0c58, 0x0c60, 0x0c68,
  207  0x0c70, 0x0c78, 0x0c80, 0x0c88, 0x0c90, 0x0c98, 0x0ca0, 0x0ca8, 0x0cb0,
  208  0x0cb8, 0x0cc0, 0x0cc8, 0x0cd0, 0x0cd8, 0x0ce0, 0x0ce8, 0x0cf0, 0x0cf8,
  209  0x0cff, 0x0d04, 0x0d08, 0x0d0c, 0x0d10, 0x0d14, 0x0d18, 0x0d1c, 0x0d20,
  210  0x0d24, 0x0d28, 0x0d2c, 0x0d30, 0x0d34, 0x0d38, 0x0d3c, 0x0d40, 0x0d44,
  211  0x0d48, 0x0d4c, 0x0d50, 0x0d54, 0x0d58, 0x0d5c, 0x0d60, 0x0d64, 0x0d68,
  212  0x0d6c, 0x0d70, 0x0d74, 0x0d78, 0x0d7c, 0x0d80, 0x0d84, 0x0d88, 0x0d8c,
  213  0x0d90, 0x0d94, 0x0d98, 0x0d9c, 0x0da0, 0x0da4, 0x0da8, 0x0dac, 0x0db0,
  214  0x0db4, 0x0db8, 0x0dbc, 0x0dc0, 0x0dc4, 0x0dc8, 0x0dcc, 0x0dd0, 0x0dd4,
  215  0x0dd8, 0x0ddc, 0x0de0, 0x0de4, 0x0de8, 0x0dec, 0x0df0, 0x0df4, 0x0df8,
  216  0x0dfc, 0x0dff, 0x0e02, 0x0e04, 0x0e06, 0x0e08, 0x0e0a, 0x0e0c, 0x0e0e,
  217  0x0e10, 0x0e12, 0x0e14, 0x0e16, 0x0e18, 0x0e1a, 0x0e1c, 0x0e1e, 0x0e20,
  218  0x0e22, 0x0e24, 0x0e26, 0x0e28, 0x0e2a, 0x0e2c, 0x0e2e, 0x0e30, 0x0e32,
  219  0x0e34, 0x0e36, 0x0e38, 0x0e3a, 0x0e3c, 0x0e3e, 0x0e40, 0x0e42, 0x0e44,
  220  0x0e46, 0x0e48, 0x0e4a, 0x0e4c, 0x0e4e, 0x0e50, 0x0e52, 0x0e54, 0x0e56,
  221  0x0e58, 0x0e5a, 0x0e5c, 0x0e5e, 0x0e60, 0x0e62, 0x0e64, 0x0e66, 0x0e68,
  222  0x0e6a, 0x0e6c, 0x0e6e, 0x0e70, 0x0e72, 0x0e74, 0x0e76, 0x0e78, 0x0e7a,
  223  0x0e7c, 0x0e7e, 0x0e80, 0x0e82, 0x0e84, 0x0e86, 0x0e88, 0x0e8a, 0x0e8c,
  224  0x0e8e, 0x0e90, 0x0e92, 0x0e94, 0x0e96, 0x0e98, 0x0e9a, 0x0e9c, 0x0e9e,
  225  0x0ea0, 0x0ea2, 0x0ea4, 0x0ea6, 0x0ea8, 0x0eaa, 0x0eac, 0x0eae, 0x0eb0,
  226  0x0eb2, 0x0eb4, 0x0eb6, 0x0eb8, 0x0eba, 0x0ebc, 0x0ebe, 0x0ec0, 0x0ec2,
  227  0x0ec4, 0x0ec6, 0x0ec8, 0x0eca, 0x0ecc, 0x0ece, 0x0ed0, 0x0ed2, 0x0ed4,
  228  0x0ed6, 0x0ed8, 0x0eda, 0x0edc, 0x0ede, 0x0ee0, 0x0ee2, 0x0ee4, 0x0ee6,
  229  0x0ee8, 0x0eea, 0x0eec, 0x0eee, 0x0ef0, 0x0ef2, 0x0ef4, 0x0ef6, 0x0ef8,
  230  0x0efa, 0x0efc, 0x0efe, 0x0eff, 0x0f01, 0x0f02, 0x0f03, 0x0f04, 0x0f05,
  231  0x0f06, 0x0f07, 0x0f08, 0x0f09, 0x0f0a, 0x0f0b, 0x0f0c, 0x0f0d, 0x0f0e,
  232  0x0f0f, 0x0f10, 0x0f11, 0x0f12, 0x0f13, 0x0f14, 0x0f15, 0x0f16, 0x0f17,
  233  0x0f18, 0x0f19, 0x0f1a, 0x0f1b, 0x0f1c, 0x0f1d, 0x0f1e, 0x0f1f, 0x0f20,
  234  0x0f21, 0x0f22, 0x0f23, 0x0f24, 0x0f25, 0x0f26, 0x0f27, 0x0f28, 0x0f29,
  235  0x0f2a, 0x0f2b, 0x0f2c, 0x0f2d, 0x0f2e, 0x0f2f, 0x0f30, 0x0f31, 0x0f32,
  236  0x0f33, 0x0f34, 0x0f35, 0x0f36, 0x0f37, 0x0f38, 0x0f39, 0x0f3a, 0x0f3b,
  237  0x0f3c, 0x0f3d, 0x0f3e, 0x0f3f, 0x0f40, 0x0f41, 0x0f42, 0x0f43, 0x0f44,
  238  0x0f45, 0x0f46, 0x0f47, 0x0f48, 0x0f49, 0x0f4a, 0x0f4b, 0x0f4c, 0x0f4d,
  239  0x0f4e, 0x0f4f, 0x0f50, 0x0f51, 0x0f52, 0x0f53, 0x0f54, 0x0f55, 0x0f56,
  240  0x0f57, 0x0f58, 0x0f59, 0x0f5a, 0x0f5b, 0x0f5c, 0x0f5d, 0x0f5e, 0x0f5f,
  241  0x0f60, 0x0f61, 0x0f62, 0x0f63, 0x0f64, 0x0f65, 0x0f66, 0x0f67, 0x0f68,
  242  0x0f69, 0x0f6a, 0x0f6b, 0x0f6c, 0x0f6d, 0x0f6e, 0x0f6f, 0x0f70, 0x0f71,
  243  0x0f72, 0x0f73, 0x0f74, 0x0f75, 0x0f76, 0x0f77, 0x0f78, 0x0f79, 0x0f7a,
  244  0x0f7b, 0x0f7c, 0x0f7d, 0x0f7e, 0x0f7f, 0x0f80, 0x0f81, 0x0f82, 0x0f83,
  245  0x0f84, 0x0f85, 0x0f86, 0x0f87, 0x0f88, 0x0f89, 0x0f8a, 0x0f8b, 0x0f8c,
  246  0x0f8d, 0x0f8e, 0x0f8f, 0x0f90, 0x0f91, 0x0f92, 0x0f93, 0x0f94, 0x0f95,
  247  0x0f96, 0x0f97, 0x0f98, 0x0f99, 0x0f9a, 0x0f9b, 0x0f9c, 0x0f9d, 0x0f9e,
  248  0x0f9f, 0x0fa0, 0x0fa1, 0x0fa2, 0x0fa3, 0x0fa4, 0x0fa5, 0x0fa6, 0x0fa7,
  249  0x0fa8, 0x0fa9, 0x0faa, 0x0fab, 0x0fac, 0x0fad, 0x0fae, 0x0faf, 0x0fb0,
  250  0x0fb1, 0x0fb2, 0x0fb3, 0x0fb4, 0x0fb5, 0x0fb6, 0x0fb7, 0x0fb8, 0x0fb9,
  251  0x0fba, 0x0fbb, 0x0fbc, 0x0fbd, 0x0fbe, 0x0fbf, 0x0fc0, 0x0fc1, 0x0fc2,
  252  0x0fc3, 0x0fc4, 0x0fc5, 0x0fc6, 0x0fc7, 0x0fc8, 0x0fc9, 0x0fca, 0x0fcb,
  253  0x0fcc, 0x0fcd, 0x0fce, 0x0fcf, 0x0fd0, 0x0fd1, 0x0fd2, 0x0fd3, 0x0fd4,
  254  0x0fd5, 0x0fd6, 0x0fd7, 0x0fd8, 0x0fd9, 0x0fda, 0x0fdb, 0x0fdc, 0x0fdd,
  255  0x0fde, 0x0fdf, 0x0fe0, 0x0fe1, 0x0fe2, 0x0fe3, 0x0fe4, 0x0fe5, 0x0fe6,
  256  0x0fe7, 0x0fe8, 0x0fe9, 0x0fea, 0x0feb, 0x0fec, 0x0fed, 0x0fee, 0x0fef,
  257  0x0ff0, 0x0ff1, 0x0ff2, 0x0ff3, 0x0ff4, 0x0ff5, 0x0ff6, 0x0ff7, 0x0ff8,
  258  0x0ff9, 0x0ffa, 0x0ffb, 0x0ffc, 0x0ffd, 0x0ffe, 0x0fff};
  259 
  260 /*
  261  * Interface to higher level audio driver
  262  */
  263 const struct audio_hw_if gus_hw_if = {
  264         .open = gusopen,
  265         .close = gusclose,
  266         .set_params = gus_set_params,
  267         .round_blocksize = gus_round_blocksize,
  268         .commit_settings = gus_commit_settings,
  269         .start_output = gus_dma_output,
  270         .start_input = gus_dma_input,
  271         .halt_output = gus_halt_out_dma,
  272         .halt_input = gus_halt_in_dma,
  273         .set_port = gus_mixer_set_port,
  274         .get_port = gus_mixer_get_port,
  275         .query_devinfo = gus_mixer_query_devinfo,
  276         .allocm = gus_malloc,
  277         .freem = gus_free,
  278         .round_buffersize = gus_round,
  279 };
  280 
  281 static const struct audio_hw_if gusmax_hw_if = {
  282         .open = gusmaxopen,
  283         .close = gusmax_close,
  284         .set_params = gusmax_set_params,
  285         .round_blocksize = gusmax_round_blocksize,
  286         .commit_settings = gusmax_commit_settings,
  287         .start_output = gusmax_dma_output,
  288         .start_input = gusmax_dma_input,
  289         .halt_output = gusmax_halt_out_dma,
  290         .halt_input = gusmax_halt_in_dma,
  291         .set_port = gusmax_mixer_set_port,
  292         .get_port = gusmax_mixer_get_port,
  293         .query_devinfo = gusmax_mixer_query_devinfo,
  294         .allocm = ad1848_malloc,
  295         .freem = ad1848_free,
  296         .round_buffersize = ad1848_round,
  297 };
  298 
  299 int
  300 gusopen(void *addr, int flags)
  301 {
  302         struct gus_softc *sc = addr;
  303 
  304         DPRINTF(("gusopen() called\n"));
  305 
  306         if ((flags & (FWRITE | FREAD)) == (FWRITE | FREAD) &&
  307             sc->sc_recdrq == sc->sc_drq)
  308                 return ENXIO;
  309 
  310         if (sc->sc_flags & GUS_OPEN)
  311                 return EBUSY;
  312 
  313         gus_speaker_ctl(sc, (flags & FWRITE) ? SPKR_ON : SPKR_OFF);
  314 
  315         /*
  316          * Some initialization
  317          */
  318 
  319         sc->sc_flags |= GUS_OPEN;
  320         sc->sc_dmabuf = 0;
  321         sc->sc_playbuf = -1;
  322         sc->sc_bufcnt = 0;
  323         sc->sc_voc[GUS_VOICE_LEFT].start_addr = GUS_MEM_OFFSET - 1;
  324         sc->sc_voc[GUS_VOICE_LEFT].current_addr = GUS_MEM_OFFSET;
  325 
  326         if (HAS_CODEC(sc)) {
  327                 ad1848_open(&sc->sc_codec, flags);
  328                 sc->sc_codec.mute[AD1848_AUX1_CHANNEL] = 0;
  329                 ad1848_mute_channel(&sc->sc_codec, AD1848_AUX1_CHANNEL, 0); /* turn on DAC output */
  330                 if (flags & FREAD) {
  331                         sc->sc_codec.mute[AD1848_MONO_CHANNEL] = 0;
  332                         ad1848_mute_channel(&sc->sc_codec, AD1848_MONO_CHANNEL, 0);
  333                 }
  334         } else if (flags & FREAD) {
  335                 /* enable/unmute the microphone */
  336                 if (HAS_MIXER(sc)) {
  337                         gusics_mic_mute(&sc->sc_mixer, 0);
  338                 } else
  339                         gus_mic_ctl(sc, SPKR_ON);
  340         }
  341         if (sc->sc_nbufs == 0)
  342             gus_round_blocksize(sc, GUS_BUFFER_MULTIPLE); /* default blksiz */
  343         return 0;
  344 }
  345 
  346 int
  347 gusmaxopen(void *addr, int flags)
  348 {
  349         struct ad1848_softc *ac = addr;
  350         return gusopen(ac->parent, flags);
  351 }
  352 
  353 void
  354 gus_deinterleave(struct gus_softc *sc, void *buf, int size)
  355 {
  356         /* deinterleave the stereo data.  We can use sc->sc_deintr_buf
  357            for scratch space. */
  358         int i;
  359 
  360         if (size > sc->sc_blocksize) {
  361                 printf("gus: deinterleave %d > %d\n", size, sc->sc_blocksize);
  362                 return;
  363         } else if (size < sc->sc_blocksize) {
  364                 DPRINTF(("gus: deinterleave %d < %d\n", size, sc->sc_blocksize));
  365         }
  366 
  367         /*
  368          * size is in bytes.
  369          */
  370         if (sc->sc_precision == 16) {
  371                 u_short *dei = sc->sc_deintr_buf;
  372                 u_short *sbuf = buf;
  373                 size >>= 1;             /* bytecnt to shortcnt */
  374                 /* copy 2nd of each pair of samples to the staging area, while
  375                    compacting the 1st of each pair into the original area. */
  376                 for (i = 0; i < size/2-1; i++)  {
  377                         dei[i] = sbuf[i*2+1];
  378                         sbuf[i+1] = sbuf[i*2+2];
  379                 }
  380                 /*
  381                  * this has copied one less sample than half of the
  382                  * buffer.  The first sample of the 1st stream was
  383                  * already in place and didn't need copying.
  384                  * Therefore, we've moved all of the 1st stream's
  385                  * samples into place.  We have one sample from 2nd
  386                  * stream in the last slot of original area, not
  387                  * copied to the staging area (But we don't need to!).
  388                  * Copy the remainder of the original stream into place.
  389                  */
  390                 bcopy(dei, &sbuf[size/2], i * sizeof(short));
  391         } else {
  392                 u_char *dei = sc->sc_deintr_buf;
  393                 u_char *sbuf = buf;
  394                 for (i = 0; i < size/2-1; i++)  {
  395                         dei[i] = sbuf[i*2+1];
  396                         sbuf[i+1] = sbuf[i*2+2];
  397                 }
  398                 bcopy(dei, &sbuf[size/2], i);
  399         }
  400 }
  401 
  402 /*
  403  * Actually output a buffer to the DSP chip
  404  */
  405 
  406 int
  407 gusmax_dma_output(void *addr, void *buf, int size, void (*intr)(void *),
  408     void *arg)
  409 {
  410         struct ad1848_softc *ac = addr;
  411         return gus_dma_output(ac->parent, buf, size, intr, arg);
  412 }
  413 
  414 /*
  415  * called at splaudio() from interrupt handler.
  416  */
  417 void
  418 stereo_dmaintr(void *arg)
  419 {
  420     struct gus_softc *sc = arg;
  421     struct stereo_dma_intr *sa = &sc->sc_stereo;
  422 
  423     DMAPRINTF(("stereo_dmaintr"));
  424 
  425     /*
  426      * Put other half in its place, then call the real interrupt routine :)
  427      */
  428 
  429     sc->sc_dmaoutintr = sa->intr;
  430     sc->sc_outarg = sa->arg;
  431 
  432 #ifdef GUSPLAYDEBUG
  433     if (gusstats) {
  434       microtime(&dmarecords[dmarecord_index].tv);
  435       dmarecords[dmarecord_index].gusaddr = sa->dmabuf;
  436       dmarecords[dmarecord_index].bsdaddr = sa->buffer;
  437       dmarecords[dmarecord_index].count = sa->size;
  438       dmarecords[dmarecord_index].channel = 1;
  439       dmarecords[dmarecord_index++].direction = 1;
  440       dmarecord_index = dmarecord_index % NDMARECS;
  441     }
  442 #endif
  443 
  444     gusdmaout(sc, sa->flags, sa->dmabuf, (caddr_t) sa->buffer, sa->size);
  445 
  446     sa->flags = 0;
  447     sa->dmabuf = 0;
  448     sa->buffer = 0;
  449     sa->size = 0;
  450     sa->intr = 0;
  451     sa->arg = 0;
  452 }
  453 
  454 /*
  455  * Start up DMA output to the card.
  456  * Called at splaudio(), either from intr handler or from
  457  * generic audio code.
  458  */
  459 int
  460 gus_dma_output(void *addr, void *buf, int size, void (*intr)(void *), void *arg)
  461 {
  462         struct gus_softc *sc = addr;
  463         u_char *buffer = buf;
  464         u_long boarddma;
  465         int flags;
  466 
  467         DMAPRINTF(("gus_dma_output %d @ %p\n", size, buf));
  468         if (size != sc->sc_blocksize) {
  469             DPRINTF(("gus_dma_output reqsize %d not sc_blocksize %d\n",
  470                      size, sc->sc_blocksize));
  471             return EINVAL;
  472         }
  473 
  474         flags = GUSMASK_DMA_WRITE;
  475         if (sc->sc_precision == 16)
  476             flags |= GUSMASK_DMA_DATA_SIZE;
  477         if (sc->sc_encoding == AUDIO_ENCODING_ULAW ||
  478             sc->sc_encoding == AUDIO_ENCODING_ALAW ||
  479             sc->sc_encoding == AUDIO_ENCODING_ULINEAR_BE ||
  480             sc->sc_encoding == AUDIO_ENCODING_ULINEAR_LE)
  481             flags |= GUSMASK_DMA_INVBIT;
  482 
  483         if (sc->sc_channels == 2) {
  484                 if (sc->sc_precision == 16) {
  485                         if (size & 3) {
  486                                 DPRINTF(("gus_dma_output: unpaired 16bit samples"));
  487                                 size &= 3;
  488                         }
  489                 } else if (size & 1) {
  490                         DPRINTF(("gus_dma_output: unpaired samples"));
  491                         size &= 1;
  492                 }
  493                 if (size == 0) {
  494                         return 0;
  495                 }
  496 
  497                 gus_deinterleave(sc, (void *)buffer, size);
  498 
  499                 size >>= 1;
  500 
  501                 boarddma = size * sc->sc_dmabuf + GUS_MEM_OFFSET;
  502 
  503                 sc->sc_stereo.intr = intr;
  504                 sc->sc_stereo.arg = arg;
  505                 sc->sc_stereo.size = size;
  506                 sc->sc_stereo.dmabuf = boarddma + GUS_LEFT_RIGHT_OFFSET;
  507                 sc->sc_stereo.buffer = buffer + size;
  508                 sc->sc_stereo.flags = flags;
  509                 if (gus_dostereo) {
  510                   intr = stereo_dmaintr;
  511                   arg = sc;
  512                 }
  513         } else
  514                 boarddma = size * sc->sc_dmabuf + GUS_MEM_OFFSET;
  515 
  516 
  517         sc->sc_flags |= GUS_LOCKED;
  518         sc->sc_dmaoutintr = intr;
  519         sc->sc_outarg = arg;
  520 
  521 #ifdef GUSPLAYDEBUG
  522         if (gusstats) {
  523           microtime(&dmarecords[dmarecord_index].tv);
  524           dmarecords[dmarecord_index].gusaddr = boarddma;
  525           dmarecords[dmarecord_index].bsdaddr = buffer;
  526           dmarecords[dmarecord_index].count = size;
  527           dmarecords[dmarecord_index].channel = 0;
  528           dmarecords[dmarecord_index++].direction = 1;
  529           dmarecord_index = dmarecord_index % NDMARECS;
  530         }
  531 #endif
  532 
  533         gusdmaout(sc, flags, boarddma, (caddr_t) buffer, size);
  534         return 0;
  535 }
  536 
  537 void
  538 gusmax_close(void *addr)
  539 {
  540         struct ad1848_softc *ac = addr;
  541         struct gus_softc *sc = ac->parent;
  542 #if 0
  543         ac->mute[AD1848_AUX1_CHANNEL] = MUTE_ALL;
  544         ad1848_mute_channel(ac, MUTE_ALL); /* turn off DAC output */
  545 #endif
  546         ad1848_close(ac);
  547         gusclose(sc);
  548 }
  549 
  550 /*
  551  * Close out device stuff.  Called at splaudio() from generic audio layer.
  552  */
  553 void
  554 gusclose(void *addr)
  555 {
  556         struct gus_softc *sc = addr;
  557 
  558         DPRINTF(("gus_close: sc=%p\n", sc));
  559 
  560 /*      if (sc->sc_flags & GUS_DMAOUT_ACTIVE) */ {
  561                 gus_halt_out_dma(sc);
  562         }
  563 /*      if (sc->sc_flags & GUS_DMAIN_ACTIVE) */ {
  564                 gus_halt_in_dma(sc);
  565         }
  566         sc->sc_flags &= ~(GUS_OPEN|GUS_LOCKED|GUS_DMAOUT_ACTIVE|GUS_DMAIN_ACTIVE);
  567 
  568         if (sc->sc_deintr_buf) {
  569                 free(sc->sc_deintr_buf, M_DEVBUF, 0);
  570                 sc->sc_deintr_buf = NULL;
  571         }
  572         /* turn off speaker, etc. */
  573 
  574         /* make sure the voices shut up: */
  575         gus_stop_voice(sc, GUS_VOICE_LEFT, 1);
  576         gus_stop_voice(sc, GUS_VOICE_RIGHT, 0);
  577 }
  578 
  579 /*
  580  * Service interrupts.  Farm them off to helper routines if we are using the
  581  * GUS for simple playback/record
  582  */
  583 
  584 #ifdef AUDIO_DEBUG
  585 int gusintrcnt;
  586 int gusdmaintrcnt;
  587 int gusvocintrcnt;
  588 #endif
  589 
  590 int
  591 gusintr(void *arg)
  592 {
  593         struct gus_softc *sc = arg;
  594         bus_space_tag_t iot = sc->sc_iot;
  595         bus_space_handle_t ioh1 = sc->sc_ioh1;
  596         bus_space_handle_t ioh2 = sc->sc_ioh2;
  597         unsigned char intr;
  598 
  599         int retval = 0;
  600 
  601         DPRINTF(("gusintr\n"));
  602 #ifdef AUDIO_DEBUG
  603         gusintrcnt++;
  604 #endif
  605         if (HAS_CODEC(sc))
  606                 retval = ad1848_intr(&sc->sc_codec);
  607         mtx_enter(&audio_lock);
  608         if ((intr = bus_space_read_1(iot, ioh1, GUS_IRQ_STATUS)) & GUSMASK_IRQ_DMATC) {
  609                 DMAPRINTF(("gusintr dma flags=%x\n", sc->sc_flags));
  610 #ifdef AUDIO_DEBUG
  611                 gusdmaintrcnt++;
  612 #endif
  613                 retval += gus_dmaout_intr(sc);
  614                 if (sc->sc_flags & GUS_DMAIN_ACTIVE) {
  615                     SELECT_GUS_REG(iot, ioh2, GUSREG_SAMPLE_CONTROL);
  616                     intr = bus_space_read_1(iot, ioh2, GUS_DATA_HIGH);
  617                     if (intr & GUSMASK_SAMPLE_DMATC) {
  618                         retval += gus_dmain_intr(sc);
  619                     }
  620                 }
  621         }
  622         if (intr & (GUSMASK_IRQ_VOICE | GUSMASK_IRQ_VOLUME)) {
  623                 DMAPRINTF(("gusintr voice flags=%x\n", sc->sc_flags));
  624 #ifdef AUDIO_DEBUG
  625                 gusvocintrcnt++;
  626 #endif
  627                 retval += gus_voice_intr(sc);
  628         }
  629         if (retval) {
  630                 mtx_leave(&audio_lock);
  631                 return 1;
  632         }
  633         mtx_leave(&audio_lock);
  634         return retval;
  635 }
  636 
  637 int gus_bufcnt[GUS_MEM_FOR_BUFFERS / GUS_BUFFER_MULTIPLE];
  638 int gus_restart;                                /* how many restarts? */
  639 int gus_stops;                          /* how many times did voice stop? */
  640 int gus_falsestops;                     /* stopped but not done? */
  641 int gus_continues;
  642 
  643 struct playcont {
  644         struct timeval tv;
  645         u_int playbuf;
  646         u_int dmabuf;
  647         u_char bufcnt;
  648         u_char vaction;
  649         u_char voccntl;
  650         u_char volcntl;
  651         u_long curaddr;
  652         u_long endaddr;
  653 } playstats[NDMARECS];
  654 
  655 int playcntr;
  656 
  657 void
  658 gus_dmaout_timeout(void *arg)
  659 {
  660         struct gus_softc *sc = arg;
  661         bus_space_tag_t iot = sc->sc_iot;
  662         bus_space_handle_t ioh2 = sc->sc_ioh2;
  663 
  664         printf("%s: dmaout timeout\n", sc->sc_dev.dv_xname);
  665         /*
  666          * Stop any DMA.
  667          */
  668 
  669         mtx_enter(&audio_lock);
  670         SELECT_GUS_REG(iot, ioh2, GUSREG_DMA_CONTROL);
  671         bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0);
  672  
  673 #if 0
  674         /* XXX we will dmadone below? */
  675         isa_dmaabort(sc->sc_dev.dv_parent, sc->sc_drq);
  676 #endif
  677  
  678         gus_dmaout_dointr(sc);
  679         mtx_leave(&audio_lock);
  680 }
  681 
  682 
  683 /*
  684  * Service DMA interrupts.  This routine will only get called if we're doing
  685  * a DMA transfer for playback/record requests from the audio layer.
  686  */
  687 
  688 int
  689 gus_dmaout_intr(struct gus_softc *sc)
  690 {
  691         bus_space_tag_t iot = sc->sc_iot;
  692         bus_space_handle_t ioh2 = sc->sc_ioh2;
  693 
  694         /*
  695          * If we got a DMA transfer complete from the GUS DRAM, then deal
  696          * with it.
  697          */
  698 
  699         SELECT_GUS_REG(iot, ioh2, GUSREG_DMA_CONTROL);
  700         if (bus_space_read_1(iot, ioh2, GUS_DATA_HIGH) & GUSMASK_DMA_IRQPEND) {
  701             timeout_del(&sc->sc_dma_tmo);
  702             gus_dmaout_dointr(sc);
  703             return 1;
  704         }
  705         return 0;
  706 }
  707 
  708 void
  709 gus_dmaout_dointr(struct gus_softc *sc)
  710 {
  711         bus_space_tag_t iot = sc->sc_iot;
  712         bus_space_handle_t ioh2 = sc->sc_ioh2;
  713 
  714         /* sc->sc_dmaoutcnt - 1 because DMA controller counts from zero?. */
  715         isa_dmadone(sc->sc_dev.dv_parent, sc->sc_drq);
  716         sc->sc_flags &= ~GUS_DMAOUT_ACTIVE;  /* pending DMA is done */
  717         DMAPRINTF(("gus_dmaout_dointr %d @ %p\n", sc->sc_dmaoutcnt,
  718                    sc->sc_dmaoutaddr));
  719 
  720         /*
  721          * to prevent clicking, we need to copy last sample
  722          * from last buffer to scratch area just before beginning of
  723          * buffer.  However, if we're doing formats that are converted by
  724          * the card during the DMA process, we need to pick up the converted
  725          * byte rather than the one we have in memory.
  726          */
  727         if (sc->sc_dmabuf == sc->sc_nbufs - 1) {
  728           int i;
  729           switch (sc->sc_encoding) {
  730           case AUDIO_ENCODING_SLINEAR_LE:
  731           case AUDIO_ENCODING_SLINEAR_BE:
  732             if (sc->sc_precision == 8)
  733               goto byte;
  734             /* we have the native format */
  735             for (i = 1; i <= 2; i++)
  736               guspoke(iot, ioh2, sc->sc_gusaddr -
  737                       (sc->sc_nbufs - 1) * sc->sc_chanblocksize - i,
  738                       sc->sc_dmaoutaddr[sc->sc_dmaoutcnt-i]);
  739             break;
  740           case AUDIO_ENCODING_ULINEAR_LE:
  741           case AUDIO_ENCODING_ULINEAR_BE:
  742             guspoke(iot, ioh2, sc->sc_gusaddr -
  743                     (sc->sc_nbufs - 1) * sc->sc_chanblocksize - 2,
  744                     guspeek(iot, ioh2,
  745                             sc->sc_gusaddr + sc->sc_chanblocksize - 2));
  746           case AUDIO_ENCODING_ALAW:
  747           case AUDIO_ENCODING_ULAW:
  748           byte:
  749             /* we need to fetch the translated byte, then stuff it. */
  750             guspoke(iot, ioh2, sc->sc_gusaddr -
  751                     (sc->sc_nbufs - 1) * sc->sc_chanblocksize - 1,
  752                     guspeek(iot, ioh2,
  753                             sc->sc_gusaddr + sc->sc_chanblocksize - 1));
  754             break;
  755           }
  756         }
  757         /*
  758          * If this is the first half of stereo, "ignore" this one
  759          * and copy out the second half.
  760          */
  761         if (sc->sc_dmaoutintr == stereo_dmaintr) {
  762             (*sc->sc_dmaoutintr)(sc->sc_outarg);
  763             return;
  764         }
  765         /*
  766          * If the voice is stopped, then start it.  Reset the loop
  767          * and roll bits.  Call the audio layer routine, since if
  768          * we're starting a stopped voice, that means that the next
  769          * buffer can be filled
  770          */
  771 
  772         sc->sc_flags &= ~GUS_LOCKED;
  773         if (sc->sc_voc[GUS_VOICE_LEFT].voccntl &
  774             GUSMASK_VOICE_STOPPED) {
  775             if (sc->sc_flags & GUS_PLAYING) {
  776                 printf("%s: playing yet stopped?\n", sc->sc_dev.dv_xname);
  777             }
  778             sc->sc_bufcnt++; /* another yet to be played */
  779             gus_start_playing(sc, sc->sc_dmabuf);
  780             gus_restart++;
  781         } else {
  782             /*
  783              * set the sound action based on which buffer we
  784              * just transferred.  If we just transferred buffer 0
  785              * we want the sound to loop when it gets to the nth
  786              * buffer; if we just transferred
  787              * any other buffer, we want the sound to roll over
  788              * at least one more time.  The voice interrupt
  789              * handlers will take care of accounting &
  790              * setting control bits if it's not caught up to us
  791              * yet.
  792              */
  793             if (++sc->sc_bufcnt == 2) {
  794                 /*
  795                  * XXX
  796                  * If we're too slow in reaction here,
  797                  * the voice could be just approaching the
  798                  * end of its run.  It should be set to stop,
  799                  * so these adjustments might not DTRT.
  800                  */
  801                 if (sc->sc_dmabuf == 0 &&
  802                     sc->sc_playbuf == sc->sc_nbufs - 1) {
  803                     /* player is just at the last buf, we're at the
  804                        first.  Turn on looping, turn off rolling. */
  805                     sc->sc_voc[GUS_VOICE_LEFT].voccntl |= GUSMASK_LOOP_ENABLE;
  806                     sc->sc_voc[GUS_VOICE_LEFT].volcntl &= ~GUSMASK_VOICE_ROLL;
  807                     playstats[playcntr].vaction = 3;
  808                 } else {
  809                     /* player is at previous buf:
  810                        turn on rolling, turn off looping */
  811                     sc->sc_voc[GUS_VOICE_LEFT].voccntl &= ~GUSMASK_LOOP_ENABLE;
  812                     sc->sc_voc[GUS_VOICE_LEFT].volcntl |= GUSMASK_VOICE_ROLL;
  813                     playstats[playcntr].vaction = 4;
  814                 }
  815 #ifdef GUSPLAYDEBUG
  816                 if (gusstats) {
  817                   microtime(&playstats[playcntr].tv);
  818                   playstats[playcntr].endaddr = sc->sc_voc[GUS_VOICE_LEFT].end_addr;
  819                   playstats[playcntr].voccntl = sc->sc_voc[GUS_VOICE_LEFT].voccntl;
  820                   playstats[playcntr].volcntl = sc->sc_voc[GUS_VOICE_LEFT].volcntl;
  821                   playstats[playcntr].playbuf = sc->sc_playbuf;
  822                   playstats[playcntr].dmabuf = sc->sc_dmabuf;
  823                   playstats[playcntr].bufcnt = sc->sc_bufcnt;
  824                   playstats[playcntr++].curaddr = gus_get_curaddr(sc, GUS_VOICE_LEFT);
  825                   playcntr = playcntr % NDMARECS;
  826                 }
  827 #endif
  828                 bus_space_write_1(iot, ioh2, GUS_VOICE_SELECT, GUS_VOICE_LEFT);
  829                 SELECT_GUS_REG(iot, ioh2, GUSREG_VOICE_CNTL);
  830                 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[GUS_VOICE_LEFT].voccntl);
  831                 SELECT_GUS_REG(iot, ioh2, GUSREG_VOLUME_CONTROL);
  832                 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[GUS_VOICE_LEFT].volcntl);
  833             }
  834         }
  835         gus_bufcnt[sc->sc_bufcnt-1]++;
  836         /*
  837          * flip to the next DMA buffer
  838          */
  839 
  840         sc->sc_dmabuf = (sc->sc_dmabuf + 1) % sc->sc_nbufs;
  841         /*
  842          * See comments below about DMA admission control strategy.
  843          * We can call the upper level here if we have an
  844          * idle buffer (not currently playing) to DMA into.
  845          */
  846         if (sc->sc_dmaoutintr && sc->sc_bufcnt < sc->sc_nbufs) {
  847             /* clean out to prevent double calls */
  848             void (*pfunc)(void *) = sc->sc_dmaoutintr;
  849             void *arg = sc->sc_outarg;
  850 
  851             sc->sc_outarg = 0;
  852             sc->sc_dmaoutintr = 0;
  853             (*pfunc)(arg);
  854         }
  855 }
  856 
  857 /*
  858  * Service voice interrupts
  859  */
  860 
  861 int
  862 gus_voice_intr(struct gus_softc *sc)
  863 {
  864         bus_space_tag_t iot = sc->sc_iot;
  865         bus_space_handle_t ioh2 = sc->sc_ioh2;
  866         int ignore = 0, voice, rval = 0;
  867         unsigned char intr, status;
  868 
  869         /*
  870          * The point of this may not be obvious at first.  A voice can
  871          * interrupt more than once; according to the GUS SDK we are supposed
  872          * to ignore multiple interrupts for the same voice.
  873          */
  874 
  875         while(1) {
  876                 SELECT_GUS_REG(iot, ioh2, GUSREG_IRQ_STATUS);
  877                 intr = bus_space_read_1(iot, ioh2, GUS_DATA_HIGH);
  878 
  879                 if ((intr & (GUSMASK_WIRQ_VOLUME | GUSMASK_WIRQ_VOICE))
  880                         == (GUSMASK_WIRQ_VOLUME | GUSMASK_WIRQ_VOICE))
  881                         /*
  882                          * No more interrupts, time to return
  883                          */
  884                         return rval;
  885 
  886                 if ((intr & GUSMASK_WIRQ_VOICE) == 0) {
  887 
  888                     /*
  889                      * We've got a voice interrupt.  Ignore previous
  890                      * interrupts by the same voice.
  891                      */
  892 
  893                     rval = 1;
  894                     voice = intr & GUSMASK_WIRQ_VOICEMASK;
  895 
  896                     if ((1 << voice) & ignore)
  897                         break;
  898 
  899                     ignore |= 1 << voice;
  900 
  901                     /*
  902                      * If the voice is stopped, then force it to stop
  903                      * (this stops it from continuously generating IRQs)
  904                      */
  905 
  906                     SELECT_GUS_REG(iot, ioh2, GUSREG_VOICE_CNTL+0x80);
  907                     status = bus_space_read_1(iot, ioh2, GUS_DATA_HIGH);
  908                     if (status & GUSMASK_VOICE_STOPPED) {
  909                         if (voice != GUS_VOICE_LEFT) {
  910                             DMAPRINTF(("%s: spurious voice %d stop?\n",
  911                                        sc->sc_dev.dv_xname, voice));
  912                             gus_stop_voice(sc, voice, 0);
  913                             continue;
  914                         }
  915                         gus_stop_voice(sc, voice, 1);
  916                         /* also kill right voice */
  917                         gus_stop_voice(sc, GUS_VOICE_RIGHT, 0);
  918                         sc->sc_bufcnt--; /* it finished a buffer */
  919                         if (sc->sc_bufcnt > 0) {
  920                             /*
  921                              * probably a race to get here: the voice
  922                              * stopped while the DMA code was just trying to
  923                              * get the next buffer in place.
  924                              * Start the voice again.
  925                              */
  926                             printf("%s: stopped voice not drained? (%x)\n",
  927                                    sc->sc_dev.dv_xname, sc->sc_bufcnt);
  928                             gus_falsestops++;
  929 
  930                             sc->sc_playbuf = (sc->sc_playbuf + 1) % sc->sc_nbufs;
  931                             gus_start_playing(sc, sc->sc_playbuf);
  932                         } else if (sc->sc_bufcnt < 0) {
  933                             panic("%s: negative bufcnt in stopped voice",
  934                                    sc->sc_dev.dv_xname);
  935                         } else {
  936                             sc->sc_playbuf = -1; /* none are active */
  937                             gus_stops++;
  938                         }
  939                         /* fall through to callback and admit another
  940                            buffer.... */
  941                     } else if (sc->sc_bufcnt != 0) {
  942                         /*
  943                          * This should always be taken if the voice
  944                          * is not stopped.
  945                          */
  946                         gus_continues++;
  947                         if (gus_continue_playing(sc, voice)) {
  948                                 /*
  949                                  * we shouldn't have continued--active DMA
  950                                  * is in the way in the ring, for
  951                                  * some as-yet undebugged reason.
  952                                  */
  953                                 gus_stop_voice(sc, GUS_VOICE_LEFT, 1);
  954                                 /* also kill right voice */
  955                                 gus_stop_voice(sc, GUS_VOICE_RIGHT, 0);
  956                                 sc->sc_playbuf = -1;
  957                                 gus_stops++;
  958                         }
  959                     }
  960                     /*
  961                      * call the upper level to send on down another
  962                      * block. We do admission rate control as follows:
  963                      *
  964                      * When starting up output (in the first N
  965                      * blocks), call the upper layer after the DMA is
  966                      * complete (see above in gus_dmaout_intr()).
  967                      *
  968                      * When output is already in progress and we have
  969                      * no more GUS buffers to use for DMA, the DMA
  970                      * output routines do not call the upper layer.
  971                      * Instead, we call the DMA completion routine
  972                      * here, after the voice interrupts indicating
  973                      * that it's finished with a buffer.
  974                      *
  975                      * However, don't call anything here if the DMA
  976                      * output flag is set, (which shouldn't happen)
  977                      * because we'll squish somebody else's DMA if
  978                      * that's the case.  When DMA is done, it will
  979                      * call back if there is a spare buffer.
  980                      */
  981                     if (sc->sc_dmaoutintr && !(sc->sc_flags & GUS_LOCKED)) {
  982                         if (sc->sc_dmaoutintr == stereo_dmaintr)
  983                             printf("gusdmaout botch?\n");
  984                         else {
  985                             /* clean out to avoid double calls */
  986                             void (*pfunc)(void *) = sc->sc_dmaoutintr;
  987                             void *arg = sc->sc_outarg;
  988 
  989                             sc->sc_outarg = 0;
  990                             sc->sc_dmaoutintr = 0;
  991                             (*pfunc)(arg);
  992                         }
  993                     }
  994                 }
  995 
  996                 /*
  997                  * Ignore other interrupts for now
  998                  */
  999         }
 1000         return 0;
 1001 }
 1002 
 1003 void
 1004 gus_start_playing(struct gus_softc *sc, int bufno)
 1005 {
 1006         bus_space_tag_t iot = sc->sc_iot;
 1007         bus_space_handle_t ioh2 = sc->sc_ioh2;
 1008         /*
 1009          * Start the voices playing, with buffer BUFNO.
 1010          */
 1011 
 1012         /*
 1013          * Loop or roll if we have buffers ready.
 1014          */
 1015 
 1016         if (sc->sc_bufcnt == 1) {
 1017                 sc->sc_voc[GUS_VOICE_LEFT].voccntl &= ~(GUSMASK_LOOP_ENABLE);
 1018                 sc->sc_voc[GUS_VOICE_LEFT].volcntl &= ~(GUSMASK_VOICE_ROLL);
 1019         } else {
 1020                 if (bufno == sc->sc_nbufs - 1) {
 1021                         sc->sc_voc[GUS_VOICE_LEFT].voccntl |= GUSMASK_LOOP_ENABLE;
 1022                         sc->sc_voc[GUS_VOICE_LEFT].volcntl &= ~(GUSMASK_VOICE_ROLL);
 1023                 } else {
 1024                         sc->sc_voc[GUS_VOICE_LEFT].voccntl &= ~GUSMASK_LOOP_ENABLE;
 1025                         sc->sc_voc[GUS_VOICE_LEFT].volcntl |= GUSMASK_VOICE_ROLL;
 1026                 }
 1027         }
 1028 
 1029         bus_space_write_1(iot, ioh2, GUS_VOICE_SELECT, GUS_VOICE_LEFT);
 1030 
 1031         SELECT_GUS_REG(iot, ioh2, GUSREG_VOICE_CNTL);
 1032         bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[GUS_VOICE_LEFT].voccntl);
 1033 
 1034         SELECT_GUS_REG(iot, ioh2, GUSREG_VOLUME_CONTROL);
 1035         bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[GUS_VOICE_LEFT].volcntl);
 1036 
 1037         sc->sc_voc[GUS_VOICE_LEFT].current_addr =
 1038                 GUS_MEM_OFFSET + sc->sc_chanblocksize * bufno;
 1039         sc->sc_voc[GUS_VOICE_LEFT].end_addr =
 1040                 sc->sc_voc[GUS_VOICE_LEFT].current_addr + sc->sc_chanblocksize - 1;
 1041         sc->sc_voc[GUS_VOICE_RIGHT].current_addr =
 1042                 sc->sc_voc[GUS_VOICE_LEFT].current_addr +
 1043                 (gus_dostereo && sc->sc_channels == 2 ? GUS_LEFT_RIGHT_OFFSET : 0);
 1044         /*
 1045          * set up right channel to just loop forever, no interrupts,
 1046          * starting at the buffer we just filled.  We'll feed it data
 1047          * at the same time as left channel.
 1048          */
 1049         sc->sc_voc[GUS_VOICE_RIGHT].voccntl |= GUSMASK_LOOP_ENABLE;
 1050         sc->sc_voc[GUS_VOICE_RIGHT].volcntl &= ~(GUSMASK_VOICE_ROLL);
 1051 
 1052 #ifdef GUSPLAYDEBUG
 1053         if (gusstats) {
 1054                 microtime(&playstats[playcntr].tv);
 1055                 playstats[playcntr].curaddr = sc->sc_voc[GUS_VOICE_LEFT].current_addr;
 1056 
 1057                 playstats[playcntr].voccntl = sc->sc_voc[GUS_VOICE_LEFT].voccntl;
 1058                 playstats[playcntr].volcntl = sc->sc_voc[GUS_VOICE_LEFT].volcntl;
 1059                 playstats[playcntr].endaddr = sc->sc_voc[GUS_VOICE_LEFT].end_addr;
 1060                 playstats[playcntr].playbuf = bufno;
 1061                 playstats[playcntr].dmabuf = sc->sc_dmabuf;
 1062                 playstats[playcntr].bufcnt = sc->sc_bufcnt;
 1063                 playstats[playcntr++].vaction = 5;
 1064                 playcntr = playcntr % NDMARECS;
 1065         }
 1066 #endif
 1067 
 1068         bus_space_write_1(iot, ioh2, GUS_VOICE_SELECT, GUS_VOICE_RIGHT);
 1069         SELECT_GUS_REG(iot, ioh2, GUSREG_VOICE_CNTL);
 1070         bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[GUS_VOICE_RIGHT].voccntl);
 1071         SELECT_GUS_REG(iot, ioh2, GUSREG_VOLUME_CONTROL);
 1072         bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[GUS_VOICE_RIGHT].volcntl);
 1073 
 1074         gus_start_voice(sc, GUS_VOICE_RIGHT, 0);
 1075         gus_start_voice(sc, GUS_VOICE_LEFT, 1);
 1076         if (sc->sc_playbuf == -1)
 1077                 /* mark start of playing */
 1078                 sc->sc_playbuf = bufno;
 1079 }
 1080 
 1081 int
 1082 gus_continue_playing(struct gus_softc *sc, int voice)
 1083 {
 1084         bus_space_tag_t iot = sc->sc_iot;
 1085         bus_space_handle_t ioh2 = sc->sc_ioh2;
 1086 
 1087         /*
 1088          * stop this voice from interrupting while we work.
 1089          */
 1090 
 1091         SELECT_GUS_REG(iot, ioh2, GUSREG_VOICE_CNTL);
 1092         bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[voice].voccntl & ~(GUSMASK_VOICE_IRQ));
 1093 
 1094         /*
 1095          * update playbuf to point to the buffer the hardware just started
 1096          * playing
 1097          */
 1098         sc->sc_playbuf = (sc->sc_playbuf + 1) % sc->sc_nbufs;
 1099 
 1100         /*
 1101          * account for buffer just finished
 1102          */
 1103         if (--sc->sc_bufcnt == 0) {
 1104                 DPRINTF(("gus: bufcnt 0 on continuing voice?\n"));
 1105         }
 1106         if (sc->sc_playbuf == sc->sc_dmabuf && (sc->sc_flags & GUS_LOCKED)) {
 1107                 printf("%s: continue into active dmabuf?\n", sc->sc_dev.dv_xname);
 1108                 return 1;
 1109         }
 1110 
 1111         /*
 1112          * Select the end of the buffer based on the currently active
 1113          * buffer, [plus extra contiguous buffers (if ready)].
 1114          */
 1115 
 1116         /*
 1117          * set endpoint at end of buffer we just started playing.
 1118          *
 1119          * The total gets -1 because end addrs are one less than you might
 1120          * think (the end_addr is the address of the last sample to play)
 1121          */
 1122         gus_set_endaddr(sc, voice, GUS_MEM_OFFSET +
 1123                         sc->sc_chanblocksize * (sc->sc_playbuf + 1) - 1);
 1124 
 1125         if (sc->sc_bufcnt < 2) {
 1126                 /*
 1127                  * Clear out the loop and roll flags, and rotate the currently
 1128                  * playing buffer.  That way, if we don't manage to get more
 1129                  * data before this buffer finishes, we'll just stop.
 1130                  */
 1131                 sc->sc_voc[voice].voccntl &= ~GUSMASK_LOOP_ENABLE;
 1132                 sc->sc_voc[voice].volcntl &= ~GUSMASK_VOICE_ROLL;
 1133                 playstats[playcntr].vaction = 0;
 1134         } else {
 1135                 /*
 1136                  * We have some buffers to play.  set LOOP if we're on the
 1137                  * last buffer in the ring, otherwise set ROLL.
 1138                  */
 1139                 if (sc->sc_playbuf == sc->sc_nbufs - 1) {
 1140                         sc->sc_voc[voice].voccntl |= GUSMASK_LOOP_ENABLE;
 1141                         sc->sc_voc[voice].volcntl &= ~GUSMASK_VOICE_ROLL;
 1142                         playstats[playcntr].vaction = 1;
 1143                 } else {
 1144                         sc->sc_voc[voice].voccntl &= ~GUSMASK_LOOP_ENABLE;
 1145                         sc->sc_voc[voice].volcntl |= GUSMASK_VOICE_ROLL;
 1146                         playstats[playcntr].vaction = 2;
 1147                 }
 1148         }
 1149 #ifdef GUSPLAYDEBUG
 1150         if (gusstats) {
 1151                 microtime(&playstats[playcntr].tv);
 1152                 playstats[playcntr].curaddr = gus_get_curaddr(sc, voice);
 1153 
 1154                 playstats[playcntr].voccntl = sc->sc_voc[voice].voccntl;
 1155                 playstats[playcntr].volcntl = sc->sc_voc[voice].volcntl;
 1156                 playstats[playcntr].endaddr = sc->sc_voc[voice].end_addr;
 1157                 playstats[playcntr].playbuf = sc->sc_playbuf;
 1158                 playstats[playcntr].dmabuf = sc->sc_dmabuf;
 1159                 playstats[playcntr++].bufcnt = sc->sc_bufcnt;
 1160                 playcntr = playcntr % NDMARECS;
 1161         }
 1162 #endif
 1163 
 1164         /*
 1165          * (re-)set voice parameters.  This will reenable interrupts from this
 1166          * voice.
 1167          */
 1168 
 1169         SELECT_GUS_REG(iot, ioh2, GUSREG_VOICE_CNTL);
 1170         bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[voice].voccntl);
 1171         SELECT_GUS_REG(iot, ioh2, GUSREG_VOLUME_CONTROL);
 1172         bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[voice].volcntl);
 1173         return 0;
 1174 }
 1175 
 1176 /*
 1177  * Send/receive data into GUS's DRAM using DMA.  Called at splaudio()
 1178  */
 1179 
 1180 void
 1181 gusdmaout(struct gus_softc *sc, int flags, u_long gusaddr, caddr_t buffaddr,
 1182     int length)
 1183 {
 1184         unsigned char c = (unsigned char) flags;
 1185         bus_space_tag_t iot = sc->sc_iot;
 1186         bus_space_handle_t ioh2 = sc->sc_ioh2;
 1187 
 1188         DMAPRINTF(("gusdmaout flags=%x scflags=%x\n", flags, sc->sc_flags));
 1189 
 1190         sc->sc_gusaddr = gusaddr;
 1191 
 1192         /*
 1193          * If we're using a 16 bit DMA channel, we have to jump through some
 1194          * extra hoops; this includes translating the DRAM address a bit
 1195          */
 1196 
 1197         if (sc->sc_drq >= 4) {
 1198                 c |= GUSMASK_DMA_WIDTH;
 1199                 gusaddr = convert_to_16bit(gusaddr);
 1200         }
 1201 
 1202         /*
 1203          * Add flag bits that we always set - fast DMA, enable IRQ
 1204          */
 1205 
 1206         c |= GUSMASK_DMA_ENABLE | GUSMASK_DMA_R0 | GUSMASK_DMA_IRQ;
 1207 
 1208         /*
 1209          * Make sure the GUS _isn't_ setup for DMA
 1210          */
 1211 
 1212         SELECT_GUS_REG(iot, ioh2, GUSREG_DMA_CONTROL);
 1213         bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0);
 1214 
 1215         /*
 1216          * Tell the PC DMA controller to start doing DMA
 1217          */
 1218 
 1219         sc->sc_dmaoutaddr = (u_char *) buffaddr;
 1220         sc->sc_dmaoutcnt = length;
 1221         isa_dmastart(sc->sc_dev.dv_parent, sc->sc_drq, buffaddr, length,
 1222             NULL, DMAMODE_WRITE, BUS_DMA_NOWAIT);
 1223 
 1224         /*
 1225          * Set up DMA address - use the upper 16 bits ONLY
 1226          */
 1227 
 1228         sc->sc_flags |= GUS_DMAOUT_ACTIVE;
 1229 
 1230         SELECT_GUS_REG(iot, ioh2, GUSREG_DMA_START);
 1231         bus_space_write_2(iot, ioh2, GUS_DATA_LOW, (int) (gusaddr >> 4));
 1232 
 1233         /*
 1234          * Tell the GUS to start doing DMA
 1235          */
 1236 
 1237         SELECT_GUS_REG(iot, ioh2, GUSREG_DMA_CONTROL);
 1238         bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, c);
 1239 
 1240         /*
 1241          * XXX If we don't finish in one second, give up...
 1242          */
 1243         timeout_add_sec(&sc->sc_dma_tmo, 1);
 1244 }
 1245 
 1246 /*
 1247  * Start a voice playing on the GUS.  Called from interrupt handler at
 1248  * splaudio().
 1249  */
 1250 
 1251 void
 1252 gus_start_voice(struct gus_softc *sc, int voice, int intrs)
 1253 {
 1254         bus_space_tag_t iot = sc->sc_iot;
 1255         bus_space_handle_t ioh2 = sc->sc_ioh2;
 1256         u_long start;
 1257         u_long current;
 1258         u_long end;
 1259 
 1260         /*
 1261          * Pick all the values for the voice out of the gus_voice struct
 1262          * and use those to program the voice
 1263          */
 1264 
 1265         start = sc->sc_voc[voice].start_addr;
 1266         current = sc->sc_voc[voice].current_addr;
 1267         end = sc->sc_voc[voice].end_addr;
 1268 
 1269         /*
 1270          * If we're using 16 bit data, mangle the addresses a bit
 1271          */
 1272 
 1273         if (sc->sc_voc[voice].voccntl & GUSMASK_DATA_SIZE16) {
 1274                 /* -1 on start so that we get onto sample boundary--other
 1275                    code always sets it for 1-byte rollover protection */
 1276                 start = convert_to_16bit(start-1);
 1277                 current = convert_to_16bit(current);
 1278                 end = convert_to_16bit(end);
 1279         }
 1280 
 1281         /*
 1282          * Select the voice we want to use, and program the data addresses
 1283          */
 1284 
 1285         bus_space_write_1(iot, ioh2, GUS_VOICE_SELECT, (unsigned char) voice);
 1286 
 1287         SELECT_GUS_REG(iot, ioh2, GUSREG_START_ADDR_HIGH);
 1288         bus_space_write_2(iot, ioh2, GUS_DATA_LOW, ADDR_HIGH(start));
 1289         SELECT_GUS_REG(iot, ioh2, GUSREG_START_ADDR_LOW);
 1290         bus_space_write_2(iot, ioh2, GUS_DATA_LOW, ADDR_LOW(start));
 1291 
 1292         SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_ADDR_HIGH);
 1293         bus_space_write_2(iot, ioh2, GUS_DATA_LOW, ADDR_HIGH(current));
 1294         SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_ADDR_LOW);
 1295         bus_space_write_2(iot, ioh2, GUS_DATA_LOW, ADDR_LOW(current));
 1296 
 1297         SELECT_GUS_REG(iot, ioh2, GUSREG_END_ADDR_HIGH);
 1298         bus_space_write_2(iot, ioh2, GUS_DATA_LOW, ADDR_HIGH(end));
 1299         SELECT_GUS_REG(iot, ioh2, GUSREG_END_ADDR_LOW);
 1300         bus_space_write_2(iot, ioh2, GUS_DATA_LOW, ADDR_LOW(end));
 1301 
 1302         /*
 1303          * (maybe) enable interrupts, disable voice stopping
 1304          */
 1305 
 1306         if (intrs) {
 1307                 sc->sc_flags |= GUS_PLAYING; /* playing is about to start */
 1308                 sc->sc_voc[voice].voccntl |= GUSMASK_VOICE_IRQ;
 1309                 DMAPRINTF(("gus voice playing=%x\n", sc->sc_flags));
 1310         } else
 1311                 sc->sc_voc[voice].voccntl &= ~GUSMASK_VOICE_IRQ;
 1312         sc->sc_voc[voice].voccntl &= ~(GUSMASK_VOICE_STOPPED |
 1313                 GUSMASK_STOP_VOICE);
 1314 
 1315         /*
 1316          * Tell the GUS about it.  Note that we're doing volume ramping here
 1317          * from 0 up to the set volume to help reduce clicks.
 1318          */
 1319 
 1320         SELECT_GUS_REG(iot, ioh2, GUSREG_START_VOLUME);
 1321         bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0x00);
 1322         SELECT_GUS_REG(iot, ioh2, GUSREG_END_VOLUME);
 1323         bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[voice].current_volume >> 4);
 1324         SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_VOLUME);
 1325         bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x00);
 1326         SELECT_GUS_REG(iot, ioh2, GUSREG_VOLUME_RATE);
 1327         bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 63);
 1328 
 1329         SELECT_GUS_REG(iot, ioh2, GUSREG_VOICE_CNTL);
 1330         bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[voice].voccntl);
 1331         SELECT_GUS_REG(iot, ioh2, GUSREG_VOLUME_CONTROL);
 1332         bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0x00);
 1333         delay(50);
 1334         SELECT_GUS_REG(iot, ioh2, GUSREG_VOICE_CNTL);
 1335         bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[voice].voccntl);
 1336         SELECT_GUS_REG(iot, ioh2, GUSREG_VOLUME_CONTROL);
 1337         bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0x00);
 1338 
 1339 }
 1340 
 1341 /*
 1342  * Stop a given voice.  Called at splaudio().
 1343  */
 1344 
 1345 void
 1346 gus_stop_voice(struct gus_softc *sc, int voice, int intrs_too)
 1347 {
 1348         bus_space_tag_t iot = sc->sc_iot;
 1349         bus_space_handle_t ioh2 = sc->sc_ioh2;
 1350 
 1351         sc->sc_voc[voice].voccntl |= GUSMASK_VOICE_STOPPED |
 1352                 GUSMASK_STOP_VOICE;
 1353         if (intrs_too) {
 1354           sc->sc_voc[voice].voccntl &= ~(GUSMASK_VOICE_IRQ);
 1355           /* no more DMA to do */
 1356           sc->sc_flags &= ~GUS_PLAYING;
 1357         }
 1358         DMAPRINTF(("gusintr voice notplaying=%x\n", sc->sc_flags));
 1359 
 1360         guspoke(iot, ioh2, 0L, 0);
 1361 
 1362         bus_space_write_1(iot, ioh2, GUS_VOICE_SELECT, (unsigned char) voice);
 1363 
 1364         SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_VOLUME);
 1365         bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x0000);
 1366         SELECT_GUS_REG(iot, ioh2, GUSREG_VOICE_CNTL);
 1367         bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[voice].voccntl);
 1368         delay(100);
 1369         SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_VOLUME);
 1370         bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x0000);
 1371         SELECT_GUS_REG(iot, ioh2, GUSREG_VOICE_CNTL);
 1372         bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[voice].voccntl);
 1373 
 1374         SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_ADDR_HIGH);
 1375         bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x0000);
 1376         SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_ADDR_LOW);
 1377         bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x0000);
 1378 
 1379 }
 1380 
 1381 
 1382 /*
 1383  * Set the volume of a given voice.  Called at splaudio().
 1384  */
 1385 void
 1386 gus_set_volume(struct gus_softc *sc, int voice, int volume)
 1387 {
 1388         bus_space_tag_t iot = sc->sc_iot;
 1389         bus_space_handle_t ioh2 = sc->sc_ioh2;
 1390         unsigned int gusvol;
 1391 
 1392         gusvol = gus_log_volumes[volume < 512 ? volume : 511];
 1393 
 1394         sc->sc_voc[voice].current_volume = gusvol;
 1395 
 1396         bus_space_write_1(iot, ioh2, GUS_VOICE_SELECT, (unsigned char) voice);
 1397 
 1398         SELECT_GUS_REG(iot, ioh2, GUSREG_START_VOLUME);
 1399         bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, (unsigned char) (gusvol >> 4));
 1400 
 1401         SELECT_GUS_REG(iot, ioh2, GUSREG_END_VOLUME);
 1402         bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, (unsigned char) (gusvol >> 4));
 1403 
 1404         SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_VOLUME);
 1405         bus_space_write_2(iot, ioh2, GUS_DATA_LOW, gusvol << 4);
 1406         delay(500);
 1407         bus_space_write_2(iot, ioh2, GUS_DATA_LOW, gusvol << 4);
 1408 
 1409 }
 1410 
 1411 /*
 1412  * Interface to the audio layer.
 1413  */
 1414 
 1415 int
 1416 gusmax_set_params(void *addr, int setmode, int usemode, struct audio_params *p,
 1417     struct audio_params *r)
 1418 {
 1419         struct ad1848_softc *ac = addr;
 1420         struct gus_softc *sc = ac->parent;
 1421         int error;
 1422 
 1423         error = ad1848_set_params(ac, setmode, usemode, p, r);
 1424         if (error)
 1425                 return error;
 1426         error = gus_set_params(sc, setmode, usemode, p, r);
 1427         return error;
 1428 }
 1429 
 1430 int
 1431 gus_set_params(void *addr, int setmode, int usemode, struct audio_params *p,
 1432     struct audio_params *r)
 1433 {
 1434         struct gus_softc *sc = addr;
 1435 
 1436         switch (p->encoding) {
 1437         case AUDIO_ENCODING_SLINEAR_LE:
 1438         case AUDIO_ENCODING_ULINEAR_LE:
 1439                 break;
 1440         default:
 1441                 return (EINVAL);
 1442         }
 1443 
 1444         /* XXX: why?! this is called with interrupts disabled */
 1445         mtx_enter(&audio_lock);
 1446 
 1447         if (p->precision == 8) {
 1448                 sc->sc_voc[GUS_VOICE_LEFT].voccntl &= ~GUSMASK_DATA_SIZE16;
 1449                 sc->sc_voc[GUS_VOICE_RIGHT].voccntl &= ~GUSMASK_DATA_SIZE16;
 1450         } else {
 1451                 sc->sc_voc[GUS_VOICE_LEFT].voccntl |= GUSMASK_DATA_SIZE16;
 1452                 sc->sc_voc[GUS_VOICE_RIGHT].voccntl |= GUSMASK_DATA_SIZE16;
 1453         }
 1454 
 1455         sc->sc_encoding = p->encoding;
 1456         sc->sc_precision = p->precision;
 1457         sc->sc_channels = p->channels;
 1458 
 1459         mtx_leave(&audio_lock);
 1460 
 1461         if (p->sample_rate > gus_max_frequency[sc->sc_voices - GUS_MIN_VOICES])
 1462                 p->sample_rate = gus_max_frequency[sc->sc_voices - GUS_MIN_VOICES];
 1463         if (setmode & AUMODE_RECORD)
 1464                 sc->sc_irate = p->sample_rate;
 1465         if (setmode & AUMODE_PLAY)
 1466                 sc->sc_orate = p->sample_rate;
 1467 
 1468         p->bps = AUDIO_BPS(p->precision);
 1469         r->bps = AUDIO_BPS(r->precision);
 1470         p->msb = r->msb = 1;
 1471 
 1472         return 0;
 1473 }
 1474 
 1475 /*
 1476  * Interface to the audio layer - set the blocksize to the correct number
 1477  * of units
 1478  */
 1479 
 1480 int
 1481 gusmax_round_blocksize(void *addr, int blocksize)
 1482 {
 1483         struct ad1848_softc *ac = addr;
 1484         struct gus_softc *sc = ac->parent;
 1485 
 1486 /*      blocksize = ad1848_round_blocksize(ac, blocksize);*/
 1487         return gus_round_blocksize(sc, blocksize);
 1488 }
 1489 
 1490 int
 1491 gus_round_blocksize(void *addr, int blocksize)
 1492 {
 1493         struct gus_softc *sc = addr;
 1494 
 1495         DPRINTF(("gus_round_blocksize called\n"));
 1496 
 1497         if ((sc->sc_encoding == AUDIO_ENCODING_ULAW ||
 1498              sc->sc_encoding == AUDIO_ENCODING_ALAW) && blocksize > 32768)
 1499                 blocksize = 32768;
 1500         else if (blocksize > 65536)
 1501                 blocksize = 65536;
 1502 
 1503         if ((blocksize % GUS_BUFFER_MULTIPLE) != 0)
 1504                 blocksize = (blocksize / GUS_BUFFER_MULTIPLE + 1) *
 1505                         GUS_BUFFER_MULTIPLE;
 1506 
 1507         /* set up temporary buffer to hold the deinterleave, if necessary
 1508            for stereo output */
 1509         if (sc->sc_deintr_buf) {
 1510                 free(sc->sc_deintr_buf, M_DEVBUF, 0);
 1511                 sc->sc_deintr_buf = NULL;
 1512         }
 1513         sc->sc_deintr_buf = malloc(blocksize/2, M_DEVBUF, M_WAITOK);
 1514 
 1515         sc->sc_blocksize = blocksize;
 1516         /* multi-buffering not quite working yet. */
 1517         sc->sc_nbufs = /*GUS_MEM_FOR_BUFFERS / blocksize*/ 2;
 1518 
 1519         gus_set_chan_addrs(sc);
 1520 
 1521         return blocksize;
 1522 }
 1523 
 1524 int
 1525 gus_get_out_gain(caddr_t addr)
 1526 {
 1527         struct gus_softc *sc = (struct gus_softc *) addr;
 1528 
 1529         DPRINTF(("gus_get_out_gain called\n"));
 1530         return sc->sc_ogain / 2;
 1531 }
 1532 
 1533 inline void
 1534 gus_set_voices(struct gus_softc *sc, int voices)
 1535 {
 1536         bus_space_tag_t iot = sc->sc_iot;
 1537         bus_space_handle_t ioh2 = sc->sc_ioh2;
 1538         /*
 1539          * Select the active number of voices
 1540          */
 1541 
 1542         SELECT_GUS_REG(iot, ioh2, GUSREG_ACTIVE_VOICES);
 1543         bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, (voices-1) | 0xc0);
 1544 
 1545         sc->sc_voices = voices;
 1546 }
 1547 
 1548 /*
 1549  * Actually set the settings of various values on the card
 1550  */
 1551 
 1552 int
 1553 gusmax_commit_settings(void *addr)
 1554 {
 1555         struct ad1848_softc *ac = addr;
 1556         struct gus_softc *sc = ac->parent;
 1557         int error;
 1558 
 1559         error = ad1848_commit_settings(ac);
 1560         if (error)
 1561                 return error;
 1562         return gus_commit_settings(sc);
 1563 }
 1564 
 1565 /*
 1566  * Commit the settings.  Called at normal IPL.
 1567  */
 1568 int
 1569 gus_commit_settings(void *addr)
 1570 {
 1571         struct gus_softc *sc = addr;
 1572 
 1573         DPRINTF(("gus_commit_settings called (gain = %d)\n",sc->sc_ogain));
 1574 
 1575 
 1576         /* XXX: why?! this is called with interrupts disabled */
 1577         mtx_enter(&audio_lock);
 1578 
 1579         gus_set_recrate(sc, sc->sc_irate);
 1580         gus_set_volume(sc, GUS_VOICE_LEFT, sc->sc_ogain);
 1581         gus_set_volume(sc, GUS_VOICE_RIGHT, sc->sc_ogain);
 1582         gus_set_samprate(sc, GUS_VOICE_LEFT, sc->sc_orate);
 1583         gus_set_samprate(sc, GUS_VOICE_RIGHT, sc->sc_orate);
 1584         mtx_leave(&audio_lock);
 1585         gus_set_chan_addrs(sc);
 1586 
 1587         return 0;
 1588 }
 1589 
 1590 void
 1591 gus_set_chan_addrs(struct gus_softc *sc)
 1592 {
 1593         /*
 1594          * We use sc_nbufs * blocksize bytes of storage in the on-board GUS
 1595          * ram.
 1596          * For mono, each of the sc_nbufs buffers is DMA'd to in one chunk,
 1597          * and both left & right channels play the same buffer.
 1598          *
 1599          * For stereo, each channel gets a contiguous half of the memory,
 1600          * and each has sc_nbufs buffers of size blocksize/2.
 1601          * Stereo data are deinterleaved in main memory before the DMA out
 1602          * routines are called to queue the output.
 1603          *
 1604          * The blocksize per channel is kept in sc_chanblocksize.
 1605          */
 1606         if (sc->sc_channels == 2)
 1607             sc->sc_chanblocksize = sc->sc_blocksize/2;
 1608         else
 1609             sc->sc_chanblocksize = sc->sc_blocksize;
 1610 
 1611         sc->sc_voc[GUS_VOICE_LEFT].start_addr = GUS_MEM_OFFSET - 1;
 1612         sc->sc_voc[GUS_VOICE_RIGHT].start_addr =
 1613             (gus_dostereo && sc->sc_channels == 2 ? GUS_LEFT_RIGHT_OFFSET : 0)
 1614               + GUS_MEM_OFFSET - 1;
 1615         sc->sc_voc[GUS_VOICE_RIGHT].current_addr =
 1616             sc->sc_voc[GUS_VOICE_RIGHT].start_addr + 1;
 1617         sc->sc_voc[GUS_VOICE_RIGHT].end_addr =
 1618             sc->sc_voc[GUS_VOICE_RIGHT].start_addr +
 1619             sc->sc_nbufs * sc->sc_chanblocksize;
 1620 
 1621 }
 1622 
 1623 /*
 1624  * Set the sample rate of the given voice.  Called at splaudio().
 1625  */
 1626 
 1627 void
 1628 gus_set_samprate(struct gus_softc *sc, int voice, int freq)
 1629 {
 1630         bus_space_tag_t iot = sc->sc_iot;
 1631         bus_space_handle_t ioh2 = sc->sc_ioh2;
 1632         unsigned int fc;
 1633         u_long temp, f = (u_long) freq;
 1634 
 1635         /*
 1636          * calculate fc based on the number of active voices;
 1637          * we need to use longs to preserve enough bits
 1638          */
 1639 
 1640         temp = (u_long) gus_max_frequency[sc->sc_voices-GUS_MIN_VOICES];
 1641 
 1642         fc = (unsigned int)(((f << 9L) + (temp >> 1L)) / temp);
 1643 
 1644         fc <<= 1;
 1645 
 1646 
 1647         /*
 1648          * Program the voice frequency, and set it in the voice data record
 1649          */
 1650 
 1651         bus_space_write_1(iot, ioh2, GUS_VOICE_SELECT, (unsigned char) voice);
 1652         SELECT_GUS_REG(iot, ioh2, GUSREG_FREQ_CONTROL);
 1653         bus_space_write_2(iot, ioh2, GUS_DATA_LOW, fc);
 1654 
 1655         sc->sc_voc[voice].rate = freq;
 1656 
 1657 }
 1658 
 1659 /*
 1660  * Set the sample rate of the recording frequency.  Formula is from the GUS
 1661  * SDK.  Called at splaudio().
 1662  */
 1663 
 1664 void
 1665 gus_set_recrate(struct gus_softc *sc, u_long rate)
 1666 {
 1667         bus_space_tag_t iot = sc->sc_iot;
 1668         bus_space_handle_t ioh2 = sc->sc_ioh2;
 1669         u_char realrate;
 1670         DPRINTF(("gus_set_recrate %lu\n", rate));
 1671 
 1672 #if 0
 1673         realrate = 9878400/(16*(rate+2)); /* formula from GUS docs */
 1674 #endif
 1675         realrate = (9878400 >> 4)/rate - 2; /* formula from code, sigh. */
 1676 
 1677         SELECT_GUS_REG(iot, ioh2, GUSREG_SAMPLE_FREQ);
 1678         bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, realrate);
 1679 }
 1680 
 1681 /*
 1682  * Turn the output on or off.  Note that some
 1683  * of these bits are flipped in the register
 1684  */
 1685 
 1686 int
 1687 gus_speaker_ctl(void *addr, int newstate)
 1688 {
 1689         struct gus_softc *sc = (struct gus_softc *) addr;
 1690         bus_space_tag_t iot = sc->sc_iot;
 1691         bus_space_handle_t ioh1 = sc->sc_ioh1;
 1692 
 1693         /* Line out bit is flipped: 0 enables, 1 disables */
 1694         if ((newstate == SPKR_ON) &&
 1695             (sc->sc_mixcontrol & GUSMASK_LINE_OUT)) {
 1696                 sc->sc_mixcontrol &= ~GUSMASK_LINE_OUT;
 1697                 bus_space_write_1(iot, ioh1, GUS_MIX_CONTROL, sc->sc_mixcontrol);
 1698         }
 1699         if ((newstate == SPKR_OFF) &&
 1700             (sc->sc_mixcontrol & GUSMASK_LINE_OUT) == 0) {
 1701                 sc->sc_mixcontrol |= GUSMASK_LINE_OUT;
 1702                 bus_space_write_1(iot, ioh1, GUS_MIX_CONTROL, sc->sc_mixcontrol);
 1703         }
 1704 
 1705         return 0;
 1706 }
 1707 
 1708 int
 1709 gus_linein_ctl(void *addr, int newstate)
 1710 {
 1711         struct gus_softc *sc = (struct gus_softc *) addr;
 1712         bus_space_tag_t iot = sc->sc_iot;
 1713         bus_space_handle_t ioh1 = sc->sc_ioh1;
 1714 
 1715         /* Line in bit is flipped: 0 enables, 1 disables */
 1716         if ((newstate == SPKR_ON) &&
 1717             (sc->sc_mixcontrol & GUSMASK_LINE_IN)) {
 1718                 sc->sc_mixcontrol &= ~GUSMASK_LINE_IN;
 1719                 bus_space_write_1(iot, ioh1, GUS_MIX_CONTROL, sc->sc_mixcontrol);
 1720         }
 1721         if ((newstate == SPKR_OFF) &&
 1722             (sc->sc_mixcontrol & GUSMASK_LINE_IN) == 0) {
 1723                 sc->sc_mixcontrol |= GUSMASK_LINE_IN;
 1724                 bus_space_write_1(iot, ioh1, GUS_MIX_CONTROL, sc->sc_mixcontrol);
 1725         }
 1726 
 1727         return 0;
 1728 }
 1729 
 1730 int
 1731 gus_mic_ctl(void *addr, int newstate)
 1732 {
 1733         struct gus_softc *sc = (struct gus_softc *) addr;
 1734         bus_space_tag_t iot = sc->sc_iot;
 1735         bus_space_handle_t ioh1 = sc->sc_ioh1;
 1736 
 1737         /* Mic bit is normal: 1 enables, 0 disables */
 1738         if ((newstate == SPKR_ON) &&
 1739             (sc->sc_mixcontrol & GUSMASK_MIC_IN) == 0) {
 1740                 sc->sc_mixcontrol |= GUSMASK_MIC_IN;
 1741                 bus_space_write_1(iot, ioh1, GUS_MIX_CONTROL, sc->sc_mixcontrol);
 1742         }
 1743         if ((newstate == SPKR_OFF) &&
 1744             (sc->sc_mixcontrol & GUSMASK_MIC_IN)) {
 1745                 sc->sc_mixcontrol &= ~GUSMASK_MIC_IN;
 1746                 bus_space_write_1(iot, ioh1, GUS_MIX_CONTROL, sc->sc_mixcontrol);
 1747         }
 1748 
 1749         return 0;
 1750 }
 1751 
 1752 /*
 1753  * Set the end address of a give voice.  Called at splaudio().
 1754  */
 1755 
 1756 void
 1757 gus_set_endaddr(struct gus_softc *sc, int voice, u_long addr)
 1758 {
 1759         bus_space_tag_t iot = sc->sc_iot;
 1760         bus_space_handle_t ioh2 = sc->sc_ioh2;
 1761 
 1762         sc->sc_voc[voice].end_addr = addr;
 1763 
 1764         if (sc->sc_voc[voice].voccntl & GUSMASK_DATA_SIZE16)
 1765                 addr = convert_to_16bit(addr);
 1766 
 1767         SELECT_GUS_REG(iot, ioh2, GUSREG_END_ADDR_HIGH);
 1768         bus_space_write_2(iot, ioh2, GUS_DATA_LOW, ADDR_HIGH(addr));
 1769         SELECT_GUS_REG(iot, ioh2, GUSREG_END_ADDR_LOW);
 1770         bus_space_write_2(iot, ioh2, GUS_DATA_LOW, ADDR_LOW(addr));
 1771 
 1772 }
 1773 
 1774 #ifdef GUSPLAYDEBUG
 1775 /*
 1776  * Set current address.  Called at splaudio().
 1777  */
 1778 void
 1779 gus_set_curaddr(struct gus_softc *sc, int voice, u_long addr)
 1780 {
 1781         bus_space_tag_t iot = sc->sc_iot;
 1782         bus_space_handle_t ioh2 = sc->sc_ioh2;
 1783 
 1784         sc->sc_voc[voice].current_addr = addr;
 1785 
 1786         if (sc->sc_voc[voice].voccntl & GUSMASK_DATA_SIZE16)
 1787                 addr = convert_to_16bit(addr);
 1788 
 1789         bus_space_write_1(iot, ioh2, GUS_VOICE_SELECT, (unsigned char) voice);
 1790 
 1791         SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_ADDR_HIGH);
 1792         bus_space_write_2(iot, ioh2, GUS_DATA_LOW, ADDR_HIGH(addr));
 1793         SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_ADDR_LOW);
 1794         bus_space_write_2(iot, ioh2, GUS_DATA_LOW, ADDR_LOW(addr));
 1795 
 1796 }
 1797 
 1798 /*
 1799  * Get current GUS playback address.  Called at splaudio().
 1800  */
 1801 u_long
 1802 gus_get_curaddr(struct gus_softc *sc, int voice)
 1803 {
 1804         bus_space_tag_t iot = sc->sc_iot;
 1805         bus_space_handle_t ioh2 = sc->sc_ioh2;
 1806         u_long addr;
 1807 
 1808         bus_space_write_1(iot, ioh2, GUS_VOICE_SELECT, (unsigned char) voice);
 1809         SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_ADDR_HIGH|GUSREG_READ);
 1810         addr = (bus_space_read_2(iot, ioh2, GUS_DATA_LOW) & 0x1fff) << 7;
 1811         SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_ADDR_LOW|GUSREG_READ);
 1812         addr |= (bus_space_read_2(iot, ioh2, GUS_DATA_LOW) >> 9L) & 0x7f;
 1813 
 1814         if (sc->sc_voc[voice].voccntl & GUSMASK_DATA_SIZE16)
 1815             addr = (addr & 0xc0000) | ((addr & 0x1ffff) << 1); /* undo 16-bit change */
 1816         DPRINTF(("gus voice %d curaddr %ld end_addr %ld\n",
 1817                  voice, addr, sc->sc_voc[voice].end_addr));
 1818         /* XXX sanity check the address? */
 1819 
 1820         return(addr);
 1821 }
 1822 #endif
 1823 
 1824 /*
 1825  * Convert an address value to a "16 bit" value - why this is necessary I
 1826  * have NO idea
 1827  */
 1828 
 1829 u_long
 1830 convert_to_16bit(u_long address)
 1831 {
 1832         u_long old_address;
 1833 
 1834         old_address = address;
 1835         address >>= 1;
 1836         address &= 0x0001ffffL;
 1837         address |= (old_address & 0x000c0000L);
 1838 
 1839         return (address);
 1840 }
 1841 
 1842 /*
 1843  * Write a value into the GUS's DRAM
 1844  */
 1845 
 1846 void
 1847 guspoke(bus_space_tag_t iot, bus_space_handle_t ioh2, long address,
 1848     unsigned char value)
 1849 {
 1850 
 1851         /*
 1852          * Select the DRAM address
 1853          */
 1854 
 1855         SELECT_GUS_REG(iot, ioh2, GUSREG_DRAM_ADDR_LOW);
 1856         bus_space_write_2(iot, ioh2, GUS_DATA_LOW, (unsigned int) (address & 0xffff));
 1857         SELECT_GUS_REG(iot, ioh2, GUSREG_DRAM_ADDR_HIGH);
 1858         bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, (unsigned char) ((address >> 16) & 0xff));
 1859 
 1860         /*
 1861          * Actually write the data
 1862          */
 1863 
 1864         bus_space_write_1(iot, ioh2, GUS_DRAM_DATA, value);
 1865 }
 1866 
 1867 /*
 1868  * Read a value from the GUS's DRAM
 1869  */
 1870 
 1871 unsigned char
 1872 guspeek(bus_space_tag_t iot, bus_space_handle_t ioh2, u_long address)
 1873 {
 1874 
 1875         /*
 1876          * Select the DRAM address
 1877          */
 1878 
 1879         SELECT_GUS_REG(iot, ioh2, GUSREG_DRAM_ADDR_LOW);
 1880         bus_space_write_2(iot, ioh2, GUS_DATA_LOW, (unsigned int) (address & 0xffff));
 1881         SELECT_GUS_REG(iot, ioh2, GUSREG_DRAM_ADDR_HIGH);
 1882         bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, (unsigned char) ((address >> 16) & 0xff));
 1883 
 1884         /*
 1885          * Read in the data from the board
 1886          */
 1887 
 1888         return (unsigned char) bus_space_read_1(iot, ioh2, GUS_DRAM_DATA);
 1889 }
 1890 
 1891 /*
 1892  * Reset the Gravis UltraSound card, completely
 1893  */
 1894 
 1895 void
 1896 gusreset(struct gus_softc *sc, int voices)
 1897 {
 1898         bus_space_tag_t iot = sc->sc_iot;
 1899         bus_space_handle_t ioh1 = sc->sc_ioh1;
 1900         bus_space_handle_t ioh2 = sc->sc_ioh2;
 1901         bus_space_handle_t ioh4 = sc->sc_ioh4;
 1902         int i;
 1903 
 1904         mtx_enter(&audio_lock);
 1905 
 1906         /*
 1907          * Reset the GF1 chip
 1908          */
 1909 
 1910         SELECT_GUS_REG(iot, ioh2, GUSREG_RESET);
 1911         bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0x00);
 1912 
 1913         delay(500);
 1914 
 1915         /*
 1916          * Release reset
 1917          */
 1918 
 1919         SELECT_GUS_REG(iot, ioh2, GUSREG_RESET);
 1920         bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, GUSMASK_MASTER_RESET);
 1921 
 1922         delay(500);
 1923 
 1924         /*
 1925          * Reset MIDI port as well, if applicable
 1926          */
 1927 
 1928         if (ioh4 != (bus_space_handle_t)NULL) {
 1929                 bus_space_write_1(iot, ioh4, GUS_MIDI_CONTROL, MIDI_RESET);
 1930 
 1931                 delay(500);
 1932 
 1933                 bus_space_write_1(iot, ioh4, GUS_MIDI_CONTROL, 0x00);
 1934         }
 1935 
 1936         /*
 1937          * Clear interrupts
 1938          */
 1939 
 1940         SELECT_GUS_REG(iot, ioh2, GUSREG_DMA_CONTROL);
 1941         bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0x00);
 1942         SELECT_GUS_REG(iot, ioh2, GUSREG_TIMER_CONTROL);
 1943         bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0x00);
 1944         SELECT_GUS_REG(iot, ioh2, GUSREG_SAMPLE_CONTROL);
 1945         bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0x00);
 1946 
 1947         gus_set_voices(sc, voices);
 1948 
 1949         bus_space_read_1(iot, ioh1, GUS_IRQ_STATUS);
 1950         SELECT_GUS_REG(iot, ioh2, GUSREG_DMA_CONTROL);
 1951         bus_space_read_1(iot, ioh2, GUS_DATA_HIGH);
 1952         SELECT_GUS_REG(iot, ioh2, GUSREG_SAMPLE_CONTROL);
 1953         bus_space_read_1(iot, ioh2, GUS_DATA_HIGH);
 1954         SELECT_GUS_REG(iot, ioh2, GUSREG_IRQ_STATUS);
 1955         bus_space_read_1(iot, ioh2, GUS_DATA_HIGH);
 1956 
 1957         /*
 1958          * Reset voice specific information
 1959          */
 1960 
 1961         for(i = 0; i < voices; i++) {
 1962                 bus_space_write_1(iot, ioh2, GUS_VOICE_SELECT, (unsigned char) i);
 1963 
 1964                 SELECT_GUS_REG(iot, ioh2, GUSREG_VOICE_CNTL);
 1965 
 1966                 sc->sc_voc[i].voccntl = GUSMASK_VOICE_STOPPED |
 1967                         GUSMASK_STOP_VOICE;
 1968 
 1969                 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[i].voccntl);
 1970 
 1971                 sc->sc_voc[i].volcntl = GUSMASK_VOLUME_STOPPED |
 1972                                 GUSMASK_STOP_VOLUME;
 1973 
 1974                 SELECT_GUS_REG(iot, ioh2, GUSREG_VOLUME_CONTROL);
 1975                 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[i].volcntl);
 1976 
 1977                 delay(100);
 1978 
 1979                 gus_set_samprate(sc, i, 8000);
 1980                 SELECT_GUS_REG(iot, ioh2, GUSREG_START_ADDR_HIGH);
 1981                 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x0000);
 1982                 SELECT_GUS_REG(iot, ioh2, GUSREG_START_ADDR_LOW);
 1983                 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x0000);
 1984                 SELECT_GUS_REG(iot, ioh2, GUSREG_END_ADDR_HIGH);
 1985                 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x0000);
 1986                 SELECT_GUS_REG(iot, ioh2, GUSREG_END_ADDR_LOW);
 1987                 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x0000);
 1988                 SELECT_GUS_REG(iot, ioh2, GUSREG_VOLUME_RATE);
 1989                 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0x01);
 1990                 SELECT_GUS_REG(iot, ioh2, GUSREG_START_VOLUME);
 1991                 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0x10);
 1992                 SELECT_GUS_REG(iot, ioh2, GUSREG_END_VOLUME);
 1993                 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0xe0);
 1994                 SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_VOLUME);
 1995                 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x0000);
 1996 
 1997                 SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_ADDR_HIGH);
 1998                 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x0000);
 1999                 SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_ADDR_LOW);
 2000                 bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x0000);
 2001                 SELECT_GUS_REG(iot, ioh2, GUSREG_PAN_POS);
 2002                 bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0x07);
 2003         }
 2004 
 2005         /*
 2006          * Clear out any pending IRQs
 2007          */
 2008 
 2009         bus_space_read_1(iot, ioh1, GUS_IRQ_STATUS);
 2010         SELECT_GUS_REG(iot, ioh2, GUSREG_DMA_CONTROL);
 2011         bus_space_read_1(iot, ioh2, GUS_DATA_HIGH);
 2012         SELECT_GUS_REG(iot, ioh2, GUSREG_SAMPLE_CONTROL);
 2013         bus_space_read_1(iot, ioh2, GUS_DATA_HIGH);
 2014         SELECT_GUS_REG(iot, ioh2, GUSREG_IRQ_STATUS);
 2015         bus_space_read_1(iot, ioh2, GUS_DATA_HIGH);
 2016 
 2017         SELECT_GUS_REG(iot, ioh2, GUSREG_RESET);
 2018         bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, GUSMASK_MASTER_RESET | GUSMASK_DAC_ENABLE |
 2019                 GUSMASK_IRQ_ENABLE);
 2020 
 2021         mtx_leave(&audio_lock);
 2022 }
 2023 
 2024 
 2025 int
 2026 gus_init_cs4231(struct gus_softc *sc)
 2027 {
 2028         bus_space_tag_t iot = sc->sc_iot;
 2029         bus_space_handle_t ioh1 = sc->sc_ioh1;
 2030         int port = sc->sc_iobase;
 2031         u_char ctrl;
 2032 
 2033         ctrl = (port & 0xf0) >> 4;      /* set port address middle nibble */
 2034         /*
 2035          * The codec is a bit weird--swapped dma channels.
 2036          */
 2037         ctrl |= GUS_MAX_CODEC_ENABLE;
 2038         if (sc->sc_drq >= 4)
 2039                 ctrl |= GUS_MAX_RECCHAN16;
 2040         if (sc->sc_recdrq >= 4)
 2041                 ctrl |= GUS_MAX_PLAYCHAN16;
 2042 
 2043         bus_space_write_1(iot, ioh1, GUS_MAX_CTRL, ctrl);
 2044 
 2045         sc->sc_codec.sc_iot = sc->sc_iot;
 2046         sc->sc_codec.sc_iobase = port+GUS_MAX_CODEC_BASE;
 2047 
 2048         if (ad1848_mapprobe(&sc->sc_codec, sc->sc_codec.sc_iobase) == 0) {
 2049                 sc->sc_flags &= ~GUS_CODEC_INSTALLED;
 2050                 return (0);
 2051         } else {
 2052                 struct ad1848_volume vol = {AUDIO_MAX_GAIN, AUDIO_MAX_GAIN};
 2053                 sc->sc_flags |= GUS_CODEC_INSTALLED;
 2054                 sc->sc_codec.parent = sc;
 2055                 sc->sc_codec.sc_drq = sc->sc_recdrq;
 2056                 sc->sc_codec.sc_recdrq = sc->sc_drq;
 2057                 /* enable line in and mic in the GUS mixer; the codec chip
 2058                    will do the real mixing for them. */
 2059                 sc->sc_mixcontrol &= ~GUSMASK_LINE_IN; /* 0 enables. */
 2060                 sc->sc_mixcontrol |= GUSMASK_MIC_IN; /* 1 enables. */
 2061                 bus_space_write_1(iot, ioh1, GUS_MIX_CONTROL, sc->sc_mixcontrol);
 2062 
 2063                 ad1848_attach(&sc->sc_codec);
 2064                 /* turn on pre-MUX microphone gain. */
 2065                 ad1848_set_mic_gain(&sc->sc_codec, &vol);
 2066 
 2067                 return (1);
 2068         }
 2069 }
 2070 
 2071 /*
 2072  * stubs (XXX)
 2073  */
 2074 
 2075 int
 2076 gus_set_in_gain(caddr_t addr, u_int gain,  u_char balance)
 2077 {
 2078         DPRINTF(("gus_set_in_gain called\n"));
 2079         return 0;
 2080 }
 2081 
 2082 int
 2083 gus_get_in_gain(caddr_t addr)
 2084 {
 2085         DPRINTF(("gus_get_in_gain called\n"));
 2086         return 0;
 2087 }
 2088 
 2089 int
 2090 gusmax_dma_input(void *addr, void *buf, int size, void (*callback)(void *),
 2091     void *arg)
 2092 {
 2093         struct ad1848_softc *sc = addr;
 2094         return gus_dma_input(sc->parent, buf, size, callback, arg);
 2095 }
 2096 
 2097 /*
 2098  * Start sampling the input source into the requested DMA buffer.
 2099  * Called at splaudio(), either from top-half or from interrupt handler.
 2100  */
 2101 int
 2102 gus_dma_input(void *addr, void *buf, int size, void (*callback)(void *),
 2103     void *arg)
 2104 {
 2105         struct gus_softc *sc = addr;
 2106         bus_space_tag_t iot = sc->sc_iot;
 2107         bus_space_handle_t ioh2 = sc->sc_ioh2;
 2108         u_char dmac;
 2109         DMAPRINTF(("gus_dma_input called\n"));
 2110 
 2111         /*
 2112          * Sample SIZE bytes of data from the card, into buffer at BUF.
 2113          */
 2114         if (sc->sc_precision == 16) {
 2115             return EINVAL;              /* XXX */
 2116         }
 2117 
 2118         /* set DMA modes */
 2119         dmac = GUSMASK_SAMPLE_IRQ|GUSMASK_SAMPLE_START;
 2120         if (sc->sc_recdrq >= 4)
 2121                 dmac |= GUSMASK_SAMPLE_DATA16;
 2122         if (sc->sc_encoding == AUDIO_ENCODING_ULAW ||
 2123             sc->sc_encoding == AUDIO_ENCODING_ALAW ||
 2124             sc->sc_encoding == AUDIO_ENCODING_ULINEAR_LE ||
 2125             sc->sc_encoding == AUDIO_ENCODING_ULINEAR_BE)
 2126             dmac |= GUSMASK_SAMPLE_INVBIT;
 2127         if (sc->sc_channels == 2)
 2128             dmac |= GUSMASK_SAMPLE_STEREO;
 2129         isa_dmastart(sc->sc_dev.dv_parent, sc->sc_recdrq, buf, size,
 2130             NULL, DMAMODE_READ, BUS_DMA_NOWAIT);
 2131 
 2132         DMAPRINTF(("gus_dma_input isadma_started\n"));
 2133         sc->sc_flags |= GUS_DMAIN_ACTIVE;
 2134         sc->sc_dmainintr = callback;
 2135         sc->sc_inarg = arg;
 2136         sc->sc_dmaincnt = size;
 2137         sc->sc_dmainaddr = buf;
 2138 
 2139         SELECT_GUS_REG(iot, ioh2, GUSREG_SAMPLE_CONTROL);
 2140         bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, dmac);      /* Go! */
 2141 
 2142 
 2143         DMAPRINTF(("gus_dma_input returning\n"));
 2144         return 0;
 2145 }
 2146 
 2147 int
 2148 gus_dmain_intr(struct gus_softc *sc)
 2149 {
 2150         void (*callback)(void *);
 2151         void *arg;
 2152 
 2153         DMAPRINTF(("gus_dmain_intr called\n"));
 2154         if (sc->sc_dmainintr) {
 2155             isa_dmadone(sc->sc_dev.dv_parent, sc->sc_recdrq);
 2156             callback = sc->sc_dmainintr;
 2157             arg = sc->sc_inarg;
 2158 
 2159             sc->sc_dmainaddr = 0;
 2160             sc->sc_dmaincnt = 0;
 2161             sc->sc_dmainintr = 0;
 2162             sc->sc_inarg = 0;
 2163 
 2164             sc->sc_flags &= ~GUS_DMAIN_ACTIVE;
 2165             DMAPRINTF(("calling dmain_intr callback %p(%p)\n", callback, arg));
 2166             (*callback)(arg);
 2167             return 1;
 2168         } else {
 2169             DMAPRINTF(("gus_dmain_intr false?\n"));
 2170             return 0;                   /* XXX ??? */
 2171         }
 2172 }
 2173 
 2174 int
 2175 gusmax_halt_out_dma(void *addr)
 2176 {
 2177         struct ad1848_softc *sc = addr;
 2178         return gus_halt_out_dma(sc->parent);
 2179 }
 2180 
 2181 
 2182 int
 2183 gusmax_halt_in_dma(void *addr)
 2184 {
 2185         struct ad1848_softc *sc = addr;
 2186         return gus_halt_in_dma(sc->parent);
 2187 }
 2188 
 2189 /*
 2190  * Stop any DMA output.  Called at splaudio().
 2191  */
 2192 int
 2193 gus_halt_out_dma(void *addr)
 2194 {
 2195         struct gus_softc *sc = addr;
 2196         bus_space_tag_t iot = sc->sc_iot;
 2197         bus_space_handle_t ioh2 = sc->sc_ioh2;
 2198 
 2199         mtx_enter(&audio_lock);
 2200         DMAPRINTF(("gus_halt_out_dma called\n"));
 2201         /*
 2202          * Make sure the GUS _isn't_ setup for DMA
 2203          */
 2204 
 2205         SELECT_GUS_REG(iot, ioh2, GUSREG_DMA_CONTROL);
 2206         bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0);
 2207 
 2208         timeout_del(&sc->sc_dma_tmo);
 2209         isa_dmaabort(sc->sc_dev.dv_parent, sc->sc_drq);
 2210         sc->sc_flags &= ~(GUS_DMAOUT_ACTIVE|GUS_LOCKED);
 2211         sc->sc_dmaoutintr = 0;
 2212         sc->sc_outarg = 0;
 2213         sc->sc_dmaoutaddr = 0;
 2214         sc->sc_dmaoutcnt = 0;
 2215         sc->sc_dmabuf = 0;
 2216         sc->sc_bufcnt = 0;
 2217         sc->sc_playbuf = -1;
 2218         /* also stop playing */
 2219         gus_stop_voice(sc, GUS_VOICE_LEFT, 1);
 2220         gus_stop_voice(sc, GUS_VOICE_RIGHT, 0);
 2221         mtx_leave(&audio_lock);
 2222         return 0;
 2223 }
 2224 
 2225 /*
 2226  * Stop any DMA output.  Called at splaudio().
 2227  */
 2228 int
 2229 gus_halt_in_dma(void *addr)
 2230 {
 2231         struct gus_softc *sc = addr;
 2232         bus_space_tag_t iot = sc->sc_iot;
 2233         bus_space_handle_t ioh2 = sc->sc_ioh2;
 2234 
 2235         mtx_enter(&audio_lock);
 2236         DMAPRINTF(("gus_halt_in_dma called\n"));
 2237 
 2238         /*
 2239          * Make sure the GUS _isn't_ setup for DMA
 2240          */
 2241 
 2242         SELECT_GUS_REG(iot, ioh2, GUSREG_SAMPLE_CONTROL);
 2243         bus_space_write_1(iot, ioh2, GUS_DATA_HIGH,
 2244              bus_space_read_1(iot, ioh2, GUS_DATA_HIGH) & ~(GUSMASK_SAMPLE_START|GUSMASK_SAMPLE_IRQ));
 2245 
 2246         isa_dmaabort(sc->sc_dev.dv_parent, sc->sc_recdrq);
 2247         sc->sc_flags &= ~GUS_DMAIN_ACTIVE;
 2248         sc->sc_dmainintr = 0;
 2249         sc->sc_inarg = 0;
 2250         sc->sc_dmainaddr = 0;
 2251         sc->sc_dmaincnt = 0;
 2252         mtx_leave(&audio_lock);
 2253         return 0;
 2254 }
 2255 
 2256 
 2257 ad1848_devmap_t gusmapping[] = {
 2258   {GUSMAX_DAC_LVL, AD1848_KIND_LVL, AD1848_AUX1_CHANNEL},
 2259   {GUSMAX_LINE_IN_LVL, AD1848_KIND_LVL, AD1848_LINE_CHANNEL},
 2260   {GUSMAX_MONO_LVL, AD1848_KIND_LVL, AD1848_MONO_CHANNEL},
 2261   {GUSMAX_CD_LVL, AD1848_KIND_LVL, AD1848_AUX2_CHANNEL},
 2262   {GUSMAX_MONITOR_LVL, AD1848_KIND_LVL, AD1848_MONITOR_CHANNEL},
 2263   {GUSMAX_OUT_LVL, AD1848_KIND_LVL, AD1848_DAC_CHANNEL},
 2264   {GUSMAX_DAC_MUTE, AD1848_KIND_MUTE, AD1848_AUX1_CHANNEL},
 2265   {GUSMAX_LINE_IN_MUTE, AD1848_KIND_MUTE, AD1848_LINE_CHANNEL},
 2266   {GUSMAX_MONO_MUTE, AD1848_KIND_MUTE, AD1848_MONO_CHANNEL},
 2267   {GUSMAX_CD_MUTE, AD1848_KIND_MUTE, AD1848_AUX2_CHANNEL},
 2268   {GUSMAX_MONITOR_MUTE, AD1848_KIND_MUTE, AD1848_MONITOR_CHANNEL},
 2269   {GUSMAX_REC_LVL, AD1848_KIND_RECORDGAIN, -1},
 2270   {GUSMAX_RECORD_SOURCE, AD1848_KIND_RECORDSOURCE, -1}
 2271 };
 2272 
 2273 int nummap = sizeof(gusmapping) / sizeof(gusmapping[0]);
 2274 
 2275 int
 2276 gusmax_mixer_get_port(void *addr, mixer_ctrl_t *cp)
 2277 {
 2278         struct ad1848_softc *ac = addr;
 2279         struct gus_softc *sc = ac->parent;
 2280         struct ad1848_volume vol;
 2281         int error = ad1848_mixer_get_port(ac, gusmapping, nummap, cp);
 2282 
 2283         if (error != ENXIO)
 2284           return (error);
 2285 
 2286         error = EINVAL;
 2287 
 2288         switch (cp->dev) {
 2289         case GUSMAX_SPEAKER_LVL:        /* fake speaker for mute naming */
 2290                 if (cp->type == AUDIO_MIXER_VALUE) {
 2291                         if (sc->sc_mixcontrol & GUSMASK_LINE_OUT)
 2292                                 vol.left = vol.right = AUDIO_MAX_GAIN;
 2293                         else
 2294                                 vol.left = vol.right = AUDIO_MIN_GAIN;
 2295                         error = 0;
 2296                         ad1848_from_vol(cp, &vol);
 2297                 }
 2298                 break;
 2299 
 2300         case GUSMAX_SPEAKER_MUTE:
 2301                 if (cp->type == AUDIO_MIXER_ENUM) {
 2302                         cp->un.ord = sc->sc_mixcontrol & GUSMASK_LINE_OUT ? 1 : 0;
 2303                         error = 0;
 2304                 }
 2305                 break;
 2306         default:
 2307                 error = ENXIO;
 2308                 break;
 2309         }
 2310 
 2311         return(error);
 2312 }
 2313 
 2314 int
 2315 gus_mixer_get_port(void *addr, mixer_ctrl_t *cp)
 2316 {
 2317         struct gus_softc *sc = addr;
 2318         struct ics2101_softc *ic = &sc->sc_mixer;
 2319         struct ad1848_volume vol;
 2320         int error = EINVAL;
 2321 
 2322         DPRINTF(("gus_mixer_get_port: dev=%d type=%d\n", cp->dev, cp->type));
 2323 
 2324         if (!HAS_MIXER(sc) && cp->dev > GUSICS_MASTER_MUTE)
 2325                 return ENXIO;
 2326 
 2327         switch (cp->dev) {
 2328 
 2329         case GUSICS_MIC_IN_MUTE:        /* Microphone */
 2330                 if (cp->type == AUDIO_MIXER_ENUM) {
 2331                         if (HAS_MIXER(sc))
 2332                                 cp->un.ord = ic->sc_mute[GUSMIX_CHAN_MIC][ICSMIX_LEFT];
 2333                         else
 2334                                 cp->un.ord =
 2335                                     sc->sc_mixcontrol & GUSMASK_MIC_IN ? 0 : 1;
 2336                         error = 0;
 2337                 }
 2338                 break;
 2339 
 2340         case GUSICS_LINE_IN_MUTE:
 2341                 if (cp->type == AUDIO_MIXER_ENUM) {
 2342                         if (HAS_MIXER(sc))
 2343                                 cp->un.ord = ic->sc_mute[GUSMIX_CHAN_LINE][ICSMIX_LEFT];
 2344                         else
 2345                                 cp->un.ord =
 2346                                     sc->sc_mixcontrol & GUSMASK_LINE_IN ? 1 : 0;
 2347                         error = 0;
 2348                 }
 2349                 break;
 2350 
 2351         case GUSICS_MASTER_MUTE:
 2352                 if (cp->type == AUDIO_MIXER_ENUM) {
 2353                         if (HAS_MIXER(sc))
 2354                                 cp->un.ord = ic->sc_mute[GUSMIX_CHAN_MASTER][ICSMIX_LEFT];
 2355                         else
 2356                                 cp->un.ord =
 2357                                     sc->sc_mixcontrol & GUSMASK_LINE_OUT ? 1 : 0;
 2358                         error = 0;
 2359                 }
 2360                 break;
 2361 
 2362         case GUSICS_DAC_MUTE:
 2363                 if (cp->type == AUDIO_MIXER_ENUM) {
 2364                         cp->un.ord = ic->sc_mute[GUSMIX_CHAN_DAC][ICSMIX_LEFT];
 2365                         error = 0;
 2366                 }
 2367                 break;
 2368 
 2369         case GUSICS_CD_MUTE:
 2370                 if (cp->type == AUDIO_MIXER_ENUM) {
 2371                         cp->un.ord = ic->sc_mute[GUSMIX_CHAN_CD][ICSMIX_LEFT];
 2372                         error = 0;
 2373                 }
 2374                 break;
 2375 
 2376         case GUSICS_MASTER_LVL:
 2377                 if (cp->type == AUDIO_MIXER_VALUE) {
 2378                         vol.left = ic->sc_setting[GUSMIX_CHAN_MASTER][ICSMIX_LEFT];
 2379                         vol.right = ic->sc_setting[GUSMIX_CHAN_MASTER][ICSMIX_RIGHT];
 2380                         if (ad1848_from_vol(cp, &vol))
 2381                                 error = 0;
 2382                 }
 2383                 break;
 2384 
 2385         case GUSICS_MIC_IN_LVL: /* Microphone */
 2386                 if (cp->type == AUDIO_MIXER_VALUE) {
 2387                         vol.left = ic->sc_setting[GUSMIX_CHAN_MIC][ICSMIX_LEFT];
 2388                         vol.right = ic->sc_setting[GUSMIX_CHAN_MIC][ICSMIX_RIGHT];
 2389                         if (ad1848_from_vol(cp, &vol))
 2390                                 error = 0;
 2391                 }
 2392                 break;
 2393 
 2394         case GUSICS_LINE_IN_LVL:        /* line in */
 2395                 if (cp->type == AUDIO_MIXER_VALUE) {
 2396                         vol.left = ic->sc_setting[GUSMIX_CHAN_LINE][ICSMIX_LEFT];
 2397                         vol.right = ic->sc_setting[GUSMIX_CHAN_LINE][ICSMIX_RIGHT];
 2398                         if (ad1848_from_vol(cp, &vol))
 2399                                 error = 0;
 2400                 }
 2401                 break;
 2402 
 2403 
 2404         case GUSICS_CD_LVL:
 2405                 if (cp->type == AUDIO_MIXER_VALUE) {
 2406                         vol.left = ic->sc_setting[GUSMIX_CHAN_CD][ICSMIX_LEFT];
 2407                         vol.right = ic->sc_setting[GUSMIX_CHAN_CD][ICSMIX_RIGHT];
 2408                         if (ad1848_from_vol(cp, &vol))
 2409                                 error = 0;
 2410                 }
 2411                 break;
 2412 
 2413         case GUSICS_DAC_LVL:            /* dac out */
 2414                 if (cp->type == AUDIO_MIXER_VALUE) {
 2415                         vol.left = ic->sc_setting[GUSMIX_CHAN_DAC][ICSMIX_LEFT];
 2416                         vol.right = ic->sc_setting[GUSMIX_CHAN_DAC][ICSMIX_RIGHT];
 2417                         if (ad1848_from_vol(cp, &vol))
 2418                                 error = 0;
 2419                 }
 2420                 break;
 2421 
 2422 
 2423         case GUSICS_RECORD_SOURCE:
 2424                 if (cp->type == AUDIO_MIXER_ENUM) {
 2425                         /* Can't set anything else useful, sigh. */
 2426                          cp->un.ord = 0;
 2427                 }
 2428                 break;
 2429 
 2430         default:
 2431                 return ENXIO;
 2432             /*NOTREACHED*/
 2433         }
 2434         return error;
 2435 }
 2436 
 2437 void
 2438 gusics_master_mute(struct ics2101_softc *ic, int mute)
 2439 {
 2440         ics2101_mix_mute(ic, GUSMIX_CHAN_MASTER, ICSMIX_LEFT, mute);
 2441         ics2101_mix_mute(ic, GUSMIX_CHAN_MASTER, ICSMIX_RIGHT, mute);
 2442 }
 2443 
 2444 void
 2445 gusics_mic_mute(struct ics2101_softc *ic, int mute)
 2446 {
 2447         ics2101_mix_mute(ic, GUSMIX_CHAN_MIC, ICSMIX_LEFT, mute);
 2448         ics2101_mix_mute(ic, GUSMIX_CHAN_MIC, ICSMIX_RIGHT, mute);
 2449 }
 2450 
 2451 void
 2452 gusics_linein_mute(struct ics2101_softc *ic, int mute)
 2453 {
 2454         ics2101_mix_mute(ic, GUSMIX_CHAN_LINE, ICSMIX_LEFT, mute);
 2455         ics2101_mix_mute(ic, GUSMIX_CHAN_LINE, ICSMIX_RIGHT, mute);
 2456 }
 2457 
 2458 void
 2459 gusics_cd_mute(struct ics2101_softc *ic, int mute)
 2460 {
 2461         ics2101_mix_mute(ic, GUSMIX_CHAN_CD, ICSMIX_LEFT, mute);
 2462         ics2101_mix_mute(ic, GUSMIX_CHAN_CD, ICSMIX_RIGHT, mute);
 2463 }
 2464 
 2465 void
 2466 gusics_dac_mute(struct ics2101_softc *ic, int mute)
 2467 {
 2468         ics2101_mix_mute(ic, GUSMIX_CHAN_DAC, ICSMIX_LEFT, mute);
 2469         ics2101_mix_mute(ic, GUSMIX_CHAN_DAC, ICSMIX_RIGHT, mute);
 2470 }
 2471 
 2472 int
 2473 gusmax_mixer_set_port(void *addr, mixer_ctrl_t *cp)
 2474 {
 2475         struct ad1848_softc *ac = addr;
 2476         struct gus_softc *sc = ac->parent;
 2477         struct ad1848_volume vol;
 2478         int error = ad1848_mixer_set_port(ac, gusmapping, nummap, cp);
 2479 
 2480         if (error != ENXIO)
 2481           return (error);
 2482 
 2483         DPRINTF(("gusmax_mixer_set_port: dev=%d type=%d\n", cp->dev, cp->type));
 2484 
 2485         switch (cp->dev) {
 2486         case GUSMAX_SPEAKER_LVL:
 2487                 if (cp->type == AUDIO_MIXER_VALUE &&
 2488                     cp->un.value.num_channels == 1) {
 2489                         if (ad1848_to_vol(cp, &vol)) {
 2490                                 gus_speaker_ctl(sc, vol.left > AUDIO_MIN_GAIN ?
 2491                                                 SPKR_ON : SPKR_OFF);
 2492                                 error = 0;
 2493                         }
 2494                 }
 2495                 break;
 2496 
 2497         case GUSMAX_SPEAKER_MUTE:
 2498                 if (cp->type == AUDIO_MIXER_ENUM) {
 2499                         gus_speaker_ctl(sc, cp->un.ord ? SPKR_OFF : SPKR_ON);
 2500                         error = 0;
 2501                 }
 2502                 break;
 2503 
 2504         default:
 2505                 return ENXIO;
 2506             /*NOTREACHED*/
 2507     }
 2508     return error;
 2509 }
 2510 
 2511 int
 2512 gus_mixer_set_port(void *addr, mixer_ctrl_t *cp)
 2513 {
 2514         struct gus_softc *sc = addr;
 2515         struct ics2101_softc *ic = &sc->sc_mixer;
 2516         struct ad1848_volume vol;
 2517         int error = EINVAL;
 2518 
 2519         DPRINTF(("gus_mixer_set_port: dev=%d type=%d\n", cp->dev, cp->type));
 2520 
 2521         if (!HAS_MIXER(sc) && cp->dev > GUSICS_MASTER_MUTE)
 2522                 return ENXIO;
 2523 
 2524         switch (cp->dev) {
 2525 
 2526         case GUSICS_MIC_IN_MUTE:        /* Microphone */
 2527                 if (cp->type == AUDIO_MIXER_ENUM) {
 2528                         DPRINTF(("mic mute %d\n", cp->un.ord));
 2529                         if (HAS_MIXER(sc)) {
 2530                                 gusics_mic_mute(ic, cp->un.ord);
 2531                         }
 2532                         gus_mic_ctl(sc, cp->un.ord ? SPKR_OFF : SPKR_ON);
 2533                         error = 0;
 2534                 }
 2535                 break;
 2536 
 2537         case GUSICS_LINE_IN_MUTE:
 2538                 if (cp->type == AUDIO_MIXER_ENUM) {
 2539                         DPRINTF(("linein mute %d\n", cp->un.ord));
 2540                         if (HAS_MIXER(sc)) {
 2541                                 gusics_linein_mute(ic, cp->un.ord);
 2542                         }
 2543                         gus_linein_ctl(sc, cp->un.ord ? SPKR_OFF : SPKR_ON);
 2544                         error = 0;
 2545                 }
 2546                 break;
 2547 
 2548         case GUSICS_MASTER_MUTE:
 2549                 if (cp->type == AUDIO_MIXER_ENUM) {
 2550                         DPRINTF(("master mute %d\n", cp->un.ord));
 2551                         if (HAS_MIXER(sc)) {
 2552                                 gusics_master_mute(ic, cp->un.ord);
 2553                         }
 2554                         gus_speaker_ctl(sc, cp->un.ord ? SPKR_OFF : SPKR_ON);
 2555                         error = 0;
 2556                 }
 2557                 break;
 2558 
 2559         case GUSICS_DAC_MUTE:
 2560                 if (cp->type == AUDIO_MIXER_ENUM) {
 2561                         gusics_dac_mute(ic, cp->un.ord);
 2562                         error = 0;
 2563                 }
 2564                 break;
 2565 
 2566         case GUSICS_CD_MUTE:
 2567                 if (cp->type == AUDIO_MIXER_ENUM) {
 2568                         gusics_cd_mute(ic, cp->un.ord);
 2569                         error = 0;
 2570                 }
 2571                 break;
 2572 
 2573         case GUSICS_MASTER_LVL:
 2574                 if (cp->type == AUDIO_MIXER_VALUE) {
 2575                         if (ad1848_to_vol(cp, &vol)) {
 2576                                 ics2101_mix_attenuate(ic,
 2577                                                       GUSMIX_CHAN_MASTER,
 2578                                                       ICSMIX_LEFT,
 2579                                                       vol.left);
 2580                                 ics2101_mix_attenuate(ic,
 2581                                                       GUSMIX_CHAN_MASTER,
 2582                                                       ICSMIX_RIGHT,
 2583                                                       vol.right);
 2584                                 error = 0;
 2585                         }
 2586                 }
 2587                 break;
 2588 
 2589         case GUSICS_MIC_IN_LVL: /* Microphone */
 2590                 if (cp->type == AUDIO_MIXER_VALUE) {
 2591                         if (ad1848_to_vol(cp, &vol)) {
 2592                                 ics2101_mix_attenuate(ic,
 2593                                                       GUSMIX_CHAN_MIC,
 2594                                                       ICSMIX_LEFT,
 2595                                                       vol.left);
 2596                                 ics2101_mix_attenuate(ic,
 2597                                                       GUSMIX_CHAN_MIC,
 2598                                                       ICSMIX_RIGHT,
 2599                                                       vol.right);
 2600                                 error = 0;
 2601                         }
 2602                 }
 2603                 break;
 2604 
 2605         case GUSICS_LINE_IN_LVL:        /* line in */
 2606                 if (cp->type == AUDIO_MIXER_VALUE) {
 2607                         if (ad1848_to_vol(cp, &vol)) {
 2608                                 ics2101_mix_attenuate(ic,
 2609                                                       GUSMIX_CHAN_LINE,
 2610                                                       ICSMIX_LEFT,
 2611                                                       vol.left);
 2612                                 ics2101_mix_attenuate(ic,
 2613                                                       GUSMIX_CHAN_LINE,
 2614                                                       ICSMIX_RIGHT,
 2615                                                       vol.right);
 2616                                 error = 0;
 2617                         }
 2618                 }
 2619                 break;
 2620 
 2621 
 2622         case GUSICS_CD_LVL:
 2623                 if (cp->type == AUDIO_MIXER_VALUE) {
 2624                         if (ad1848_to_vol(cp, &vol)) {
 2625                                 ics2101_mix_attenuate(ic,
 2626                                                       GUSMIX_CHAN_CD,
 2627                                                       ICSMIX_LEFT,
 2628                                                       vol.left);
 2629                                 ics2101_mix_attenuate(ic,
 2630                                                       GUSMIX_CHAN_CD,
 2631                                                       ICSMIX_RIGHT,
 2632                                                       vol.right);
 2633                                 error = 0;
 2634                         }
 2635                 }
 2636                 break;
 2637 
 2638         case GUSICS_DAC_LVL:            /* dac out */
 2639                 if (cp->type == AUDIO_MIXER_VALUE) {
 2640                         if (ad1848_to_vol(cp, &vol)) {
 2641                                 ics2101_mix_attenuate(ic,
 2642                                                       GUSMIX_CHAN_DAC,
 2643                                                       ICSMIX_LEFT,
 2644                                                       vol.left);
 2645                                 ics2101_mix_attenuate(ic,
 2646                                                       GUSMIX_CHAN_DAC,
 2647                                                       ICSMIX_RIGHT,
 2648                                                       vol.right);
 2649                                 error = 0;
 2650                         }
 2651                 }
 2652                 break;
 2653 
 2654 
 2655         case GUSICS_RECORD_SOURCE:
 2656                 if (cp->type == AUDIO_MIXER_ENUM && cp->un.ord == 0) {
 2657                         /* Can't set anything else useful, sigh. */
 2658                         error = 0;
 2659                 }
 2660                 break;
 2661 
 2662         default:
 2663                 return ENXIO;
 2664             /*NOTREACHED*/
 2665         }
 2666         return error;
 2667 }
 2668 
 2669 int
 2670 gusmax_mixer_query_devinfo(void *addr, mixer_devinfo_t *dip)
 2671 {
 2672         DPRINTF(("gusmax_query_devinfo: index=%d\n", dip->index));
 2673 
 2674         switch(dip->index) {
 2675 #if 0
 2676     case GUSMAX_MIC_IN_LVL:     /* Microphone */
 2677         dip->type = AUDIO_MIXER_VALUE;
 2678         dip->mixer_class = GUSMAX_INPUT_CLASS;
 2679         dip->prev = AUDIO_MIXER_LAST;
 2680         dip->next = GUSMAX_MIC_IN_MUTE;
 2681         strlcpy(dip->label.name, AudioNmicrophone, sizeof dip->label.name);
 2682         dip->un.v.num_channels = 2;
 2683         strlcpy(dip->un.v.units.name, AudioNvolume,
 2684             sizeof dip->un.v.units.name);
 2685         break;
 2686 #endif
 2687 
 2688     case GUSMAX_MONO_LVL:       /* mono/microphone mixer */
 2689         dip->type = AUDIO_MIXER_VALUE;
 2690         dip->mixer_class = GUSMAX_INPUT_CLASS;
 2691         dip->prev = AUDIO_MIXER_LAST;
 2692         dip->next = GUSMAX_MONO_MUTE;
 2693         strlcpy(dip->label.name, AudioNmicrophone, sizeof dip->label.name);
 2694         dip->un.v.num_channels = 1;
 2695         strlcpy(dip->un.v.units.name, AudioNvolume,
 2696             sizeof dip->un.v.units.name);
 2697         break;
 2698 
 2699     case GUSMAX_DAC_LVL:                /*  dacout */
 2700         dip->type = AUDIO_MIXER_VALUE;
 2701         dip->mixer_class = GUSMAX_INPUT_CLASS;
 2702         dip->prev = AUDIO_MIXER_LAST;
 2703         dip->next = GUSMAX_DAC_MUTE;
 2704         strlcpy(dip->label.name, AudioNdac, sizeof dip->label.name);
 2705         dip->un.v.num_channels = 2;
 2706         strlcpy(dip->un.v.units.name, AudioNvolume,
 2707             sizeof dip->un.v.units.name);
 2708         break;
 2709 
 2710     case GUSMAX_LINE_IN_LVL:    /* line */
 2711         dip->type = AUDIO_MIXER_VALUE;
 2712         dip->mixer_class = GUSMAX_INPUT_CLASS;
 2713         dip->prev = AUDIO_MIXER_LAST;
 2714         dip->next = GUSMAX_LINE_IN_MUTE;
 2715         strlcpy(dip->label.name, AudioNline, sizeof dip->label.name);
 2716         dip->un.v.num_channels = 2;
 2717         strlcpy(dip->un.v.units.name, AudioNvolume,
 2718             sizeof dip->un.v.units.name);
 2719         break;
 2720 
 2721     case GUSMAX_CD_LVL:         /* cd */
 2722         dip->type = AUDIO_MIXER_VALUE;
 2723         dip->mixer_class = GUSMAX_INPUT_CLASS;
 2724         dip->prev = AUDIO_MIXER_LAST;
 2725         dip->next = GUSMAX_CD_MUTE;
 2726         strlcpy(dip->label.name, AudioNcd, sizeof dip->label.name);
 2727         dip->un.v.num_channels = 2;
 2728         strlcpy(dip->un.v.units.name, AudioNvolume,
 2729             sizeof dip->un.v.units.name);
 2730         break;
 2731 
 2732 
 2733     case GUSMAX_MONITOR_LVL:    /* monitor level */
 2734         dip->type = AUDIO_MIXER_VALUE;
 2735         dip->mixer_class = GUSMAX_MONITOR_CLASS;
 2736         dip->next = GUSMAX_MONITOR_MUTE;
 2737         dip->prev = AUDIO_MIXER_LAST;
 2738         strlcpy(dip->label.name, AudioNmonitor, sizeof dip->label.name);
 2739         dip->un.v.num_channels = 1;
 2740         strlcpy(dip->un.v.units.name, AudioNvolume,
 2741             sizeof dip->un.v.units.name);
 2742         break;
 2743 
 2744     case GUSMAX_OUT_LVL:                /* cs4231 output volume: not useful? */
 2745         dip->type = AUDIO_MIXER_VALUE;
 2746         dip->mixer_class = GUSMAX_MONITOR_CLASS;
 2747         dip->prev = dip->next = AUDIO_MIXER_LAST;
 2748         strlcpy(dip->label.name, AudioNoutput, sizeof dip->label.name);
 2749         dip->un.v.num_channels = 2;
 2750         strlcpy(dip->un.v.units.name, AudioNvolume,
 2751             sizeof dip->un.v.units.name);
 2752         break;
 2753 
 2754     case GUSMAX_SPEAKER_LVL:            /* fake speaker volume */
 2755         dip->type = AUDIO_MIXER_VALUE;
 2756         dip->mixer_class = GUSMAX_MONITOR_CLASS;
 2757         dip->prev = AUDIO_MIXER_LAST;
 2758         dip->next = GUSMAX_SPEAKER_MUTE;
 2759         strlcpy(dip->label.name, AudioNmaster, sizeof dip->label.name);
 2760         dip->un.v.num_channels = 2;
 2761         strlcpy(dip->un.v.units.name, AudioNvolume,
 2762             sizeof dip->un.v.units.name);
 2763         break;
 2764 
 2765     case GUSMAX_LINE_IN_MUTE:
 2766         dip->mixer_class = GUSMAX_INPUT_CLASS;
 2767         dip->type = AUDIO_MIXER_ENUM;
 2768         dip->prev = GUSMAX_LINE_IN_LVL;
 2769         dip->next = AUDIO_MIXER_LAST;
 2770         goto mute;
 2771 
 2772     case GUSMAX_DAC_MUTE:
 2773         dip->mixer_class = GUSMAX_INPUT_CLASS;
 2774         dip->type = AUDIO_MIXER_ENUM;
 2775         dip->prev = GUSMAX_DAC_LVL;
 2776         dip->next = AUDIO_MIXER_LAST;
 2777         goto mute;
 2778 
 2779     case GUSMAX_CD_MUTE:
 2780         dip->mixer_class = GUSMAX_INPUT_CLASS;
 2781         dip->type = AUDIO_MIXER_ENUM;
 2782         dip->prev = GUSMAX_CD_LVL;
 2783         dip->next = AUDIO_MIXER_LAST;
 2784         goto mute;
 2785 
 2786     case GUSMAX_MONO_MUTE:
 2787         dip->mixer_class = GUSMAX_INPUT_CLASS;
 2788         dip->type = AUDIO_MIXER_ENUM;
 2789         dip->prev = GUSMAX_MONO_LVL;
 2790         dip->next = AUDIO_MIXER_LAST;
 2791         goto mute;
 2792 
 2793     case GUSMAX_MONITOR_MUTE:
 2794         dip->mixer_class = GUSMAX_OUTPUT_CLASS;
 2795         dip->type = AUDIO_MIXER_ENUM;
 2796         dip->prev = GUSMAX_MONITOR_LVL;
 2797         dip->next = AUDIO_MIXER_LAST;
 2798         goto mute;
 2799 
 2800     case GUSMAX_SPEAKER_MUTE:
 2801         dip->mixer_class = GUSMAX_OUTPUT_CLASS;
 2802         dip->type = AUDIO_MIXER_ENUM;
 2803         dip->prev = GUSMAX_SPEAKER_LVL;
 2804         dip->next = AUDIO_MIXER_LAST;
 2805     mute:
 2806         strlcpy(dip->label.name, AudioNmute, sizeof dip->label.name);
 2807         dip->un.e.num_mem = 2;
 2808         strlcpy(dip->un.e.member[0].label.name, AudioNoff,
 2809             sizeof dip->un.e.member[0].label.name);
 2810         dip->un.e.member[0].ord = 0;
 2811         strlcpy(dip->un.e.member[1].label.name, AudioNon,
 2812             sizeof dip->un.e.member[1].label.name);
 2813         dip->un.e.member[1].ord = 1;
 2814         break;
 2815 
 2816     case GUSMAX_REC_LVL:        /* record level */
 2817         dip->type = AUDIO_MIXER_VALUE;
 2818         dip->mixer_class = GUSMAX_RECORD_CLASS;
 2819         dip->prev = AUDIO_MIXER_LAST;
 2820         dip->next = GUSMAX_RECORD_SOURCE;
 2821         strlcpy(dip->label.name, AudioNrecord, sizeof dip->label.name);
 2822         dip->un.v.num_channels = 2;
 2823         strlcpy(dip->un.v.units.name, AudioNvolume, sizeof dip->un.v.units.name);
 2824         break;
 2825 
 2826     case GUSMAX_RECORD_SOURCE:
 2827         dip->mixer_class = GUSMAX_RECORD_CLASS;
 2828         dip->type = AUDIO_MIXER_ENUM;
 2829         dip->prev = GUSMAX_REC_LVL;
 2830         dip->next = AUDIO_MIXER_LAST;
 2831         strlcpy(dip->label.name, AudioNsource, sizeof dip->label.name);
 2832         dip->un.e.num_mem = 4;
 2833         strlcpy(dip->un.e.member[0].label.name, AudioNoutput,
 2834             sizeof dip->un.e.member[0].label.name);
 2835         dip->un.e.member[0].ord = DAC_IN_PORT;
 2836         strlcpy(dip->un.e.member[1].label.name, AudioNmicrophone,
 2837             sizeof dip->un.e.member[1].label.name);
 2838         dip->un.e.member[1].ord = MIC_IN_PORT;
 2839         strlcpy(dip->un.e.member[2].label.name, AudioNdac,
 2840             sizeof dip->un.e.member[2].label.name);
 2841         dip->un.e.member[2].ord = AUX1_IN_PORT;
 2842         strlcpy(dip->un.e.member[3].label.name, AudioNline,
 2843             sizeof dip->un.e.member[3].label.name);
 2844         dip->un.e.member[3].ord = LINE_IN_PORT;
 2845         break;
 2846 
 2847     case GUSMAX_INPUT_CLASS:                    /* input class descriptor */
 2848         dip->type = AUDIO_MIXER_CLASS;
 2849         dip->mixer_class = GUSMAX_INPUT_CLASS;
 2850         dip->next = dip->prev = AUDIO_MIXER_LAST;
 2851         strlcpy(dip->label.name, AudioCinputs, sizeof dip->label.name);
 2852         break;
 2853 
 2854     case GUSMAX_OUTPUT_CLASS:                   /* output class descriptor */
 2855         dip->type = AUDIO_MIXER_CLASS;
 2856         dip->mixer_class = GUSMAX_OUTPUT_CLASS;
 2857         dip->next = dip->prev = AUDIO_MIXER_LAST;
 2858         strlcpy(dip->label.name, AudioCoutputs, sizeof dip->label.name);
 2859         break;
 2860 
 2861     case GUSMAX_MONITOR_CLASS:                  /* monitor class descriptor */
 2862         dip->type = AUDIO_MIXER_CLASS;
 2863         dip->mixer_class = GUSMAX_MONITOR_CLASS;
 2864         dip->next = dip->prev = AUDIO_MIXER_LAST;
 2865         strlcpy(dip->label.name, AudioCmonitor, sizeof dip->label.name);
 2866         break;
 2867 
 2868     case GUSMAX_RECORD_CLASS:                   /* record source class */
 2869         dip->type = AUDIO_MIXER_CLASS;
 2870         dip->mixer_class = GUSMAX_RECORD_CLASS;
 2871         dip->next = dip->prev = AUDIO_MIXER_LAST;
 2872         strlcpy(dip->label.name, AudioCrecord, sizeof dip->label.name);
 2873         break;
 2874 
 2875     default:
 2876         return ENXIO;
 2877         /*NOTREACHED*/
 2878     }
 2879     DPRINTF(("AUDIO_MIXER_DEVINFO: name=%s\n", dip->label.name));
 2880         return 0;
 2881 }
 2882 
 2883 int
 2884 gus_mixer_query_devinfo(void *addr, mixer_devinfo_t *dip)
 2885 {
 2886         struct gus_softc *sc = addr;
 2887 
 2888         DPRINTF(("gusmax_query_devinfo: index=%d\n", dip->index));
 2889 
 2890         if (!HAS_MIXER(sc) && dip->index > GUSICS_MASTER_MUTE)
 2891                 return ENXIO;
 2892 
 2893         switch(dip->index) {
 2894 
 2895         case GUSICS_MIC_IN_LVL: /* Microphone */
 2896                 dip->type = AUDIO_MIXER_VALUE;
 2897                 dip->mixer_class = GUSICS_INPUT_CLASS;
 2898                 dip->prev = AUDIO_MIXER_LAST;
 2899                 dip->next = GUSICS_MIC_IN_MUTE;
 2900                 strlcpy(dip->label.name, AudioNmicrophone,
 2901                     sizeof dip->label.name);
 2902                 dip->un.v.num_channels = 2;
 2903                 strlcpy(dip->un.v.units.name, AudioNvolume,
 2904                     sizeof dip->un.v.units.name);
 2905                 break;
 2906 
 2907         case GUSICS_LINE_IN_LVL:        /* line */
 2908                 dip->type = AUDIO_MIXER_VALUE;
 2909                 dip->mixer_class = GUSICS_INPUT_CLASS;
 2910                 dip->prev = AUDIO_MIXER_LAST;
 2911                 dip->next = GUSICS_LINE_IN_MUTE;
 2912                 strlcpy(dip->label.name, AudioNline, sizeof dip->label.name);
 2913                 dip->un.v.num_channels = 2;
 2914                 strlcpy(dip->un.v.units.name, AudioNvolume,
 2915                     sizeof dip->un.v.units.name);
 2916                 break;
 2917 
 2918         case GUSICS_CD_LVL:             /* cd */
 2919                 dip->type = AUDIO_MIXER_VALUE;
 2920                 dip->mixer_class = GUSICS_INPUT_CLASS;
 2921                 dip->prev = AUDIO_MIXER_LAST;
 2922                 dip->next = GUSICS_CD_MUTE;
 2923                 strlcpy(dip->label.name, AudioNcd, sizeof dip->label.name);
 2924                 dip->un.v.num_channels = 2;
 2925                 strlcpy(dip->un.v.units.name, AudioNvolume,
 2926                     sizeof dip->un.v.units.name);
 2927                 break;
 2928 
 2929         case GUSICS_DAC_LVL:            /*  dacout */
 2930                 dip->type = AUDIO_MIXER_VALUE;
 2931                 dip->mixer_class = GUSICS_INPUT_CLASS;
 2932                 dip->prev = AUDIO_MIXER_LAST;
 2933                 dip->next = GUSICS_DAC_MUTE;
 2934                 strlcpy(dip->label.name, AudioNdac, sizeof dip->label.name);
 2935                 dip->un.v.num_channels = 2;
 2936                 strlcpy(dip->un.v.units.name, AudioNvolume,
 2937                     sizeof dip->un.v.units.name);
 2938                 break;
 2939 
 2940         case GUSICS_MASTER_LVL:         /*  master output */
 2941                 dip->type = AUDIO_MIXER_VALUE;
 2942                 dip->mixer_class = GUSICS_OUTPUT_CLASS;
 2943                 dip->prev = AUDIO_MIXER_LAST;
 2944                 dip->next = GUSICS_MASTER_MUTE;
 2945                 strlcpy(dip->label.name, AudioNmaster, sizeof dip->label.name);
 2946                 dip->un.v.num_channels = 2;
 2947                 strlcpy(dip->un.v.units.name, AudioNvolume,
 2948                     sizeof dip->un.v.units.name);
 2949                 break;
 2950 
 2951 
 2952         case GUSICS_LINE_IN_MUTE:
 2953                 dip->mixer_class = GUSICS_INPUT_CLASS;
 2954                 dip->type = AUDIO_MIXER_ENUM;
 2955                 dip->prev = GUSICS_LINE_IN_LVL;
 2956                 dip->next = AUDIO_MIXER_LAST;
 2957                 goto mute;
 2958 
 2959         case GUSICS_DAC_MUTE:
 2960                 dip->mixer_class = GUSICS_INPUT_CLASS;
 2961                 dip->type = AUDIO_MIXER_ENUM;
 2962                 dip->prev = GUSICS_DAC_LVL;
 2963                 dip->next = AUDIO_MIXER_LAST;
 2964                 goto mute;
 2965 
 2966         case GUSICS_CD_MUTE:
 2967                 dip->mixer_class = GUSICS_INPUT_CLASS;
 2968                 dip->type = AUDIO_MIXER_ENUM;
 2969                 dip->prev = GUSICS_CD_LVL;
 2970                 dip->next = AUDIO_MIXER_LAST;
 2971                 goto mute;
 2972 
 2973         case GUSICS_MIC_IN_MUTE:
 2974                 dip->mixer_class = GUSICS_INPUT_CLASS;
 2975                 dip->type = AUDIO_MIXER_ENUM;
 2976                 dip->prev = GUSICS_MIC_IN_LVL;
 2977                 dip->next = AUDIO_MIXER_LAST;
 2978                 goto mute;
 2979 
 2980         case GUSICS_MASTER_MUTE:
 2981                 dip->mixer_class = GUSICS_OUTPUT_CLASS;
 2982                 dip->type = AUDIO_MIXER_ENUM;
 2983                 dip->prev = GUSICS_MASTER_LVL;
 2984                 dip->next = AUDIO_MIXER_LAST;
 2985 mute:
 2986                 strlcpy(dip->label.name, AudioNmute, sizeof dip->label.name);
 2987                 dip->un.e.num_mem = 2;
 2988                 strlcpy(dip->un.e.member[0].label.name, AudioNoff,
 2989                     sizeof dip->un.e.member[0].label.name);
 2990                 dip->un.e.member[0].ord = 0;
 2991                 strlcpy(dip->un.e.member[1].label.name, AudioNon,
 2992                     sizeof dip->un.e.member[1].label.name);
 2993                 dip->un.e.member[1].ord = 1;
 2994                 break;
 2995 
 2996         case GUSICS_RECORD_SOURCE:
 2997                 dip->mixer_class = GUSICS_RECORD_CLASS;
 2998                 dip->type = AUDIO_MIXER_ENUM;
 2999                 dip->prev = dip->next = AUDIO_MIXER_LAST;
 3000                 strlcpy(dip->label.name, AudioNsource, sizeof dip->label.name);
 3001                 dip->un.e.num_mem = 1;
 3002                 strlcpy(dip->un.e.member[0].label.name, AudioNoutput,
 3003                     sizeof dip->un.e.member[0].label.name);
 3004                 dip->un.e.member[0].ord = GUSICS_MASTER_LVL;
 3005                 break;
 3006 
 3007         case GUSICS_INPUT_CLASS:
 3008                 dip->type = AUDIO_MIXER_CLASS;
 3009                 dip->mixer_class = GUSICS_INPUT_CLASS;
 3010                 dip->next = dip->prev = AUDIO_MIXER_LAST;
 3011                 strlcpy(dip->label.name, AudioCinputs, sizeof dip->label.name);
 3012                 break;
 3013 
 3014         case GUSICS_OUTPUT_CLASS:
 3015                 dip->type = AUDIO_MIXER_CLASS;
 3016                 dip->mixer_class = GUSICS_OUTPUT_CLASS;
 3017                 dip->next = dip->prev = AUDIO_MIXER_LAST;
 3018                 strlcpy(dip->label.name, AudioCoutputs, sizeof dip->label.name);
 3019                 break;
 3020 
 3021         case GUSICS_RECORD_CLASS:
 3022                 dip->type = AUDIO_MIXER_CLASS;
 3023                 dip->mixer_class = GUSICS_RECORD_CLASS;
 3024                 dip->next = dip->prev = AUDIO_MIXER_LAST;
 3025                 strlcpy(dip->label.name, AudioCrecord, sizeof dip->label.name);
 3026                 break;
 3027 
 3028         default:
 3029                 return ENXIO;
 3030         /*NOTREACHED*/
 3031         }
 3032         DPRINTF(("AUDIO_MIXER_DEVINFO: name=%s\n", dip->label.name));
 3033         return 0;
 3034 }
 3035 
 3036 void *
 3037 gus_malloc(void *addr, int direction, size_t size, int pool, int flags)
 3038 {
 3039         struct gus_softc *sc = addr;
 3040         int drq;
 3041 
 3042         if (direction == AUMODE_PLAY)
 3043                 drq = sc->sc_drq;
 3044         else
 3045                 drq = sc->sc_recdrq;
 3046 
 3047         return isa_malloc(sc->sc_isa, drq, size, pool, flags);
 3048 }
 3049 
 3050 void
 3051 gus_free(void *addr, void *ptr, int pool)
 3052 {
 3053         isa_free(ptr, pool);
 3054 }
 3055 
 3056 size_t
 3057 gus_round(void *addr, int direction, size_t size)
 3058 {
 3059         if (size > MAX_ISADMA)
 3060                 size = MAX_ISADMA;
 3061         return size;
 3062 }
 3063 
 3064 /*
 3065  * Setup the ICS mixer in "transparent" mode: reset everything to a sensible
 3066  * level.  Levels as suggested by GUS SDK code.
 3067  */
 3068 
 3069 void
 3070 gus_init_ics2101(struct gus_softc *sc)
 3071 {
 3072         struct ics2101_softc *ic = &sc->sc_mixer;
 3073         sc->sc_mixer.sc_iot = sc->sc_iot;
 3074         sc->sc_mixer.sc_selio = GUS_MIXER_SELECT;
 3075         sc->sc_mixer.sc_selio_ioh = sc->sc_ioh3;
 3076         sc->sc_mixer.sc_dataio = GUS_MIXER_DATA;
 3077         sc->sc_mixer.sc_dataio_ioh = sc->sc_ioh2;
 3078         sc->sc_mixer.sc_flags = (sc->sc_revision == 5) ? ICS_FLIP : 0;
 3079 
 3080         ics2101_mix_attenuate(ic,
 3081                               GUSMIX_CHAN_MIC,
 3082                               ICSMIX_LEFT,
 3083                               ICSMIX_MIN_ATTN);
 3084         ics2101_mix_attenuate(ic,
 3085                               GUSMIX_CHAN_MIC,
 3086                               ICSMIX_RIGHT,
 3087                               ICSMIX_MIN_ATTN);
 3088         /*
 3089          * Start with microphone muted by the mixer...
 3090          */
 3091         gusics_mic_mute(ic, 1);
 3092 
 3093         /* ... and enabled by the GUS master mix control */
 3094         gus_mic_ctl(sc, SPKR_ON);
 3095 
 3096         ics2101_mix_attenuate(ic,
 3097                               GUSMIX_CHAN_LINE,
 3098                               ICSMIX_LEFT,
 3099                               ICSMIX_MIN_ATTN);
 3100         ics2101_mix_attenuate(ic,
 3101                               GUSMIX_CHAN_LINE,
 3102                               ICSMIX_RIGHT,
 3103                               ICSMIX_MIN_ATTN);
 3104 
 3105         ics2101_mix_attenuate(ic,
 3106                               GUSMIX_CHAN_CD,
 3107                               ICSMIX_LEFT,
 3108                               ICSMIX_MIN_ATTN);
 3109         ics2101_mix_attenuate(ic,
 3110                               GUSMIX_CHAN_CD,
 3111                               ICSMIX_RIGHT,
 3112                               ICSMIX_MIN_ATTN);
 3113 
 3114         ics2101_mix_attenuate(ic,
 3115                               GUSMIX_CHAN_DAC,
 3116                               ICSMIX_LEFT,
 3117                               ICSMIX_MIN_ATTN);
 3118         ics2101_mix_attenuate(ic,
 3119                               GUSMIX_CHAN_DAC,
 3120                               ICSMIX_RIGHT,
 3121                               ICSMIX_MIN_ATTN);
 3122 
 3123         ics2101_mix_attenuate(ic,
 3124                               ICSMIX_CHAN_4,
 3125                               ICSMIX_LEFT,
 3126                               ICSMIX_MAX_ATTN);
 3127         ics2101_mix_attenuate(ic,
 3128                               ICSMIX_CHAN_4,
 3129                               ICSMIX_RIGHT,
 3130                               ICSMIX_MAX_ATTN);
 3131 
 3132         ics2101_mix_attenuate(ic,
 3133                               GUSMIX_CHAN_MASTER,
 3134                               ICSMIX_LEFT,
 3135                               ICSMIX_MIN_ATTN);
 3136         ics2101_mix_attenuate(ic,
 3137                               GUSMIX_CHAN_MASTER,
 3138                               ICSMIX_RIGHT,
 3139                               ICSMIX_MIN_ATTN);
 3140         /* unmute other stuff: */
 3141         gusics_cd_mute(ic, 0);
 3142         gusics_dac_mute(ic, 0);
 3143         gusics_linein_mute(ic, 0);
 3144         return;
 3145 }
 3146 
 3147 
 3148 
 3149 void
 3150 gus_subattach(struct gus_softc *sc, struct isa_attach_args *ia)
 3151 {
 3152         int             i;
 3153         bus_space_tag_t iot;
 3154         unsigned char   c,d,m;
 3155         u_long          s;
 3156 
 3157         iot = sc->sc_iot;
 3158 
 3159         /*
 3160          * Figure out our board rev, and see if we need to initialize the
 3161          * mixer
 3162          */
 3163 
 3164         c = bus_space_read_1(iot, sc->sc_ioh3, GUS_BOARD_REV);
 3165         if (c != 0xff)
 3166                 sc->sc_revision = c;
 3167         else
 3168                 sc->sc_revision = 0;
 3169 
 3170         SELECT_GUS_REG(iot, sc->sc_ioh2, GUSREG_RESET);
 3171         bus_space_write_1(iot, sc->sc_ioh2, GUS_DATA_HIGH, 0x00);
 3172 
 3173         gusreset(sc, GUS_MAX_VOICES); /* initialize all voices */
 3174         gusreset(sc, GUS_MIN_VOICES); /* then set to just the ones we use */
 3175 
 3176         /*
 3177          * Setup the IRQ and DRQ lines in software, using values from
 3178          * config file
 3179          */
 3180 
 3181         m = GUSMASK_LINE_IN|GUSMASK_LINE_OUT;           /* disable all */
 3182 
 3183         c = ((unsigned char) gus_irq_map[ia->ia_irq]) | GUSMASK_BOTH_RQ;
 3184 
 3185         if (sc->sc_recdrq == sc->sc_drq)
 3186                 d = (unsigned char) (gus_drq_map[sc->sc_drq] |
 3187                                 GUSMASK_BOTH_RQ);
 3188         else
 3189                 d = (unsigned char) (gus_drq_map[sc->sc_drq] |
 3190                                 gus_drq_map[sc->sc_recdrq] << 3);
 3191 
 3192         /*
 3193          * Program the IRQ and DMA channels on the GUS.  Note that we hardwire
 3194          * the GUS to only use one IRQ channel, but we give the user the
 3195          * option of using two DMA channels (the other one given by the drq2
 3196          * option in the config file).  Two DMA channels are needed for full-
 3197          * duplex operation.
 3198          *
 3199          * The order of these operations is very magical.
 3200          */
 3201 
 3202         s = intr_disable();             /* XXX needed? */
 3203 
 3204         bus_space_write_1(iot, sc->sc_ioh1, GUS_REG_CONTROL, GUS_REG_IRQCTL);
 3205         bus_space_write_1(iot, sc->sc_ioh1, GUS_MIX_CONTROL, m);
 3206         bus_space_write_1(iot, sc->sc_ioh1, GUS_IRQCTL_CONTROL, 0x00);
 3207         bus_space_write_1(iot, sc->sc_ioh1, 0x0f, 0x00);
 3208 
 3209         bus_space_write_1(iot, sc->sc_ioh1, GUS_MIX_CONTROL, m);
 3210 
 3211         /* magic reset? */
 3212         bus_space_write_1(iot, sc->sc_ioh1, GUS_DMA_CONTROL, d | 0x80);
 3213 
 3214         bus_space_write_1(iot, sc->sc_ioh1, GUS_MIX_CONTROL,
 3215             m | GUSMASK_CONTROL_SEL);
 3216         bus_space_write_1(iot, sc->sc_ioh1, GUS_IRQ_CONTROL, c);
 3217 
 3218         bus_space_write_1(iot, sc->sc_ioh1, GUS_MIX_CONTROL, m);
 3219         bus_space_write_1(iot, sc->sc_ioh1, GUS_DMA_CONTROL, d);
 3220 
 3221         bus_space_write_1(iot, sc->sc_ioh1, GUS_MIX_CONTROL,
 3222             m | GUSMASK_CONTROL_SEL);
 3223         bus_space_write_1(iot, sc->sc_ioh1, GUS_IRQ_CONTROL, c);
 3224 
 3225         bus_space_write_1(iot, sc->sc_ioh2, GUS_VOICE_SELECT, 0x00);
 3226 
 3227         /* enable line in, line out.  leave mic disabled. */
 3228         bus_space_write_1(iot, sc->sc_ioh1, GUS_MIX_CONTROL,
 3229              (m | GUSMASK_LATCHES) & ~(GUSMASK_LINE_OUT|GUSMASK_LINE_IN));
 3230         bus_space_write_1(iot, sc->sc_ioh2, GUS_VOICE_SELECT, 0x00);
 3231 
 3232         intr_restore(s);
 3233 
 3234         sc->sc_mixcontrol =
 3235                 (m | GUSMASK_LATCHES) & ~(GUSMASK_LINE_OUT|GUSMASK_LINE_IN);
 3236 
 3237         sc->sc_codec.sc_isa = sc->sc_isa;
 3238 
 3239         if (sc->sc_revision >= 5 && sc->sc_revision <= 9) {
 3240                 sc->sc_flags |= GUS_MIXER_INSTALLED;
 3241                 gus_init_ics2101(sc);
 3242         }
 3243         if (sc->sc_revision < 10 || !gus_init_cs4231(sc)) {
 3244                 /* Not using the CS4231, so create our DMA maps. */
 3245                 if (sc->sc_drq != -1) {
 3246                         if (isa_dmamap_create(sc->sc_isa, sc->sc_drq,
 3247                             MAX_ISADMA, BUS_DMA_NOWAIT|BUS_DMA_ALLOCNOW)) {
 3248                                 printf("%s: can't create map for drq %d\n",
 3249                                        sc->sc_dev.dv_xname, sc->sc_drq);
 3250                                 return;
 3251                         }
 3252                 }
 3253                 if (sc->sc_recdrq != -1 && sc->sc_recdrq != sc->sc_drq) {
 3254                         if (isa_dmamap_create(sc->sc_isa, sc->sc_recdrq,
 3255                             MAX_ISADMA, BUS_DMA_NOWAIT|BUS_DMA_ALLOCNOW)) {
 3256                                 printf("%s: can't create map for drq %d\n",
 3257                                        sc->sc_dev.dv_xname, sc->sc_recdrq);
 3258                                 return;
 3259                         }
 3260                 }
 3261         }
 3262 
 3263         timeout_set(&sc->sc_dma_tmo, gus_dmaout_timeout, sc);
 3264 
 3265         SELECT_GUS_REG(iot, sc->sc_ioh2, GUSREG_RESET);
 3266         /*
 3267          * Check to see how much memory we have on this card; see if any
 3268          * "mirroring" occurs.  We're assuming at least 256K already exists
 3269          * on the card; otherwise the initial probe would have failed
 3270          */
 3271 
 3272         guspoke(iot, sc->sc_ioh2, 0L, 0x00);
 3273         for(i = 1; i < 1024; i++) {
 3274                 u_long loc;
 3275 
 3276                 /*
 3277                  * See if we've run into mirroring yet
 3278                  */
 3279 
 3280                 if (guspeek(iot, sc->sc_ioh2, 0L) != 0)
 3281                         break;
 3282 
 3283                 loc = i << 10;
 3284 
 3285                 guspoke(iot, sc->sc_ioh2, loc, 0xaa);
 3286                 if (guspeek(iot, sc->sc_ioh2, loc) != 0xaa)
 3287                         break;
 3288         }
 3289 
 3290         sc->sc_dsize = i;
 3291         /*
 3292          * The "official" (3.x) version number cannot easily be obtained.
 3293          * The revision register does not correspond to the minor number
 3294          * of the board version. Simply use the revision register as
 3295          * identification.
 3296          */
 3297         printf(": ver %d", sc->sc_revision);
 3298         if (sc->sc_revision >= 10)
 3299                 printf(", MAX");
 3300         else {
 3301                 if (HAS_MIXER(sc))
 3302                         printf(", ICS2101 mixer");
 3303                 if (HAS_CODEC(sc))
 3304                         printf(", %s codec/mixer", sc->sc_codec.chip_name);
 3305         }
 3306         printf(", %dKB DRAM, ", sc->sc_dsize);
 3307         if (sc->sc_recdrq == sc->sc_drq) {
 3308                 printf("half-duplex");
 3309         } else {
 3310                 printf("full-duplex, record drq %d", sc->sc_recdrq);
 3311         }
 3312 
 3313         printf("\n");
 3314 
 3315         /*
 3316          * Setup a default interrupt handler
 3317          */
 3318 
 3319         sc->sc_ih = isa_intr_establish(ia->ia_ic, ia->ia_irq,
 3320             IST_EDGE, IPL_AUDIO | IPL_MPSAFE,
 3321             gusintr, sc /* sc->sc_gusdsp */, sc->sc_dev.dv_xname);
 3322 
 3323         /*
 3324          * Set some default values
 3325          * XXX others start with 8kHz mono mulaw
 3326          */
 3327 
 3328         sc->sc_irate = sc->sc_orate = 44100;
 3329         sc->sc_encoding = AUDIO_ENCODING_SLINEAR_LE;
 3330         sc->sc_precision = 16;
 3331         sc->sc_voc[GUS_VOICE_LEFT].voccntl |= GUSMASK_DATA_SIZE16;
 3332         sc->sc_voc[GUS_VOICE_RIGHT].voccntl |= GUSMASK_DATA_SIZE16;
 3333         sc->sc_channels = 1;
 3334         sc->sc_ogain = 340;
 3335         gus_commit_settings(sc);
 3336 
 3337         /*
 3338          * We always put the left channel full left & right channel
 3339          * full right.
 3340          * For mono playback, we set up both voices playing the same buffer.
 3341          */
 3342         bus_space_write_1(iot, sc->sc_ioh2, GUS_VOICE_SELECT,
 3343             (u_char)GUS_VOICE_LEFT);
 3344         SELECT_GUS_REG(iot, sc->sc_ioh2, GUSREG_PAN_POS);
 3345         bus_space_write_1(iot, sc->sc_ioh2, GUS_DATA_HIGH, GUS_PAN_FULL_LEFT);
 3346 
 3347         bus_space_write_1(iot, sc->sc_ioh2, GUS_VOICE_SELECT,
 3348             (u_char)GUS_VOICE_RIGHT);
 3349         SELECT_GUS_REG(iot, sc->sc_ioh2, GUSREG_PAN_POS);
 3350         bus_space_write_1(iot, sc->sc_ioh2, GUS_DATA_HIGH, GUS_PAN_FULL_RIGHT);
 3351 
 3352         /*
 3353          * Attach to the generic audio layer
 3354          */
 3355 
 3356         if (HAS_CODEC(sc)) {
 3357                 audio_attach_mi(&gusmax_hw_if, (void *)&sc->sc_codec, NULL,
 3358                     &sc->sc_dev);
 3359         } else {
 3360                 audio_attach_mi(&gus_hw_if, (void *)sc, NULL, &sc->sc_dev);
 3361         }
 3362 }
 3363 
 3364 /*
 3365  * Test to see if a particular I/O base is valid for the GUS.  Return true
 3366  * if it is.
 3367  */
 3368 
 3369 int
 3370 gus_test_iobase (bus_space_tag_t iot, int iobase)
 3371 {
 3372         bus_space_handle_t ioh1, ioh2, ioh3, ioh4;
 3373         u_char s1, s2;
 3374         int rv = 0;
 3375 
 3376         /* Map i/o space */
 3377         if (bus_space_map(iot, iobase, GUS_NPORT1, 0, &ioh1))
 3378                 return 0;
 3379         if (bus_space_map(iot, iobase+GUS_IOH2_OFFSET, GUS_NPORT2, 0, &ioh2))
 3380                 goto bad1;
 3381 
 3382         /* XXX Maybe we shouldn't fail on mapping this, but just assume
 3383          * the card is of revision 0? */
 3384         if (bus_space_map(iot, iobase+GUS_IOH3_OFFSET, GUS_NPORT3, 0, &ioh3))
 3385                 goto bad2;
 3386 
 3387         if (bus_space_map(iot, iobase+GUS_IOH4_OFFSET, GUS_NPORT4, 0, &ioh4))
 3388                 goto bad3;
 3389 
 3390         /*
 3391          * Reset GUS to an initial state before we do anything.
 3392          */
 3393 
 3394         mtx_enter(&audio_lock);
 3395         delay(500);
 3396 
 3397         SELECT_GUS_REG(iot, ioh2, GUSREG_RESET);
 3398         bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0x00);
 3399 
 3400         delay(500);
 3401 
 3402         SELECT_GUS_REG(iot, ioh2, GUSREG_RESET);
 3403         bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, GUSMASK_MASTER_RESET);
 3404 
 3405         delay(500);
 3406 
 3407         mtx_leave(&audio_lock);
 3408 
 3409         /*
 3410          * See if we can write to the board's memory
 3411          */
 3412 
 3413         s1 = guspeek(iot, ioh2, 0L);
 3414         s2 = guspeek(iot, ioh2, 1L);
 3415 
 3416         guspoke(iot, ioh2, 0L, 0xaa);
 3417         guspoke(iot, ioh2, 1L, 0x55);
 3418 
 3419         if (guspeek(iot, ioh2, 0L) != 0xaa)
 3420                 goto bad;
 3421 
 3422         guspoke(iot, ioh2, 0L, s1);
 3423         guspoke(iot, ioh2, 1L, s2);
 3424 
 3425         rv = 1;
 3426 
 3427 bad:
 3428         bus_space_unmap(iot, ioh4, GUS_NPORT4);
 3429 bad3:
 3430         bus_space_unmap(iot, ioh3, GUS_NPORT3);
 3431 bad2:
 3432         bus_space_unmap(iot, ioh2, GUS_NPORT2);
 3433 bad1:
 3434         bus_space_unmap(iot, ioh1, GUS_NPORT1);
 3435         return rv;
 3436 }

Cache object: e8feac3b2f9edbee7508268d8b0c3ecf


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.