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