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