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


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

FreeBSD/Linux Kernel Cross Reference
sys/dev/isa/gusvar.h

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

    1 /*      $OpenBSD: gusvar.h,v 1.13 2022/11/02 10:41:34 kn Exp $  */
    2 /*      $NetBSD: gus.c,v 1.51 1998/01/25 23:48:06 mycroft Exp $ */
    3 
    4 /*-
    5  * Copyright (c) 1996 The NetBSD Foundation, Inc.
    6  * All rights reserved.
    7  *
    8  * This code is derived from software contributed to The NetBSD Foundation
    9  * by Ken Hornstein and John Kohl.
   10  *
   11  * Redistribution and use in source and binary forms, with or without
   12  * modification, are permitted provided that the following conditions
   13  * are met:
   14  * 1. Redistributions of source code must retain the above copyright
   15  *    notice, this list of conditions and the following disclaimer.
   16  * 2. Redistributions in binary form must reproduce the above copyright
   17  *    notice, this list of conditions and the following disclaimer in the
   18  *    documentation and/or other materials provided with the distribution.
   19  *
   20  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
   21  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
   22  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
   23  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
   24  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   25  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   26  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   27  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   28  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   29  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   30  * POSSIBILITY OF SUCH DAMAGE.
   31  */
   32 
   33 /*
   34  *
   35  * TODO:
   36  *      . figure out why mixer activity while sound is playing causes problems
   37  *        (phantom interrupts?)
   38  *      . figure out a better deinterleave strategy that avoids sucking up
   39  *        CPU, memory and cache bandwidth.  (Maybe a special encoding?
   40  *        Maybe use the double-speed sampling/hardware deinterleave trick
   41  *        from the GUS SDK?)  A 486/33 isn't quite fast enough to keep
   42  *        up with 44.1kHz 16-bit stereo output without some drop-outs.
   43  *      . use CS4231 for 16-bit sampling, for a-law and mu-law playback.
   44  *      . actually test full-duplex sampling(recording) and playback.
   45  */
   46 
   47 /*
   48  * Gravis UltraSound driver
   49  *
   50  * For more detailed information, see the GUS developers' kit
   51  * available on the net at:
   52  *
   53  * ftp://freedom.nmsu.edu/pub/ultrasound/gravis/util/
   54  *      gusdkXXX.zip (developers' kit--get rev 2.22 or later)
   55  *              See ultrawrd.doc inside--it's MS Word (ick), but it's the bible
   56  *
   57  */
   58 
   59 /*
   60  * The GUS Max has a slightly strange set of connections between the CS4231
   61  * and the GF1 and the DMA interconnects.  It's set up so that the CS4231 can
   62  * be playing while the GF1 is loading patches from the system.
   63  *
   64  * Here's a recreation of the DMA interconnect diagram:
   65  *
   66  *       GF1
   67  *   +---------+                                 digital
   68  *   |         |  record                         ASIC
   69  *   |         |--------------+
   70  *   |         |              |                +--------+
   71  *   |         | play (dram)  |      +----+    |        |
   72  *   |         |--------------(------|-\  |    |   +-+  |
   73  *   +---------+              |      |  >-|----|---|C|--|------  dma chan 1
   74  *                            |  +---|-/  |    |   +-+  |
   75  *                            |  |   +----+    |    |   |
   76  *                            |  |   +----+    |    |   |
   77  *   +---------+        +-+   +--(---|-\  |    |    |   |
   78  *   |         | play   |8|      |   |  >-|----|----+---|------  dma chan 2
   79  *   | ---C----|--------|/|------(---|-/  |    |        |
   80  *   |    ^    |record  |1|      |   +----+    |        |
   81  *   |    |    |   /----|6|------+             +--------+
   82  *   | ---+----|--/     +-+
   83  *   +---------+
   84  *     CS4231   8-to-16 bit bus conversion, if needed
   85  *
   86  *
   87  * "C" is an optional combiner.
   88  *
   89  */
   90 
   91 /*
   92  * Software state of a single "voice" on the GUS
   93  */
   94 struct gus_voice {
   95 
   96         /*
   97          * Various control bits
   98          */
   99 
  100         unsigned char voccntl;  /* State of voice control register */
  101         unsigned char volcntl;  /* State of volume control register */
  102         unsigned char pan_pos;  /* Position of volume panning (4 bits) */
  103         int rate;               /* Sample rate of voice being played back */
  104 
  105         /*
  106          * Address of the voice data into the GUS's DRAM.  20 bits each
  107          */
  108 
  109         u_long start_addr;      /* Starting address of voice data loop area */
  110         u_long end_addr;        /* Ending address of voice data loop */
  111         u_long current_addr;    /* Beginning address of voice data
  112                                    (start playing here) */
  113 
  114         /*
  115          * linear volume values for the GUS's volume ramp.  0-511 (9 bits).
  116          * These values must be translated into the logarithmic values using
  117          * gus_log_volumes[]
  118          */
  119 
  120         int start_volume;       /* Starting position of volume ramp */
  121         int current_volume;     /* Current position of volume on volume ramp */
  122         int end_volume;         /* Ending position of volume on volume ramp */
  123 };
  124 
  125 /*
  126  * Software state of GUS
  127  */
  128 struct gus_softc {
  129         struct device sc_dev;           /* base device */
  130         struct device *sc_isa;          /* pointer to ISA parent */
  131         void *sc_ih;                    /* interrupt vector */
  132         struct timeout sc_dma_tmo;
  133         bus_space_tag_t sc_iot;         /* tag */
  134         bus_space_handle_t sc_ioh1;     /* handle */
  135         bus_space_handle_t sc_ioh2;     /* handle */
  136         bus_space_handle_t sc_ioh3;     /* ICS2101 handle */
  137         bus_space_handle_t sc_ioh4;     /* MIDI handle */
  138 
  139         int sc_iobase;                  /* I/O base address */
  140         int sc_irq;                     /* IRQ used */
  141         int sc_drq;                     /* DMA channel for play */
  142         int sc_recdrq;                  /* DMA channel for recording */
  143 
  144         int sc_flags;                   /* Various flags about the GUS */
  145 #define GUS_MIXER_INSTALLED     0x01    /* An ICS mixer is installed */
  146 #define GUS_LOCKED              0x02    /* GUS is busy doing multi-phase DMA */
  147 #define GUS_CODEC_INSTALLED     0x04    /* CS4231 installed/MAX */
  148 #define GUS_PLAYING             0x08    /* GUS is playing a voice */
  149 #define GUS_DMAOUT_ACTIVE       0x10    /* GUS is busy doing audio DMA */
  150 #define GUS_DMAIN_ACTIVE        0x20    /* GUS is busy sampling  */
  151 #define GUS_OPEN                0x100   /* GUS is open */
  152         int sc_dsize;                   /* Size of GUS DRAM */
  153         int sc_voices;                  /* Number of active voices */
  154         u_char sc_revision;             /* Board revision of GUS */
  155         u_char sc_mixcontrol;           /* Value of GUS_MIX_CONTROL register */
  156 
  157         u_long sc_orate;                /* Output sampling rate */
  158         u_long sc_irate;                /* Input sampling rate */
  159 
  160         int sc_encoding;                /* Current data encoding type */
  161         int sc_precision;               /* # of bits of precision */
  162         int sc_channels;                /* Number of active channels */
  163         int sc_blocksize;               /* Current blocksize */
  164         int sc_chanblocksize;           /* Current blocksize for each in-use
  165                                            channel */
  166         short sc_nbufs;                 /* how many on-GUS bufs per-channel */
  167         short sc_bufcnt;                /* how many need to be played */
  168         void *sc_deintr_buf;            /* deinterleave buffer for stereo */
  169 
  170         int sc_ogain;                   /* Output gain control */
  171         u_char sc_out_port;             /* Current out port (generic only) */
  172         u_char sc_in_port;              /* keep track of it when no codec */
  173 
  174         void (*sc_dmaoutintr)(void *);  /* DMA completion intr handler */
  175         void *sc_outarg;                /* argument for sc_dmaoutintr() */
  176         u_char *sc_dmaoutaddr;          /* for isadma_done */
  177         u_long sc_gusaddr;              /* where did we just put it? */
  178         int sc_dmaoutcnt;               /* for isadma_done */
  179 
  180         void (*sc_dmainintr)(void *);   /* DMA completion intr handler */
  181         void *sc_inarg;                 /* argument for sc_dmaoutintr() */
  182         u_char *sc_dmainaddr;           /* for isadma_done */
  183         int sc_dmaincnt;                /* for isadma_done */
  184 
  185         struct stereo_dma_intr {
  186                 void (*intr)(void *);
  187                 void *arg;
  188                 u_char *buffer;
  189                 u_long dmabuf;
  190                 int size;
  191                 int flags;
  192         } sc_stereo;
  193 
  194         /*
  195          * State information for linear audio layer
  196          */
  197 
  198         int sc_dmabuf;                  /* Which ring buffer we're DMA'ing to */
  199         int sc_playbuf;                 /* Which ring buffer we're playing */
  200 
  201         /*
  202          * Voice information array.  All voice-specific information is stored
  203          * here
  204          */
  205 
  206         struct gus_voice sc_voc[32];    /* Voice data for each voice */
  207         union {
  208                 struct ics2101_softc sc_mixer_u;
  209                 struct ad1848_softc sc_codec_u;
  210         } u;
  211 #define sc_mixer u.sc_mixer_u
  212 #define sc_codec u.sc_codec_u
  213 };
  214 
  215 struct ics2101_volume {
  216         u_char left;
  217         u_char right;
  218 };
  219 
  220 #define HAS_CODEC(sc) ((sc)->sc_flags & GUS_CODEC_INSTALLED)
  221 #define HAS_MIXER(sc) ((sc)->sc_flags & GUS_MIXER_INSTALLED)
  222 
  223 /*
  224  * Mixer devices for ICS2101
  225  */
  226 /* MIC IN mute, line in mute, line out mute are first since they can be done
  227    even if no ICS mixer. */
  228 #define GUSICS_MIC_IN_MUTE              0
  229 #define GUSICS_LINE_IN_MUTE             1
  230 #define GUSICS_MASTER_MUTE              2
  231 #define GUSICS_CD_MUTE                  3
  232 #define GUSICS_DAC_MUTE                 4
  233 #define GUSICS_MIC_IN_LVL               5
  234 #define GUSICS_LINE_IN_LVL              6
  235 #define GUSICS_CD_LVL                   7
  236 #define GUSICS_DAC_LVL                  8
  237 #define GUSICS_MASTER_LVL               9
  238 
  239 #define GUSICS_RECORD_SOURCE            10
  240 
  241 /* Classes */
  242 #define GUSICS_INPUT_CLASS              11
  243 #define GUSICS_OUTPUT_CLASS             12
  244 #define GUSICS_RECORD_CLASS             13
  245 
  246 /*
  247  * Mixer & MUX devices for CS4231
  248  */
  249 #define GUSMAX_MONO_LVL                 0 /* mic input to MUX;
  250                                              also mono mixer input */
  251 #define GUSMAX_DAC_LVL                  1 /* input to MUX; also mixer input */
  252 #define GUSMAX_LINE_IN_LVL              2 /* input to MUX; also mixer input */
  253 #define GUSMAX_CD_LVL                   3 /* mixer input only */
  254 #define GUSMAX_MONITOR_LVL              4 /* digital mix (?) */
  255 #define GUSMAX_OUT_LVL                  5 /* output level. (?) */
  256 #define GUSMAX_SPEAKER_LVL              6 /* pseudo-device for mute */
  257 #define GUSMAX_LINE_IN_MUTE             7 /* pre-mixer */
  258 #define GUSMAX_DAC_MUTE                 8 /* pre-mixer */
  259 #define GUSMAX_CD_MUTE                  9 /* pre-mixer */
  260 #define GUSMAX_MONO_MUTE                10 /* pre-mixer--microphone/mono */
  261 #define GUSMAX_MONITOR_MUTE             11 /* post-mixer level/mute */
  262 #define GUSMAX_SPEAKER_MUTE             12 /* speaker mute */
  263 
  264 #define GUSMAX_REC_LVL                  13 /* post-MUX gain */
  265 
  266 #define GUSMAX_RECORD_SOURCE            14
  267 
  268 /* Classes */
  269 #define GUSMAX_INPUT_CLASS              15
  270 #define GUSMAX_RECORD_CLASS             16
  271 #define GUSMAX_MONITOR_CLASS            17
  272 #define GUSMAX_OUTPUT_CLASS             18
  273 
  274 #ifdef AUDIO_DEBUG
  275 #define GUSPLAYDEBUG    /*XXX*/
  276 #define DPRINTF(x)      if (gusdebug) printf x
  277 #define DMAPRINTF(x)    if (gusdmadebug) printf x
  278 extern int      gusdebug;
  279 extern int      gusdmadebug;
  280 #else
  281 #define DPRINTF(x)
  282 #define DMAPRINTF(x)
  283 #endif
  284 extern int      gus_dostereo;
  285 
  286 #define NDMARECS 2048
  287 #ifdef GUSPLAYDEBUG
  288 extern int      gusstats;
  289 struct dma_record {
  290     struct timeval tv;
  291     u_long gusaddr;
  292     caddr_t bsdaddr;
  293     u_short count;
  294     u_char channel;
  295     u_char direction;
  296 };
  297 
  298 extern struct dma_record dmarecords[NDMARECS];
  299 
  300 extern int dmarecord_index;
  301 #endif
  302 
  303 /*
  304  * local routines
  305  */
  306 
  307 int     gusopen(void *, int);
  308 void    gusclose(void *);
  309 void    gusmax_close(void *);
  310 int     gusintr(void *);
  311 int     gus_set_in_gain(caddr_t, u_int, u_char);
  312 int     gus_get_in_gain(caddr_t);
  313 int     gus_set_out_gain(caddr_t, u_int, u_char);
  314 int     gus_get_out_gain(caddr_t);
  315 int     gus_set_params(void *, int, int, struct audio_params *, struct audio_params *);
  316 int     gusmax_set_params(void *, int, int, struct audio_params *, struct audio_params *);
  317 int     gus_round_blocksize(void *, int);
  318 int     gus_commit_settings(void *);
  319 int     gus_dma_output(void *, void *, int, void (*)(void *), void *);
  320 int     gus_dma_input(void *, void *, int, void (*)(void *), void *);
  321 int     gus_halt_out_dma(void *);
  322 int     gus_halt_in_dma(void *);
  323 int     gus_speaker_ctl(void *, int);
  324 int     gusmaxopen(void *, int);
  325 int     gusmax_round_blocksize(void *, int);
  326 int     gusmax_commit_settings(void *);
  327 int     gusmax_dma_output(void *, void *, int, void (*)(void *), void *);
  328 int     gusmax_dma_input(void *, void *, int, void (*)(void *), void *);
  329 int     gusmax_halt_out_dma(void *);
  330 int     gusmax_halt_in_dma(void *);
  331 
  332 void    gus_deinterleave(struct gus_softc *, void *, int);
  333 
  334 int     gus_mic_ctl(void *, int);
  335 int     gus_linein_ctl(void *, int);
  336 int             gus_test_iobase(bus_space_tag_t, int);
  337 void    guspoke(bus_space_tag_t, bus_space_handle_t, long, u_char);
  338 void    gusdmaout(struct gus_softc *, int, u_long, caddr_t, int);
  339 int     gus_init_cs4231(struct gus_softc *);
  340 void    gus_init_ics2101(struct gus_softc *);
  341 
  342 void    gus_set_chan_addrs(struct gus_softc *);
  343 void    gusreset(struct gus_softc *, int);
  344 void    gus_set_voices(struct gus_softc *, int);
  345 void    gus_set_volume(struct gus_softc *, int, int);
  346 void    gus_set_samprate(struct gus_softc *, int, int);
  347 void    gus_set_recrate(struct gus_softc *, u_long);
  348 void    gus_start_voice(struct gus_softc *, int, int);
  349 void    gus_stop_voice(struct gus_softc *, int, int);
  350 void    gus_set_endaddr(struct gus_softc *, int, u_long);
  351 #ifdef GUSPLAYDEBUG
  352 void    gus_set_curaddr(struct gus_softc *, int, u_long);
  353 u_long  gus_get_curaddr(struct gus_softc *, int);
  354 #endif
  355 int     gus_dmaout_intr(struct gus_softc *);
  356 void    gus_dmaout_dointr(struct gus_softc *);
  357 void    gus_dmaout_timeout(void *);
  358 int     gus_dmain_intr(struct gus_softc *);
  359 int     gus_voice_intr(struct gus_softc *);
  360 void    gus_start_playing(struct gus_softc *, int);
  361 int     gus_continue_playing(struct gus_softc *, int);
  362 u_char guspeek(bus_space_tag_t, bus_space_handle_t, u_long);
  363 u_long convert_to_16bit(u_long);
  364 int     gus_mixer_set_port(void *, mixer_ctrl_t *);
  365 int     gus_mixer_get_port(void *, mixer_ctrl_t *);
  366 int     gusmax_mixer_set_port(void *, mixer_ctrl_t *);
  367 int     gusmax_mixer_get_port(void *, mixer_ctrl_t *);
  368 int     gus_mixer_query_devinfo(void *, mixer_devinfo_t *);
  369 int     gusmax_mixer_query_devinfo(void *, mixer_devinfo_t *);
  370 void   *gus_malloc(void *, int, size_t, int, int);
  371 void    gus_free(void *, void *, int);
  372 size_t  gus_round(void *, int, size_t);
  373 
  374 void    gusics_master_mute(struct ics2101_softc *, int);
  375 void    gusics_dac_mute(struct ics2101_softc *, int);
  376 void    gusics_mic_mute(struct ics2101_softc *, int);
  377 void    gusics_linein_mute(struct ics2101_softc *, int);
  378 void    gusics_cd_mute(struct ics2101_softc *, int);
  379 
  380 void    stereo_dmaintr(void *);
  381 
  382 extern const int gus_irq_map[];
  383 extern const int gus_drq_map[];
  384 extern const int gus_base_addrs[];
  385 extern const int gus_addrs;
  386 
  387 #define SELECT_GUS_REG(iot,ioh1,x) bus_space_write_1(iot,ioh1,GUS_REG_SELECT,x)
  388 #define ADDR_HIGH(x) (unsigned int) ((x >> 7L) & 0x1fffL)
  389 #define ADDR_LOW(x) (unsigned int) ((x & 0x7fL) << 9L)
  390 
  391 #define GUS_MIN_VOICES 14       /* Minimum possible number of voices */
  392 #define GUS_MAX_VOICES 32       /* Maximum possible number of voices */
  393 #define GUS_VOICE_LEFT 0        /* Voice used for left (and mono) playback */
  394 #define GUS_VOICE_RIGHT 1       /* Voice used for right playback */
  395 #define GUS_MEM_OFFSET 32       /* Offset into GUS memory to begin of buffer */
  396 #define GUS_BUFFER_MULTIPLE 1024        /* Audio buffers are multiples of this */
  397 #define GUS_MEM_FOR_BUFFERS     131072  /* use this many bytes on-GUS */
  398 #define GUS_LEFT_RIGHT_OFFSET   (sc->sc_nbufs * sc->sc_chanblocksize + GUS_MEM_OFFSET)
  399 
  400 #define GUS_PREC_BYTES (sc->sc_precision >> 3) /* precision to bytes */
  401 
  402 /* splgus() must be splaudio() */
  403 
  404 #define splgus splaudio
  405 
  406 extern const struct audio_hw_if gus_hw_if;
  407 
  408 #define FLIP_REV        5               /* This rev has flipped mixer chans */
  409 
  410 void gus_subattach(struct gus_softc *, struct isa_attach_args *);

Cache object: 71b0dbad0e67760b7a4934162845c46e


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


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