root/dev/isa/gusvar.h

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

INCLUDED FROM


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

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