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