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