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