root/dev/isa/gus.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. gusopen
  2. gusmaxopen
  3. gus_deinterleave
  4. gusmax_dma_output
  5. stereo_dmaintr
  6. gus_dma_output
  7. gusmax_close
  8. gusclose
  9. gusintr
  10. gus_dmaout_timeout
  11. gus_dmaout_intr
  12. gus_dmaout_dointr
  13. gus_voice_intr
  14. gus_start_playing
  15. gus_continue_playing
  16. gusdmaout
  17. gus_start_voice
  18. gus_stop_voice
  19. gus_set_volume
  20. gusmax_set_params
  21. gus_set_params
  22. gusmax_round_blocksize
  23. gus_round_blocksize
  24. gus_get_out_gain
  25. gus_set_voices
  26. gusmax_commit_settings
  27. gus_commit_settings
  28. gus_set_chan_addrs
  29. gus_set_samprate
  30. gus_set_recrate
  31. gusmax_speaker_ctl
  32. gus_speaker_ctl
  33. gus_linein_ctl
  34. gus_mic_ctl
  35. gus_set_endaddr
  36. gus_set_curaddr
  37. gus_get_curaddr
  38. convert_to_16bit
  39. guspoke
  40. guspeek
  41. gusreset
  42. gus_init_cs4231
  43. gus_getdev
  44. gus_set_in_gain
  45. gus_get_in_gain
  46. gusmax_dma_input
  47. gus_dma_input
  48. gus_dmain_intr
  49. gusmax_halt_out_dma
  50. gusmax_halt_in_dma
  51. gus_halt_out_dma
  52. gus_halt_in_dma
  53. gusmax_mixer_get_port
  54. gus_mixer_get_port
  55. gusics_master_mute
  56. gusics_mic_mute
  57. gusics_linein_mute
  58. gusics_cd_mute
  59. gusics_dac_mute
  60. gusmax_mixer_set_port
  61. gus_mixer_set_port
  62. gus_get_props
  63. gusmax_get_props
  64. gusmax_mixer_query_devinfo
  65. gus_mixer_query_devinfo
  66. gus_query_encoding
  67. gus_init_ics2101
  68. gus_subattach
  69. gus_test_iobase

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

/* [<][>][^][v][top][bottom][index][help] */