1 /* $OpenBSD: ess.c,v 1.33 2022/11/02 10:41:34 kn Exp $ */ 2 /* $NetBSD: ess.c,v 1.44.4.1 1999/06/21 01:18:00 thorpej Exp $ */ 3 4 /* 5 * Copyright 1997 6 * Digital Equipment Corporation. All rights reserved. 7 * 8 * This software is furnished under license and may be used and 9 * copied only in accordance with the following terms and conditions. 10 * Subject to these conditions, you may download, copy, install, 11 * use, modify and distribute this software in source and/or binary 12 * form. No title or ownership is transferred hereby. 13 * 14 * 1) Any source code used, modified or distributed must reproduce 15 * and retain this copyright notice and list of conditions as 16 * they appear in the source file. 17 * 18 * 2) No right is granted to use any trade name, trademark, or logo of 19 * Digital Equipment Corporation. Neither the "Digital Equipment 20 * Corporation" name nor any trademark or logo of Digital Equipment 21 * Corporation may be used to endorse or promote products derived 22 * from this software without the prior written permission of 23 * Digital Equipment Corporation. 24 * 25 * 3) This software is provided "AS-IS" and any express or implied 26 * warranties, including but not limited to, any implied warranties 27 * of merchantability, fitness for a particular purpose, or 28 * non-infringement are disclaimed. In no event shall DIGITAL be 29 * liable for any damages whatsoever, and in particular, DIGITAL 30 * shall not be liable for special, indirect, consequential, or 31 * incidental damages or damages for lost profits, loss of 32 * revenue or loss of use, whether such damages arise in contract, 33 * negligence, tort, under statute, in equity, at law or otherwise, 34 * even if advised of the possibility of such damage. 35 */ 36 37 /* 38 **++ 39 ** 40 ** ess.c 41 ** 42 ** FACILITY: 43 ** 44 ** DIGITAL Network Appliance Reference Design (DNARD) 45 ** 46 ** MODULE DESCRIPTION: 47 ** 48 ** This module contains the device driver for the ESS 49 ** Technologies 1888/1887/888 sound chip. The code in sbdsp.c was 50 ** used as a reference point when implementing this driver. 51 ** 52 ** AUTHORS: 53 ** 54 ** Blair Fidler Software Engineering Australia 55 ** Gold Coast, Australia. 56 ** 57 ** CREATION DATE: 58 ** 59 ** March 10, 1997. 60 ** 61 ** MODIFICATION HISTORY: 62 ** 63 ** Heavily modified by Lennart Augustsson and Charles M. Hannum for 64 ** bus_dma, changes to audio interface, and many bug fixes. 65 ** ESS1788 support by Nathan J. Williams and Charles M. Hannum. 66 **-- 67 */ 68 69 #include <sys/param.h> 70 #include <sys/systm.h> 71 #include <sys/errno.h> 72 #include <sys/ioctl.h> 73 #include <sys/syslog.h> 74 #include <sys/device.h> 75 #include <sys/kernel.h> 76 #include <sys/timeout.h> 77 #include <sys/fcntl.h> 78 79 #include <machine/cpu.h> 80 #include <machine/intr.h> 81 #include <machine/bus.h> 82 83 #include <sys/audioio.h> 84 #include <dev/audio_if.h> 85 86 #include <dev/isa/isavar.h> 87 #include <dev/isa/isadmavar.h> 88 89 #include <dev/isa/essvar.h> 90 #include <dev/isa/essreg.h> 91 92 #ifdef AUDIO_DEBUG 93 #define DPRINTF(x) if (essdebug) printf x 94 #define DPRINTFN(n,x) if (essdebug>(n)) printf x 95 int essdebug = 0; 96 #else 97 #define DPRINTF(x) 98 #define DPRINTFN(n,x) 99 #endif 100 101 #if 0 102 unsigned uuu; 103 #define EREAD1(t, h, a) (uuu=bus_space_read_1(t, h, a),printf("EREAD %02x=%02x\n", ((int)h&0xfff)+a, uuu),uuu) 104 #define EWRITE1(t, h, a, d) (printf("EWRITE %02x=%02x\n", ((int)h & 0xfff)+a, d), bus_space_write_1(t, h, a, d)) 105 #else 106 #define EREAD1(t, h, a) bus_space_read_1(t, h, a) 107 #define EWRITE1(t, h, a, d) bus_space_write_1(t, h, a, d) 108 #endif 109 110 struct cfdriver ess_cd = { 111 NULL, "ess", DV_DULL 112 }; 113 114 struct audio_params ess_audio_default = 115 {44100, AUDIO_ENCODING_SLINEAR_LE, 16, 2, 1, 2}; 116 117 int ess_setup_sc(struct ess_softc *, int); 118 119 int ess_1788_open(void *, int); 120 int ess_open(void *, int); 121 void ess_1788_close(void *); 122 void ess_1888_close(void *); 123 124 int ess_set_params(void *, int, int, struct audio_params *, 125 struct audio_params *); 126 127 int ess_round_blocksize(void *, int); 128 129 int ess_audio1_trigger_output(void *, void *, void *, int, 130 void (*)(void *), void *, struct audio_params *); 131 int ess_audio2_trigger_output(void *, void *, void *, int, 132 void (*)(void *), void *, struct audio_params *); 133 int ess_audio1_trigger_input(void *, void *, void *, int, 134 void (*)(void *), void *, struct audio_params *); 135 int ess_audio1_halt(void *); 136 int ess_audio2_halt(void *); 137 int ess_audio1_intr(void *); 138 int ess_audio2_intr(void *); 139 void ess_audio1_poll(void *); 140 void ess_audio2_poll(void *); 141 142 int ess_speaker_ctl(void *, int); 143 144 int ess_set_port(void *, mixer_ctrl_t *); 145 int ess_get_port(void *, mixer_ctrl_t *); 146 147 void *ess_malloc(void *, int, size_t, int, int); 148 void ess_free(void *, void *, int); 149 size_t ess_round_buffersize(void *, int, size_t); 150 151 152 int ess_query_devinfo(void *, mixer_devinfo_t *); 153 154 void ess_speaker_on(struct ess_softc *); 155 void ess_speaker_off(struct ess_softc *); 156 157 int ess_config_addr(struct ess_softc *); 158 void ess_config_irq(struct ess_softc *); 159 void ess_config_drq(struct ess_softc *); 160 void ess_setup(struct ess_softc *); 161 int ess_identify(struct ess_softc *); 162 163 int ess_reset(struct ess_softc *); 164 void ess_set_gain(struct ess_softc *, int, int); 165 int ess_set_in_port(struct ess_softc *, int); 166 int ess_set_in_ports(struct ess_softc *, int); 167 u_int ess_srtotc(u_int); 168 u_int ess_srtofc(u_int); 169 u_char ess_get_dsp_status(struct ess_softc *); 170 u_char ess_dsp_read_ready(struct ess_softc *); 171 u_char ess_dsp_write_ready(struct ess_softc *); 172 int ess_rdsp(struct ess_softc *); 173 int ess_wdsp(struct ess_softc *, u_char); 174 u_char ess_read_x_reg(struct ess_softc *, u_char); 175 int ess_write_x_reg(struct ess_softc *, u_char, u_char); 176 void ess_clear_xreg_bits(struct ess_softc *, u_char, u_char); 177 void ess_set_xreg_bits(struct ess_softc *, u_char, u_char); 178 u_char ess_read_mix_reg(struct ess_softc *, u_char); 179 void ess_write_mix_reg(struct ess_softc *, u_char, u_char); 180 void ess_clear_mreg_bits(struct ess_softc *, u_char, u_char); 181 void ess_set_mreg_bits(struct ess_softc *, u_char, u_char); 182 void ess_read_multi_mix_reg(struct ess_softc *, u_char, u_int8_t *, bus_size_t); 183 184 static const char *essmodel[] = { 185 "unsupported", 186 "1888", 187 "1887", 188 "888", 189 "1788", 190 "1869", 191 "1879", 192 "1868", 193 "1878", 194 }; 195 196 /* 197 * Define our interface to the higher level audio driver. 198 */ 199 200 const struct audio_hw_if ess_1788_hw_if = { 201 .open = ess_1788_open, 202 .close = ess_1788_close, 203 .set_params = ess_set_params, 204 .round_blocksize = ess_round_blocksize, 205 .halt_output = ess_audio1_halt, 206 .halt_input = ess_audio1_halt, 207 .set_port = ess_set_port, 208 .get_port = ess_get_port, 209 .query_devinfo = ess_query_devinfo, 210 .allocm = ess_malloc, 211 .freem = ess_free, 212 .round_buffersize = ess_round_buffersize, 213 .trigger_output = ess_audio1_trigger_output, 214 .trigger_input = ess_audio1_trigger_input, 215 }; 216 217 const struct audio_hw_if ess_1888_hw_if = { 218 .open = ess_open, 219 .close = ess_1888_close, 220 .set_params = ess_set_params, 221 .round_blocksize = ess_round_blocksize, 222 .halt_output = ess_audio2_halt, 223 .halt_input = ess_audio1_halt, 224 .set_port = ess_set_port, 225 .get_port = ess_get_port, 226 .query_devinfo = ess_query_devinfo, 227 .allocm = ess_malloc, 228 .freem = ess_free, 229 .round_buffersize = ess_round_buffersize, 230 .trigger_output = ess_audio2_trigger_output, 231 .trigger_input = ess_audio1_trigger_input, 232 }; 233 234 #ifdef AUDIO_DEBUG 235 void ess_printsc(struct ess_softc *); 236 void ess_dump_mixer(struct ess_softc *); 237 238 void 239 ess_printsc(struct ess_softc *sc) 240 { 241 int i; 242 243 printf("open %d iobase 0x%x outport %u inport %u speaker %s\n", 244 (int)sc->sc_open, sc->sc_iobase, sc->out_port, 245 sc->in_port, sc->spkr_state ? "on" : "off"); 246 247 printf("audio1: dmachan %d irq %d nintr %lu intr %p arg %p\n", 248 sc->sc_audio1.drq, sc->sc_audio1.irq, sc->sc_audio1.nintr, 249 sc->sc_audio1.intr, sc->sc_audio1.arg); 250 251 if (!ESS_USE_AUDIO1(sc->sc_model)) { 252 printf("audio2: dmachan %d irq %d nintr %lu intr %p arg %p\n", 253 sc->sc_audio2.drq, sc->sc_audio2.irq, sc->sc_audio2.nintr, 254 sc->sc_audio2.intr, sc->sc_audio2.arg); 255 } 256 257 printf("gain:"); 258 for (i = 0; i < sc->ndevs; i++) 259 printf(" %u,%u", sc->gain[i][ESS_LEFT], sc->gain[i][ESS_RIGHT]); 260 printf("\n"); 261 } 262 263 void 264 ess_dump_mixer(struct ess_softc *sc) 265 { 266 printf("ESS_DAC_PLAY_VOL: mix reg 0x%02x=0x%02x\n", 267 0x7C, ess_read_mix_reg(sc, 0x7C)); 268 printf("ESS_MIC_PLAY_VOL: mix reg 0x%02x=0x%02x\n", 269 0x1A, ess_read_mix_reg(sc, 0x1A)); 270 printf("ESS_LINE_PLAY_VOL: mix reg 0x%02x=0x%02x\n", 271 0x3E, ess_read_mix_reg(sc, 0x3E)); 272 printf("ESS_SYNTH_PLAY_VOL: mix reg 0x%02x=0x%02x\n", 273 0x36, ess_read_mix_reg(sc, 0x36)); 274 printf("ESS_CD_PLAY_VOL: mix reg 0x%02x=0x%02x\n", 275 0x38, ess_read_mix_reg(sc, 0x38)); 276 printf("ESS_AUXB_PLAY_VOL: mix reg 0x%02x=0x%02x\n", 277 0x3A, ess_read_mix_reg(sc, 0x3A)); 278 printf("ESS_MASTER_VOL: mix reg 0x%02x=0x%02x\n", 279 0x32, ess_read_mix_reg(sc, 0x32)); 280 printf("ESS_PCSPEAKER_VOL: mix reg 0x%02x=0x%02x\n", 281 0x3C, ess_read_mix_reg(sc, 0x3C)); 282 printf("ESS_DAC_REC_VOL: mix reg 0x%02x=0x%02x\n", 283 0x69, ess_read_mix_reg(sc, 0x69)); 284 printf("ESS_MIC_REC_VOL: mix reg 0x%02x=0x%02x\n", 285 0x68, ess_read_mix_reg(sc, 0x68)); 286 printf("ESS_LINE_REC_VOL: mix reg 0x%02x=0x%02x\n", 287 0x6E, ess_read_mix_reg(sc, 0x6E)); 288 printf("ESS_SYNTH_REC_VOL: mix reg 0x%02x=0x%02x\n", 289 0x6B, ess_read_mix_reg(sc, 0x6B)); 290 printf("ESS_CD_REC_VOL: mix reg 0x%02x=0x%02x\n", 291 0x6A, ess_read_mix_reg(sc, 0x6A)); 292 printf("ESS_AUXB_REC_VOL: mix reg 0x%02x=0x%02x\n", 293 0x6C, ess_read_mix_reg(sc, 0x6C)); 294 printf("ESS_RECORD_VOL: x reg 0x%02x=0x%02x\n", 295 0xB4, ess_read_x_reg(sc, 0xB4)); 296 printf("Audio 1 play vol (unused): mix reg 0x%02x=0x%02x\n", 297 0x14, ess_read_mix_reg(sc, 0x14)); 298 299 printf("ESS_MIC_PREAMP: x reg 0x%02x=0x%02x\n", 300 ESS_XCMD_PREAMP_CTRL, ess_read_x_reg(sc, ESS_XCMD_PREAMP_CTRL)); 301 printf("ESS_RECORD_MONITOR: x reg 0x%02x=0x%02x\n", 302 ESS_XCMD_AUDIO_CTRL, ess_read_x_reg(sc, ESS_XCMD_AUDIO_CTRL)); 303 printf("Record source: mix reg 0x%02x=0x%02x, 0x%02x=0x%02x\n", 304 ESS_MREG_ADC_SOURCE, ess_read_mix_reg(sc, ESS_MREG_ADC_SOURCE), 305 ESS_MREG_AUDIO2_CTRL2, ess_read_mix_reg(sc, ESS_MREG_AUDIO2_CTRL2)); 306 } 307 308 #endif 309 310 /* 311 * Configure the ESS chip for the desired audio base address. 312 */ 313 int 314 ess_config_addr(struct ess_softc *sc) 315 { 316 int iobase = sc->sc_iobase; 317 bus_space_tag_t iot = sc->sc_iot; 318 319 /* 320 * Configure using the System Control Register method. This 321 * method is used when the AMODE line is tied high, which is 322 * the case for the Shark, but not for the evaluation board. 323 */ 324 325 bus_space_handle_t scr_access_ioh; 326 bus_space_handle_t scr_ioh; 327 u_short scr_value; 328 329 /* 330 * Set the SCR bit to enable audio. 331 */ 332 scr_value = ESS_SCR_AUDIO_ENABLE; 333 334 /* 335 * Set the SCR bits necessary to select the specified audio 336 * base address. 337 */ 338 switch(iobase) { 339 case 0x220: 340 scr_value |= ESS_SCR_AUDIO_220; 341 break; 342 case 0x230: 343 scr_value |= ESS_SCR_AUDIO_230; 344 break; 345 case 0x240: 346 scr_value |= ESS_SCR_AUDIO_240; 347 break; 348 case 0x250: 349 scr_value |= ESS_SCR_AUDIO_250; 350 break; 351 default: 352 printf("ess: configured iobase 0x%x invalid\n", iobase); 353 return (1); 354 break; 355 } 356 357 /* 358 * Get a mapping for the System Control Register (SCR) access 359 * registers and the SCR data registers. 360 */ 361 if (bus_space_map(iot, ESS_SCR_ACCESS_BASE, ESS_SCR_ACCESS_PORTS, 362 0, &scr_access_ioh)) { 363 printf("ess: can't map SCR access registers\n"); 364 return (1); 365 } 366 if (bus_space_map(iot, ESS_SCR_BASE, ESS_SCR_PORTS, 367 0, &scr_ioh)) { 368 printf("ess: can't map SCR registers\n"); 369 bus_space_unmap(iot, scr_access_ioh, ESS_SCR_ACCESS_PORTS); 370 return (1); 371 } 372 373 /* Unlock the SCR. */ 374 EWRITE1(iot, scr_access_ioh, ESS_SCR_UNLOCK, 0); 375 376 /* Write the base address information into SCR[0]. */ 377 EWRITE1(iot, scr_ioh, ESS_SCR_INDEX, 0); 378 EWRITE1(iot, scr_ioh, ESS_SCR_DATA, scr_value); 379 380 /* Lock the SCR. */ 381 EWRITE1(iot, scr_access_ioh, ESS_SCR_LOCK, 0); 382 383 /* Unmap the SCR access ports and the SCR data ports. */ 384 bus_space_unmap(iot, scr_access_ioh, ESS_SCR_ACCESS_PORTS); 385 bus_space_unmap(iot, scr_ioh, ESS_SCR_PORTS); 386 387 return 0; 388 } 389 390 391 /* 392 * Configure the ESS chip for the desired IRQ and DMA channels. 393 * ESS ISA 394 * -------- 395 * IRQA irq9 396 * IRQB irq5 397 * IRQC irq7 398 * IRQD irq10 399 * IRQE irq15 400 * 401 * DRQA drq0 402 * DRQB drq1 403 * DRQC drq3 404 * DRQD drq5 405 */ 406 void 407 ess_config_irq(struct ess_softc *sc) 408 { 409 int v; 410 411 DPRINTFN(2,("ess_config_irq\n")); 412 413 if (sc->sc_model == ESS_1887 && 414 sc->sc_audio1.irq == sc->sc_audio2.irq && 415 sc->sc_audio1.irq != -1) { 416 /* Use new method, both interrupts are the same. */ 417 v = ESS_IS_SELECT_IRQ; /* enable intrs */ 418 switch (sc->sc_audio1.irq) { 419 case 5: 420 v |= ESS_IS_INTRB; 421 break; 422 case 7: 423 v |= ESS_IS_INTRC; 424 break; 425 case 9: 426 v |= ESS_IS_INTRA; 427 break; 428 case 10: 429 v |= ESS_IS_INTRD; 430 break; 431 case 15: 432 v |= ESS_IS_INTRE; 433 break; 434 #ifdef DIAGNOSTIC 435 default: 436 printf("ess_config_irq: configured irq %d not supported for Audio 1\n", 437 sc->sc_audio1.irq); 438 return; 439 #endif 440 } 441 /* Set the IRQ */ 442 ess_write_mix_reg(sc, ESS_MREG_INTR_ST, v); 443 return; 444 } 445 446 if (sc->sc_model == ESS_1887) { 447 /* Tell the 1887 to use the old interrupt method. */ 448 ess_write_mix_reg(sc, ESS_MREG_INTR_ST, ESS_IS_ES1888); 449 } 450 451 if (sc->sc_audio1.polled) { 452 /* Turn off Audio1 interrupts. */ 453 v = 0; 454 } else { 455 /* Configure Audio 1 for the appropriate IRQ line. */ 456 v = ESS_IRQ_CTRL_MASK | ESS_IRQ_CTRL_EXT; /* All intrs on */ 457 switch (sc->sc_audio1.irq) { 458 case 5: 459 v |= ESS_IRQ_CTRL_INTRB; 460 break; 461 case 7: 462 v |= ESS_IRQ_CTRL_INTRC; 463 break; 464 case 9: 465 v |= ESS_IRQ_CTRL_INTRA; 466 break; 467 case 10: 468 v |= ESS_IRQ_CTRL_INTRD; 469 break; 470 #ifdef DIAGNOSTIC 471 default: 472 printf("ess: configured irq %d not supported for Audio 1\n", 473 sc->sc_audio1.irq); 474 return; 475 #endif 476 } 477 } 478 ess_write_x_reg(sc, ESS_XCMD_IRQ_CTRL, v); 479 480 if (ESS_USE_AUDIO1(sc->sc_model)) 481 return; 482 483 if (sc->sc_audio2.polled) { 484 /* Turn off Audio2 interrupts. */ 485 ess_clear_mreg_bits(sc, ESS_MREG_AUDIO2_CTRL2, 486 ESS_AUDIO2_CTRL2_IRQ2_ENABLE); 487 } else { 488 /* Audio2 is hardwired to INTRE in this mode. */ 489 ess_set_mreg_bits(sc, ESS_MREG_AUDIO2_CTRL2, 490 ESS_AUDIO2_CTRL2_IRQ2_ENABLE); 491 } 492 } 493 494 495 void 496 ess_config_drq(struct ess_softc *sc) 497 { 498 int v; 499 500 DPRINTFN(2,("ess_config_drq\n")); 501 502 /* Configure Audio 1 (record) for DMA on the appropriate channel. */ 503 v = ESS_DRQ_CTRL_PU | ESS_DRQ_CTRL_EXT; 504 switch (sc->sc_audio1.drq) { 505 case 0: 506 v |= ESS_DRQ_CTRL_DRQA; 507 break; 508 case 1: 509 v |= ESS_DRQ_CTRL_DRQB; 510 break; 511 case 3: 512 v |= ESS_DRQ_CTRL_DRQC; 513 break; 514 #ifdef DIAGNOSTIC 515 default: 516 printf("ess_config_drq: configured dma chan %d not supported for Audio 1\n", 517 sc->sc_audio1.drq); 518 return; 519 #endif 520 } 521 /* Set DRQ1 */ 522 ess_write_x_reg(sc, ESS_XCMD_DRQ_CTRL, v); 523 524 if (ESS_USE_AUDIO1(sc->sc_model)) 525 return; 526 527 /* Configure DRQ2 */ 528 v = ESS_AUDIO2_CTRL3_DRQ_PD; 529 switch (sc->sc_audio2.drq) { 530 case 0: 531 v |= ESS_AUDIO2_CTRL3_DRQA; 532 break; 533 case 1: 534 v |= ESS_AUDIO2_CTRL3_DRQB; 535 break; 536 case 3: 537 v |= ESS_AUDIO2_CTRL3_DRQC; 538 break; 539 case 5: 540 v |= ESS_AUDIO2_CTRL3_DRQD; 541 break; 542 #ifdef DIAGNOSTIC 543 default: 544 printf("ess_config_drq: configured dma chan %d not supported for Audio 2\n", 545 sc->sc_audio2.drq); 546 return; 547 #endif 548 } 549 ess_write_mix_reg(sc, ESS_MREG_AUDIO2_CTRL3, v); 550 /* Enable DMA 2 */ 551 ess_set_mreg_bits(sc, ESS_MREG_AUDIO2_CTRL2, 552 ESS_AUDIO2_CTRL2_DMA_ENABLE); 553 } 554 555 /* 556 * Set up registers after a reset. 557 */ 558 void 559 ess_setup(struct ess_softc *sc) 560 { 561 ess_config_irq(sc); 562 ess_config_drq(sc); 563 564 DPRINTFN(2,("ess_setup: done\n")); 565 } 566 567 /* 568 * Determine the model of ESS chip we are talking to. Currently we 569 * only support ES1888, ES1887 and ES888. The method of determining 570 * the chip is based on the information on page 27 of the ES1887 data 571 * sheet. 572 * 573 * This routine sets the values of sc->sc_model and sc->sc_version. 574 */ 575 int 576 ess_identify(struct ess_softc *sc) 577 { 578 u_char reg1; 579 u_char reg2; 580 u_char reg3; 581 u_int8_t ident[4]; 582 583 sc->sc_model = ESS_UNSUPPORTED; 584 sc->sc_version = 0; 585 586 memset(ident, 0, sizeof(ident)); 587 588 /* 589 * 1. Check legacy ID bytes. These should be 0x68 0x8n, where 590 * n >= 8 for an ES1887 or an ES888. Other values indicate 591 * earlier (unsupported) chips. 592 */ 593 ess_wdsp(sc, ESS_ACMD_LEGACY_ID); 594 595 if ((reg1 = ess_rdsp(sc)) != 0x68) { 596 printf("ess: First ID byte wrong (0x%02x)\n", reg1); 597 return 1; 598 } 599 600 reg2 = ess_rdsp(sc); 601 if (((reg2 & 0xf0) != 0x80) || 602 ((reg2 & 0x0f) < 8)) { 603 printf("ess: Second ID byte wrong (0x%02x)\n", reg2); 604 return 1; 605 } 606 607 /* 608 * Store the ID bytes as the version. 609 */ 610 sc->sc_version = (reg1 << 8) + reg2; 611 612 613 /* 614 * 2. Verify we can change bit 2 in mixer register 0x64. This 615 * should be possible on all supported chips. 616 */ 617 reg1 = ess_read_mix_reg(sc, ESS_MREG_VOLUME_CTRL); 618 reg2 = reg1 ^ 0x04; /* toggle bit 2 */ 619 620 ess_write_mix_reg(sc, ESS_MREG_VOLUME_CTRL, reg2); 621 622 if (ess_read_mix_reg(sc, ESS_MREG_VOLUME_CTRL) != reg2) { 623 printf("ess: Hardware error (unable to toggle bit 2 of mixer register 0x64)\n"); 624 return 1; 625 } 626 627 /* 628 * Restore the original value of mixer register 0x64. 629 */ 630 ess_write_mix_reg(sc, ESS_MREG_VOLUME_CTRL, reg1); 631 632 633 /* 634 * 3. Verify we can change the value of mixer register 635 * ESS_MREG_SAMPLE_RATE. 636 * This is possible on the 1888/1887/888, but not on the 1788. 637 * It is not necessary to restore the value of this mixer register. 638 */ 639 reg1 = ess_read_mix_reg(sc, ESS_MREG_SAMPLE_RATE); 640 reg2 = reg1 ^ 0xff; /* toggle all bits */ 641 642 ess_write_mix_reg(sc, ESS_MREG_SAMPLE_RATE, reg2); 643 644 if (ess_read_mix_reg(sc, ESS_MREG_SAMPLE_RATE) != reg2) { 645 /* If we got this far before failing, it's a 1788. */ 646 sc->sc_model = ESS_1788; 647 648 /* 649 * Identify ESS model for ES18[67]8. 650 */ 651 ess_read_multi_mix_reg(sc, 0x40, ident, sizeof(ident)); 652 if(ident[0] == 0x18) { 653 switch(ident[1]) { 654 case 0x68: 655 sc->sc_model = ESS_1868; 656 break; 657 case 0x78: 658 sc->sc_model = ESS_1878; 659 break; 660 } 661 } 662 } else { 663 /* 664 * 4. Determine if we can change bit 5 in mixer register 0x64. 665 * This determines whether we have an ES1887: 666 * 667 * - can change indicates ES1887 668 * - can't change indicates ES1888 or ES888 669 */ 670 reg1 = ess_read_mix_reg(sc, ESS_MREG_VOLUME_CTRL); 671 reg2 = reg1 ^ 0x20; /* toggle bit 5 */ 672 673 ess_write_mix_reg(sc, ESS_MREG_VOLUME_CTRL, reg2); 674 675 if (ess_read_mix_reg(sc, ESS_MREG_VOLUME_CTRL) == reg2) { 676 sc->sc_model = ESS_1887; 677 678 /* 679 * Restore the original value of mixer register 0x64. 680 */ 681 ess_write_mix_reg(sc, ESS_MREG_VOLUME_CTRL, reg1); 682 683 /* 684 * Identify ESS model for ES18[67]9. 685 */ 686 ess_read_multi_mix_reg(sc, 0x40, ident, sizeof(ident)); 687 if(ident[0] == 0x18) { 688 switch(ident[1]) { 689 case 0x69: 690 sc->sc_model = ESS_1869; 691 break; 692 case 0x79: 693 sc->sc_model = ESS_1879; 694 break; 695 } 696 } 697 } else { 698 /* 699 * 5. Determine if we can change the value of mixer 700 * register 0x69 independently of mixer register 701 * 0x68. This determines which chip we have: 702 * 703 * - can modify independently indicates ES888 704 * - register 0x69 is an alias of 0x68 indicates ES1888 705 */ 706 reg1 = ess_read_mix_reg(sc, 0x68); 707 reg2 = ess_read_mix_reg(sc, 0x69); 708 reg3 = reg2 ^ 0xff; /* toggle all bits */ 709 710 /* 711 * Write different values to each register. 712 */ 713 ess_write_mix_reg(sc, 0x68, reg2); 714 ess_write_mix_reg(sc, 0x69, reg3); 715 716 if (ess_read_mix_reg(sc, 0x68) == reg2 && 717 ess_read_mix_reg(sc, 0x69) == reg3) 718 sc->sc_model = ESS_888; 719 else 720 sc->sc_model = ESS_1888; 721 722 /* 723 * Restore the original value of the registers. 724 */ 725 ess_write_mix_reg(sc, 0x68, reg1); 726 ess_write_mix_reg(sc, 0x69, reg2); 727 } 728 } 729 730 return 0; 731 } 732 733 734 int 735 ess_setup_sc(struct ess_softc *sc, int doinit) 736 { 737 /* Reset the chip. */ 738 if (ess_reset(sc) != 0) { 739 DPRINTF(("ess_setup_sc: couldn't reset chip\n")); 740 return (1); 741 } 742 743 /* Identify the ESS chip, and check that it is supported. */ 744 if (ess_identify(sc)) { 745 DPRINTF(("ess_setup_sc: couldn't identify\n")); 746 return (1); 747 } 748 749 return (0); 750 } 751 752 /* 753 * Probe for the ESS hardware. 754 */ 755 int 756 essmatch(struct ess_softc *sc) 757 { 758 if (!ESS_BASE_VALID(sc->sc_iobase)) { 759 printf("ess: configured iobase 0x%x invalid\n", sc->sc_iobase); 760 return (0); 761 } 762 763 /* Configure the ESS chip for the desired audio base address. */ 764 if (ess_config_addr(sc)) 765 return (0); 766 767 if (ess_setup_sc(sc, 1)) 768 return (0); 769 770 if (sc->sc_model == ESS_UNSUPPORTED) { 771 DPRINTF(("ess: Unsupported model\n")); 772 return (0); 773 } 774 775 /* Check that requested DMA channels are valid and different. */ 776 if (!ESS_DRQ1_VALID(sc->sc_audio1.drq)) { 777 printf("ess: record drq %d invalid\n", sc->sc_audio1.drq); 778 return (0); 779 } 780 if (!isa_drq_isfree(sc->sc_isa, sc->sc_audio1.drq)) 781 return (0); 782 if (!ESS_USE_AUDIO1(sc->sc_model)) { 783 if (!ESS_DRQ2_VALID(sc->sc_audio2.drq)) { 784 printf("ess: play drq %d invalid\n", sc->sc_audio2.drq); 785 return (0); 786 } 787 if (sc->sc_audio1.drq == sc->sc_audio2.drq) { 788 printf("ess: play and record drq both %d\n", 789 sc->sc_audio1.drq); 790 return (0); 791 } 792 if (!isa_drq_isfree(sc->sc_isa, sc->sc_audio2.drq)) 793 return (0); 794 } 795 796 /* 797 * The 1887 has an additional IRQ mode where both channels are mapped 798 * to the same IRQ. 799 */ 800 if (sc->sc_model == ESS_1887 && 801 sc->sc_audio1.irq == sc->sc_audio2.irq && 802 sc->sc_audio1.irq != -1 && 803 ESS_IRQ12_VALID(sc->sc_audio1.irq)) 804 goto irq_not1888; 805 806 /* Check that requested IRQ lines are valid and different. */ 807 if (sc->sc_audio1.irq != -1 && 808 !ESS_IRQ1_VALID(sc->sc_audio1.irq)) { 809 printf("ess: record irq %d invalid\n", sc->sc_audio1.irq); 810 return (0); 811 } 812 if (!ESS_USE_AUDIO1(sc->sc_model)) { 813 if (sc->sc_audio2.irq != -1 && 814 !ESS_IRQ2_VALID(sc->sc_audio2.irq)) { 815 printf("ess: play irq %d invalid\n", sc->sc_audio2.irq); 816 return (0); 817 } 818 if (sc->sc_audio1.irq == sc->sc_audio2.irq && 819 sc->sc_audio1.irq != -1) { 820 printf("ess: play and record irq both %d\n", 821 sc->sc_audio1.irq); 822 return (0); 823 } 824 } 825 826 irq_not1888: 827 /* XXX should we check IRQs as well? */ 828 829 return (1); 830 } 831 832 833 /* 834 * Attach hardware to driver, attach hardware driver to audio 835 * pseudo-device driver. 836 */ 837 void 838 essattach(struct ess_softc *sc) 839 { 840 struct audio_attach_args arg; 841 struct audio_params pparams, rparams; 842 int i; 843 u_int v; 844 845 if (ess_setup_sc(sc, 0)) { 846 printf(": setup failed\n"); 847 return; 848 } 849 850 printf(": ESS Technology ES%s [version 0x%04x]\n", 851 essmodel[sc->sc_model], sc->sc_version); 852 853 sc->sc_audio1.polled = sc->sc_audio1.irq == -1; 854 if (!sc->sc_audio1.polled) { 855 sc->sc_audio1.ih = isa_intr_establish(sc->sc_ic, 856 sc->sc_audio1.irq, sc->sc_audio1.ist, 857 IPL_AUDIO | IPL_MPSAFE, 858 ess_audio1_intr, sc, sc->sc_dev.dv_xname); 859 printf("%s: audio1 interrupting at irq %d\n", 860 sc->sc_dev.dv_xname, sc->sc_audio1.irq); 861 } else 862 printf("%s: audio1 polled\n", sc->sc_dev.dv_xname); 863 if (isa_dmamap_create(sc->sc_isa, sc->sc_audio1.drq, 864 MAX_ISADMA, BUS_DMA_NOWAIT|BUS_DMA_ALLOCNOW)) { 865 printf("%s: can't create map for drq %d\n", 866 sc->sc_dev.dv_xname, sc->sc_audio1.drq); 867 return; 868 } 869 870 if (!ESS_USE_AUDIO1(sc->sc_model)) { 871 sc->sc_audio2.polled = sc->sc_audio2.irq == -1; 872 if (!sc->sc_audio2.polled) { 873 sc->sc_audio2.ih = isa_intr_establish(sc->sc_ic, 874 sc->sc_audio2.irq, sc->sc_audio2.ist, 875 IPL_AUDIO | IPL_MPSAFE, 876 ess_audio2_intr, sc, sc->sc_dev.dv_xname); 877 printf("%s: audio2 interrupting at irq %d\n", 878 sc->sc_dev.dv_xname, sc->sc_audio2.irq); 879 } else 880 printf("%s: audio2 polled\n", sc->sc_dev.dv_xname); 881 if (isa_dmamap_create(sc->sc_isa, sc->sc_audio2.drq, 882 MAX_ISADMA, BUS_DMA_NOWAIT|BUS_DMA_ALLOCNOW)) { 883 printf("%s: can't create map for drq %d\n", 884 sc->sc_dev.dv_xname, sc->sc_audio2.drq); 885 return; 886 } 887 } 888 889 timeout_set(&sc->sc_tmo1, ess_audio1_poll, sc); 890 timeout_set(&sc->sc_tmo2, ess_audio2_poll, sc); 891 892 /* 893 * Set record and play parameters to default values defined in 894 * generic audio driver. 895 */ 896 pparams = ess_audio_default; 897 rparams = ess_audio_default; 898 ess_set_params(sc, AUMODE_RECORD|AUMODE_PLAY, 0, &pparams, &rparams); 899 900 /* Do a hardware reset on the mixer. */ 901 ess_write_mix_reg(sc, ESS_MIX_RESET, ESS_MIX_RESET); 902 903 /* 904 * Set volume of Audio 1 to zero and disable Audio 1 DAC input 905 * to playback mixer, since playback is always through Audio 2. 906 */ 907 if (!ESS_USE_AUDIO1(sc->sc_model)) 908 ess_write_mix_reg(sc, ESS_MREG_VOLUME_VOICE, 0); 909 ess_wdsp(sc, ESS_ACMD_DISABLE_SPKR); 910 911 if (ESS_USE_AUDIO1(sc->sc_model)) { 912 ess_write_mix_reg(sc, ESS_MREG_ADC_SOURCE, ESS_SOURCE_MIC); 913 sc->in_port = ESS_SOURCE_MIC; 914 sc->ndevs = ESS_1788_NDEVS; 915 } else { 916 /* 917 * Set hardware record source to use output of the record 918 * mixer. We do the selection of record source in software by 919 * setting the gain of the unused sources to zero. (See 920 * ess_set_in_ports.) 921 */ 922 ess_write_mix_reg(sc, ESS_MREG_ADC_SOURCE, ESS_SOURCE_MIXER); 923 sc->in_mask = 1 << ESS_MIC_REC_VOL; 924 sc->ndevs = ESS_1888_NDEVS; 925 ess_clear_mreg_bits(sc, ESS_MREG_AUDIO2_CTRL2, 0x10); 926 ess_set_mreg_bits(sc, ESS_MREG_AUDIO2_CTRL2, 0x08); 927 } 928 929 /* 930 * Set gain on each mixer device to a sensible value. 931 * Devices not normally used are turned off, and other devices 932 * are set to 50% volume. 933 */ 934 for (i = 0; i < sc->ndevs; i++) { 935 switch (i) { 936 case ESS_MIC_PLAY_VOL: 937 case ESS_LINE_PLAY_VOL: 938 case ESS_CD_PLAY_VOL: 939 case ESS_AUXB_PLAY_VOL: 940 case ESS_DAC_REC_VOL: 941 case ESS_LINE_REC_VOL: 942 case ESS_SYNTH_REC_VOL: 943 case ESS_CD_REC_VOL: 944 case ESS_AUXB_REC_VOL: 945 v = 0; 946 break; 947 default: 948 v = ESS_4BIT_GAIN(AUDIO_MAX_GAIN / 2); 949 break; 950 } 951 sc->gain[i][ESS_LEFT] = sc->gain[i][ESS_RIGHT] = v; 952 ess_set_gain(sc, i, 1); 953 } 954 955 ess_setup(sc); 956 957 /* Disable the speaker until the device is opened. */ 958 ess_speaker_off(sc); 959 sc->spkr_state = SPKR_OFF; 960 961 if (ESS_USE_AUDIO1(sc->sc_model)) 962 audio_attach_mi(&ess_1788_hw_if, sc, NULL, &sc->sc_dev); 963 else 964 audio_attach_mi(&ess_1888_hw_if, sc, NULL, &sc->sc_dev); 965 966 arg.type = AUDIODEV_TYPE_OPL; 967 arg.hwif = 0; 968 arg.hdl = 0; 969 (void)config_found(&sc->sc_dev, &arg, audioprint); 970 971 #ifdef AUDIO_DEBUG 972 if (essdebug > 0) 973 ess_printsc(sc); 974 #endif 975 } 976 977 /* 978 * Various routines to interface to higher level audio driver 979 */ 980 981 int 982 ess_1788_open(void *addr, int flags) 983 { 984 if ((flags & (FWRITE | FREAD)) == (FWRITE | FREAD)) 985 return ENXIO; 986 987 return ess_open(addr, flags); 988 } 989 990 int 991 ess_open(void *addr, int flags) 992 { 993 struct ess_softc *sc = addr; 994 995 DPRINTF(("ess_open: sc=%p\n", sc)); 996 997 if (sc->sc_open != 0 || ess_reset(sc) != 0) 998 return ENXIO; 999 1000 ess_setup(sc); /* because we did a reset */ 1001 1002 ess_speaker_ctl(sc, (flags & FWRITE) ? SPKR_ON : SPKR_OFF); 1003 1004 sc->sc_open = 1; 1005 1006 DPRINTF(("ess_open: opened\n")); 1007 1008 return (0); 1009 } 1010 1011 void 1012 ess_1788_close(void *addr) 1013 { 1014 struct ess_softc *sc = addr; 1015 1016 DPRINTF(("ess_1788_close: sc=%p\n", sc)); 1017 1018 ess_speaker_off(sc); 1019 sc->spkr_state = SPKR_OFF; 1020 1021 ess_audio1_halt(sc); 1022 1023 sc->sc_open = 0; 1024 DPRINTF(("ess_1788_close: closed\n")); 1025 } 1026 1027 void 1028 ess_1888_close(void *addr) 1029 { 1030 struct ess_softc *sc = addr; 1031 1032 DPRINTF(("ess_1888_close: sc=%p\n", sc)); 1033 1034 ess_speaker_off(sc); 1035 sc->spkr_state = SPKR_OFF; 1036 1037 ess_audio1_halt(sc); 1038 ess_audio2_halt(sc); 1039 1040 sc->sc_open = 0; 1041 DPRINTF(("ess_1888_close: closed\n")); 1042 } 1043 1044 /* XXX should use reference count */ 1045 int 1046 ess_speaker_ctl(void *addr, int newstate) 1047 { 1048 struct ess_softc *sc = addr; 1049 1050 if ((newstate == SPKR_ON) && (sc->spkr_state == SPKR_OFF)) { 1051 ess_speaker_on(sc); 1052 sc->spkr_state = SPKR_ON; 1053 } 1054 if ((newstate == SPKR_OFF) && (sc->spkr_state == SPKR_ON)) { 1055 ess_speaker_off(sc); 1056 sc->spkr_state = SPKR_OFF; 1057 } 1058 return (0); 1059 } 1060 1061 int 1062 ess_set_params(void *addr, int setmode, int usemode, 1063 struct audio_params *play, struct audio_params *rec) 1064 { 1065 struct ess_softc *sc = addr; 1066 struct audio_params *p; 1067 int mode; 1068 int rate; 1069 1070 DPRINTF(("ess_set_params: set=%d use=%d\n", setmode, usemode)); 1071 1072 /* 1073 * The ES1887 manual (page 39, `Full-Duplex DMA Mode') claims that in 1074 * full-duplex operation the sample rates must be the same for both 1075 * channels. This appears to be false; the only bit in common is the 1076 * clock source selection. However, we'll be conservative here. 1077 * - mycroft 1078 */ 1079 if (play->sample_rate != rec->sample_rate && 1080 usemode == (AUMODE_PLAY | AUMODE_RECORD)) { 1081 if (setmode == AUMODE_PLAY) { 1082 rec->sample_rate = play->sample_rate; 1083 setmode |= AUMODE_RECORD; 1084 } else if (setmode == AUMODE_RECORD) { 1085 play->sample_rate = rec->sample_rate; 1086 setmode |= AUMODE_PLAY; 1087 } else 1088 return (EINVAL); 1089 } 1090 1091 for (mode = AUMODE_RECORD; mode != -1; 1092 mode = mode == AUMODE_RECORD ? AUMODE_PLAY : -1) { 1093 if ((setmode & mode) == 0) 1094 continue; 1095 1096 p = mode == AUMODE_PLAY ? play : rec; 1097 1098 if (p->sample_rate < ESS_MINRATE) 1099 p->sample_rate = ESS_MINRATE; 1100 if (p->sample_rate > ESS_MAXRATE) 1101 p->sample_rate = ESS_MAXRATE; 1102 if (p->precision > 16) 1103 p->precision = 16; 1104 if (p->channels > 2) 1105 p->channels = 2; 1106 1107 switch (p->encoding) { 1108 case AUDIO_ENCODING_SLINEAR_BE: 1109 case AUDIO_ENCODING_ULINEAR_BE: 1110 if (p->precision != 8) 1111 return EINVAL; 1112 break; 1113 case AUDIO_ENCODING_SLINEAR_LE: 1114 case AUDIO_ENCODING_ULINEAR_LE: 1115 break; 1116 default: 1117 return (EINVAL); 1118 } 1119 p->bps = AUDIO_BPS(p->precision); 1120 p->msb = 1; 1121 } 1122 1123 if (usemode == AUMODE_RECORD) 1124 rate = rec->sample_rate; 1125 else 1126 rate = play->sample_rate; 1127 1128 ess_write_x_reg(sc, ESS_XCMD_SAMPLE_RATE, ess_srtotc(rate)); 1129 ess_write_x_reg(sc, ESS_XCMD_FILTER_CLOCK, ess_srtofc(rate)); 1130 1131 if (!ESS_USE_AUDIO1(sc->sc_model)) { 1132 ess_write_mix_reg(sc, ESS_MREG_SAMPLE_RATE, ess_srtotc(rate)); 1133 ess_write_mix_reg(sc, ESS_MREG_FILTER_CLOCK, ess_srtofc(rate)); 1134 } 1135 1136 return (0); 1137 } 1138 1139 int 1140 ess_audio1_trigger_output(void *addr, void *start, void *end, int blksize, 1141 void (*intr)(void *), void *arg, struct audio_params *param) 1142 { 1143 struct ess_softc *sc = addr; 1144 u_int8_t reg; 1145 1146 mtx_enter(&audio_lock); 1147 DPRINTFN(1, ("ess_audio1_trigger_output: sc=%p start=%p end=%p blksize=%d intr=%p(%p)\n", 1148 addr, start, end, blksize, intr, arg)); 1149 1150 if (sc->sc_audio1.active) 1151 panic("ess_audio1_trigger_output: already running"); 1152 1153 sc->sc_audio1.active = 1; 1154 sc->sc_audio1.intr = intr; 1155 sc->sc_audio1.arg = arg; 1156 if (sc->sc_audio1.polled) { 1157 sc->sc_audio1.dmapos = 0; 1158 sc->sc_audio1.buffersize = (char *)end - (char *)start; 1159 sc->sc_audio1.dmacount = 0; 1160 sc->sc_audio1.blksize = blksize; 1161 timeout_add_msec(&sc->sc_tmo1, 1000/30); 1162 } 1163 1164 reg = ess_read_x_reg(sc, ESS_XCMD_AUDIO_CTRL); 1165 if (param->channels == 2) { 1166 reg &= ~ESS_AUDIO_CTRL_MONO; 1167 reg |= ESS_AUDIO_CTRL_STEREO; 1168 } else { 1169 reg |= ESS_AUDIO_CTRL_MONO; 1170 reg &= ~ESS_AUDIO_CTRL_STEREO; 1171 } 1172 ess_write_x_reg(sc, ESS_XCMD_AUDIO_CTRL, reg); 1173 1174 reg = ess_read_x_reg(sc, ESS_XCMD_AUDIO1_CTRL1); 1175 if (param->precision == 16) 1176 reg |= ESS_AUDIO1_CTRL1_FIFO_SIZE; 1177 else 1178 reg &= ~ESS_AUDIO1_CTRL1_FIFO_SIZE; 1179 if (param->channels == 2) 1180 reg |= ESS_AUDIO1_CTRL1_FIFO_STEREO; 1181 else 1182 reg &= ~ESS_AUDIO1_CTRL1_FIFO_STEREO; 1183 if (param->encoding == AUDIO_ENCODING_SLINEAR_BE || 1184 param->encoding == AUDIO_ENCODING_SLINEAR_LE) 1185 reg |= ESS_AUDIO1_CTRL1_FIFO_SIGNED; 1186 else 1187 reg &= ~ESS_AUDIO1_CTRL1_FIFO_SIGNED; 1188 reg |= ESS_AUDIO1_CTRL1_FIFO_CONNECT; 1189 ess_write_x_reg(sc, ESS_XCMD_AUDIO1_CTRL1, reg); 1190 1191 isa_dmastart(sc->sc_isa, sc->sc_audio1.drq, start, 1192 (char *)end - (char *)start, NULL, 1193 DMAMODE_WRITE | DMAMODE_LOOP, BUS_DMA_NOWAIT); 1194 1195 /* Program transfer count registers with 2's complement of count. */ 1196 blksize = -blksize; 1197 ess_write_x_reg(sc, ESS_XCMD_XFER_COUNTLO, blksize); 1198 ess_write_x_reg(sc, ESS_XCMD_XFER_COUNTHI, blksize >> 8); 1199 1200 /* Use 4 bytes per output DMA. */ 1201 ess_set_xreg_bits(sc, ESS_XCMD_DEMAND_CTRL, ESS_DEMAND_CTRL_DEMAND_4); 1202 1203 /* Start auto-init DMA */ 1204 ess_wdsp(sc, ESS_ACMD_ENABLE_SPKR); 1205 reg = ess_read_x_reg(sc, ESS_XCMD_AUDIO1_CTRL2); 1206 reg &= ~(ESS_AUDIO1_CTRL2_DMA_READ | ESS_AUDIO1_CTRL2_ADC_ENABLE); 1207 reg |= ESS_AUDIO1_CTRL2_FIFO_ENABLE | ESS_AUDIO1_CTRL2_AUTO_INIT; 1208 ess_write_x_reg(sc, ESS_XCMD_AUDIO1_CTRL2, reg); 1209 mtx_leave(&audio_lock); 1210 return (0); 1211 } 1212 1213 int 1214 ess_audio2_trigger_output(void *addr, void *start, void *end, int blksize, 1215 void (*intr)(void *), void *arg, struct audio_params *param) 1216 { 1217 struct ess_softc *sc = addr; 1218 u_int8_t reg; 1219 1220 mtx_enter(&audio_lock); 1221 DPRINTFN(1, ("ess_audio2_trigger_output: sc=%p start=%p end=%p blksize=%d intr=%p(%p)\n", 1222 addr, start, end, blksize, intr, arg)); 1223 1224 if (sc->sc_audio2.active) 1225 panic("ess_audio2_trigger_output: already running"); 1226 1227 sc->sc_audio2.active = 1; 1228 sc->sc_audio2.intr = intr; 1229 sc->sc_audio2.arg = arg; 1230 if (sc->sc_audio2.polled) { 1231 sc->sc_audio2.dmapos = 0; 1232 sc->sc_audio2.buffersize = (char *)end - (char *)start; 1233 sc->sc_audio2.dmacount = 0; 1234 sc->sc_audio2.blksize = blksize; 1235 timeout_add_msec(&sc->sc_tmo2, 1000/30); 1236 } 1237 1238 reg = ess_read_mix_reg(sc, ESS_MREG_AUDIO2_CTRL2); 1239 if (param->precision == 16) 1240 reg |= ESS_AUDIO2_CTRL2_FIFO_SIZE; 1241 else 1242 reg &= ~ESS_AUDIO2_CTRL2_FIFO_SIZE; 1243 if (param->channels == 2) 1244 reg |= ESS_AUDIO2_CTRL2_CHANNELS; 1245 else 1246 reg &= ~ESS_AUDIO2_CTRL2_CHANNELS; 1247 if (param->encoding == AUDIO_ENCODING_SLINEAR_BE || 1248 param->encoding == AUDIO_ENCODING_SLINEAR_LE) 1249 reg |= ESS_AUDIO2_CTRL2_FIFO_SIGNED; 1250 else 1251 reg &= ~ESS_AUDIO2_CTRL2_FIFO_SIGNED; 1252 ess_write_mix_reg(sc, ESS_MREG_AUDIO2_CTRL2, reg); 1253 1254 isa_dmastart(sc->sc_isa, sc->sc_audio2.drq, start, 1255 (char *)end - (char *)start, NULL, 1256 DMAMODE_WRITE | DMAMODE_LOOP, BUS_DMA_NOWAIT); 1257 1258 if (IS16BITDRQ(sc->sc_audio2.drq)) 1259 blksize >>= 1; /* use word count for 16 bit DMA */ 1260 /* Program transfer count registers with 2's complement of count. */ 1261 blksize = -blksize; 1262 ess_write_mix_reg(sc, ESS_MREG_XFER_COUNTLO, blksize); 1263 ess_write_mix_reg(sc, ESS_MREG_XFER_COUNTHI, blksize >> 8); 1264 1265 reg = ess_read_mix_reg(sc, ESS_MREG_AUDIO2_CTRL1); 1266 if (IS16BITDRQ(sc->sc_audio2.drq)) 1267 reg |= ESS_AUDIO2_CTRL1_XFER_SIZE; 1268 else 1269 reg &= ~ESS_AUDIO2_CTRL1_XFER_SIZE; 1270 reg |= ESS_AUDIO2_CTRL1_DEMAND_8; 1271 reg |= ESS_AUDIO2_CTRL1_DAC_ENABLE | ESS_AUDIO2_CTRL1_FIFO_ENABLE | 1272 ESS_AUDIO2_CTRL1_AUTO_INIT; 1273 ess_write_mix_reg(sc, ESS_MREG_AUDIO2_CTRL1, reg); 1274 mtx_leave(&audio_lock); 1275 return (0); 1276 } 1277 1278 int 1279 ess_audio1_trigger_input(void *addr, void *start, void *end, int blksize, 1280 void (*intr)(void *), void *arg, struct audio_params *param) 1281 { 1282 struct ess_softc *sc = addr; 1283 u_int8_t reg; 1284 1285 mtx_enter(&audio_lock); 1286 DPRINTFN(1, ("ess_audio1_trigger_input: sc=%p start=%p end=%p blksize=%d intr=%p(%p)\n", 1287 addr, start, end, blksize, intr, arg)); 1288 1289 if (sc->sc_audio1.active) 1290 panic("ess_audio1_trigger_input: already running"); 1291 1292 sc->sc_audio1.active = 1; 1293 sc->sc_audio1.intr = intr; 1294 sc->sc_audio1.arg = arg; 1295 if (sc->sc_audio1.polled) { 1296 sc->sc_audio1.dmapos = 0; 1297 sc->sc_audio1.buffersize = (char *)end - (char *)start; 1298 sc->sc_audio1.dmacount = 0; 1299 sc->sc_audio1.blksize = blksize; 1300 timeout_add_msec(&sc->sc_tmo1, 1000/30); 1301 } 1302 1303 reg = ess_read_x_reg(sc, ESS_XCMD_AUDIO_CTRL); 1304 if (param->channels == 2) { 1305 reg &= ~ESS_AUDIO_CTRL_MONO; 1306 reg |= ESS_AUDIO_CTRL_STEREO; 1307 } else { 1308 reg |= ESS_AUDIO_CTRL_MONO; 1309 reg &= ~ESS_AUDIO_CTRL_STEREO; 1310 } 1311 ess_write_x_reg(sc, ESS_XCMD_AUDIO_CTRL, reg); 1312 1313 reg = ess_read_x_reg(sc, ESS_XCMD_AUDIO1_CTRL1); 1314 if (param->precision == 16) 1315 reg |= ESS_AUDIO1_CTRL1_FIFO_SIZE; 1316 else 1317 reg &= ~ESS_AUDIO1_CTRL1_FIFO_SIZE; 1318 if (param->channels == 2) 1319 reg |= ESS_AUDIO1_CTRL1_FIFO_STEREO; 1320 else 1321 reg &= ~ESS_AUDIO1_CTRL1_FIFO_STEREO; 1322 if (param->encoding == AUDIO_ENCODING_SLINEAR_BE || 1323 param->encoding == AUDIO_ENCODING_SLINEAR_LE) 1324 reg |= ESS_AUDIO1_CTRL1_FIFO_SIGNED; 1325 else 1326 reg &= ~ESS_AUDIO1_CTRL1_FIFO_SIGNED; 1327 reg |= ESS_AUDIO1_CTRL1_FIFO_CONNECT; 1328 ess_write_x_reg(sc, ESS_XCMD_AUDIO1_CTRL1, reg); 1329 1330 isa_dmastart(sc->sc_isa, sc->sc_audio1.drq, start, 1331 (char *)end - (char *)start, NULL, 1332 DMAMODE_READ | DMAMODE_LOOP, BUS_DMA_NOWAIT); 1333 1334 /* Program transfer count registers with 2's complement of count. */ 1335 blksize = -blksize; 1336 ess_write_x_reg(sc, ESS_XCMD_XFER_COUNTLO, blksize); 1337 ess_write_x_reg(sc, ESS_XCMD_XFER_COUNTHI, blksize >> 8); 1338 1339 /* Use 4 bytes per input DMA. */ 1340 ess_set_xreg_bits(sc, ESS_XCMD_DEMAND_CTRL, ESS_DEMAND_CTRL_DEMAND_4); 1341 1342 /* Start auto-init DMA */ 1343 ess_wdsp(sc, ESS_ACMD_DISABLE_SPKR); 1344 reg = ess_read_x_reg(sc, ESS_XCMD_AUDIO1_CTRL2); 1345 reg |= ESS_AUDIO1_CTRL2_DMA_READ | ESS_AUDIO1_CTRL2_ADC_ENABLE; 1346 reg |= ESS_AUDIO1_CTRL2_FIFO_ENABLE | ESS_AUDIO1_CTRL2_AUTO_INIT; 1347 ess_write_x_reg(sc, ESS_XCMD_AUDIO1_CTRL2, reg); 1348 mtx_leave(&audio_lock); 1349 return (0); 1350 } 1351 1352 int 1353 ess_audio1_halt(void *addr) 1354 { 1355 struct ess_softc *sc = addr; 1356 1357 DPRINTF(("ess_audio1_halt: sc=%p\n", sc)); 1358 mtx_enter(&audio_lock); 1359 if (sc->sc_audio1.active) { 1360 ess_clear_xreg_bits(sc, ESS_XCMD_AUDIO1_CTRL2, 1361 ESS_AUDIO1_CTRL2_FIFO_ENABLE); 1362 isa_dmaabort(sc->sc_isa, sc->sc_audio1.drq); 1363 if (sc->sc_audio1.polled) 1364 timeout_del(&sc->sc_tmo1); 1365 sc->sc_audio1.active = 0; 1366 } 1367 mtx_leave(&audio_lock); 1368 return (0); 1369 } 1370 1371 int 1372 ess_audio2_halt(void *addr) 1373 { 1374 struct ess_softc *sc = addr; 1375 1376 DPRINTF(("ess_audio2_halt: sc=%p\n", sc)); 1377 mtx_enter(&audio_lock); 1378 if (sc->sc_audio2.active) { 1379 ess_clear_mreg_bits(sc, ESS_MREG_AUDIO2_CTRL1, 1380 ESS_AUDIO2_CTRL1_DAC_ENABLE | 1381 ESS_AUDIO2_CTRL1_FIFO_ENABLE); 1382 isa_dmaabort(sc->sc_isa, sc->sc_audio2.drq); 1383 if (sc->sc_audio2.polled) 1384 timeout_del(&sc->sc_tmo2); 1385 sc->sc_audio2.active = 0; 1386 } 1387 mtx_leave(&audio_lock); 1388 return (0); 1389 } 1390 1391 int 1392 ess_audio1_intr(void *arg) 1393 { 1394 struct ess_softc *sc = arg; 1395 u_int8_t reg; 1396 1397 DPRINTFN(1,("ess_audio1_intr: intr=%p\n", sc->sc_audio1.intr)); 1398 1399 mtx_enter(&audio_lock); 1400 /* Check and clear interrupt on Audio1. */ 1401 reg = EREAD1(sc->sc_iot, sc->sc_ioh, ESS_DSP_RW_STATUS); 1402 if ((reg & ESS_DSP_READ_OFLOW) == 0) { 1403 mtx_leave(&audio_lock); 1404 return (0); 1405 } 1406 reg = EREAD1(sc->sc_iot, sc->sc_ioh, ESS_CLEAR_INTR); 1407 1408 sc->sc_audio1.nintr++; 1409 1410 if (sc->sc_audio1.active) { 1411 (*sc->sc_audio1.intr)(sc->sc_audio1.arg); 1412 mtx_leave(&audio_lock); 1413 return (1); 1414 } else { 1415 mtx_leave(&audio_lock); 1416 return (0); 1417 } 1418 } 1419 1420 int 1421 ess_audio2_intr(void *arg) 1422 { 1423 struct ess_softc *sc = arg; 1424 u_int8_t reg; 1425 1426 DPRINTFN(1,("ess_audio2_intr: intr=%p\n", sc->sc_audio2.intr)); 1427 1428 mtx_enter(&audio_lock); 1429 /* Check and clear interrupt on Audio2. */ 1430 reg = ess_read_mix_reg(sc, ESS_MREG_AUDIO2_CTRL2); 1431 if ((reg & ESS_AUDIO2_CTRL2_IRQ_LATCH) == 0) { 1432 mtx_leave(&audio_lock); 1433 return (0); 1434 } 1435 reg &= ~ESS_AUDIO2_CTRL2_IRQ_LATCH; 1436 ess_write_mix_reg(sc, ESS_MREG_AUDIO2_CTRL2, reg); 1437 1438 sc->sc_audio2.nintr++; 1439 1440 if (sc->sc_audio2.active) { 1441 (*sc->sc_audio2.intr)(sc->sc_audio2.arg); 1442 mtx_leave(&audio_lock); 1443 return (1); 1444 } else { 1445 mtx_leave(&audio_lock); 1446 return (0); 1447 } 1448 } 1449 1450 void 1451 ess_audio1_poll(void *addr) 1452 { 1453 struct ess_softc *sc = addr; 1454 int dmapos, dmacount; 1455 1456 if (!sc->sc_audio1.active) 1457 return; 1458 1459 mtx_enter(&audio_lock); 1460 sc->sc_audio1.nintr++; 1461 1462 dmapos = isa_dmacount(sc->sc_isa, sc->sc_audio1.drq); 1463 dmacount = sc->sc_audio1.dmapos - dmapos; 1464 if (dmacount < 0) 1465 dmacount += sc->sc_audio1.buffersize; 1466 sc->sc_audio1.dmapos = dmapos; 1467 #if 1 1468 dmacount += sc->sc_audio1.dmacount; 1469 while (dmacount > sc->sc_audio1.blksize) { 1470 dmacount -= sc->sc_audio1.blksize; 1471 (*sc->sc_audio1.intr)(sc->sc_audio1.arg); 1472 } 1473 sc->sc_audio1.dmacount = dmacount; 1474 #else 1475 (*sc->sc_audio1.intr)(sc->sc_audio1.arg, dmacount); 1476 #endif 1477 timeout_add_msec(&sc->sc_tmo1, 1000/30); 1478 mtx_leave(&audio_lock); 1479 } 1480 1481 void 1482 ess_audio2_poll(void *addr) 1483 { 1484 struct ess_softc *sc = addr; 1485 int dmapos, dmacount; 1486 1487 if (!sc->sc_audio2.active) 1488 return; 1489 1490 mtx_enter(&audio_lock); 1491 sc->sc_audio2.nintr++; 1492 1493 dmapos = isa_dmacount(sc->sc_isa, sc->sc_audio2.drq); 1494 dmacount = sc->sc_audio2.dmapos - dmapos; 1495 if (dmacount < 0) 1496 dmacount += sc->sc_audio2.buffersize; 1497 sc->sc_audio2.dmapos = dmapos; 1498 #if 1 1499 dmacount += sc->sc_audio2.dmacount; 1500 while (dmacount > sc->sc_audio2.blksize) { 1501 dmacount -= sc->sc_audio2.blksize; 1502 (*sc->sc_audio2.intr)(sc->sc_audio2.arg); 1503 } 1504 sc->sc_audio2.dmacount = dmacount; 1505 #else 1506 (*sc->sc_audio2.intr)(sc->sc_audio2.arg, dmacount); 1507 #endif 1508 timeout_add_msec(&sc->sc_tmo2, 1000/30); 1509 mtx_leave(&audio_lock); 1510 } 1511 1512 int 1513 ess_round_blocksize(void *addr, int blk) 1514 { 1515 return ((blk + 7) & -8); /* round for max DMA size */ 1516 } 1517 1518 int 1519 ess_set_port(void *addr, mixer_ctrl_t *cp) 1520 { 1521 struct ess_softc *sc = addr; 1522 int lgain, rgain; 1523 1524 DPRINTFN(5,("ess_set_port: port=%d num_channels=%d\n", 1525 cp->dev, cp->un.value.num_channels)); 1526 1527 switch (cp->dev) { 1528 /* 1529 * The following mixer ports are all stereo. If we get a 1530 * single-channel gain value passed in, then we duplicate it 1531 * to both left and right channels. 1532 */ 1533 case ESS_MASTER_VOL: 1534 case ESS_DAC_PLAY_VOL: 1535 case ESS_MIC_PLAY_VOL: 1536 case ESS_LINE_PLAY_VOL: 1537 case ESS_SYNTH_PLAY_VOL: 1538 case ESS_CD_PLAY_VOL: 1539 case ESS_AUXB_PLAY_VOL: 1540 case ESS_RECORD_VOL: 1541 if (cp->type != AUDIO_MIXER_VALUE) 1542 return EINVAL; 1543 1544 switch (cp->un.value.num_channels) { 1545 case 1: 1546 lgain = rgain = ESS_4BIT_GAIN( 1547 cp->un.value.level[AUDIO_MIXER_LEVEL_MONO]); 1548 break; 1549 case 2: 1550 lgain = ESS_4BIT_GAIN( 1551 cp->un.value.level[AUDIO_MIXER_LEVEL_LEFT]); 1552 rgain = ESS_4BIT_GAIN( 1553 cp->un.value.level[AUDIO_MIXER_LEVEL_RIGHT]); 1554 break; 1555 default: 1556 return EINVAL; 1557 } 1558 1559 sc->gain[cp->dev][ESS_LEFT] = lgain; 1560 sc->gain[cp->dev][ESS_RIGHT] = rgain; 1561 ess_set_gain(sc, cp->dev, 1); 1562 return (0); 1563 1564 /* 1565 * The PC speaker port is mono. If we get a stereo gain value 1566 * passed in, then we return EINVAL. 1567 */ 1568 case ESS_PCSPEAKER_VOL: 1569 if (cp->un.value.num_channels != 1) 1570 return EINVAL; 1571 1572 sc->gain[cp->dev][ESS_LEFT] = sc->gain[cp->dev][ESS_RIGHT] = 1573 ESS_3BIT_GAIN(cp->un.value.level[AUDIO_MIXER_LEVEL_MONO]); 1574 ess_set_gain(sc, cp->dev, 1); 1575 return (0); 1576 1577 case ESS_RECORD_SOURCE: 1578 if (ESS_USE_AUDIO1(sc->sc_model)) { 1579 if (cp->type == AUDIO_MIXER_ENUM) 1580 return (ess_set_in_port(sc, cp->un.ord)); 1581 else 1582 return (EINVAL); 1583 } else { 1584 if (cp->type == AUDIO_MIXER_SET) 1585 return (ess_set_in_ports(sc, cp->un.mask)); 1586 else 1587 return (EINVAL); 1588 } 1589 return (0); 1590 1591 case ESS_RECORD_MONITOR: 1592 if (cp->type != AUDIO_MIXER_ENUM) 1593 return EINVAL; 1594 1595 if (cp->un.ord) 1596 /* Enable monitor */ 1597 ess_set_xreg_bits(sc, ESS_XCMD_AUDIO_CTRL, 1598 ESS_AUDIO_CTRL_MONITOR); 1599 else 1600 /* Disable monitor */ 1601 ess_clear_xreg_bits(sc, ESS_XCMD_AUDIO_CTRL, 1602 ESS_AUDIO_CTRL_MONITOR); 1603 return (0); 1604 } 1605 1606 if (ESS_USE_AUDIO1(sc->sc_model)) 1607 return (EINVAL); 1608 1609 switch (cp->dev) { 1610 case ESS_DAC_REC_VOL: 1611 case ESS_MIC_REC_VOL: 1612 case ESS_LINE_REC_VOL: 1613 case ESS_SYNTH_REC_VOL: 1614 case ESS_CD_REC_VOL: 1615 case ESS_AUXB_REC_VOL: 1616 if (cp->type != AUDIO_MIXER_VALUE) 1617 return EINVAL; 1618 1619 switch (cp->un.value.num_channels) { 1620 case 1: 1621 lgain = rgain = ESS_4BIT_GAIN( 1622 cp->un.value.level[AUDIO_MIXER_LEVEL_MONO]); 1623 break; 1624 case 2: 1625 lgain = ESS_4BIT_GAIN( 1626 cp->un.value.level[AUDIO_MIXER_LEVEL_LEFT]); 1627 rgain = ESS_4BIT_GAIN( 1628 cp->un.value.level[AUDIO_MIXER_LEVEL_RIGHT]); 1629 break; 1630 default: 1631 return EINVAL; 1632 } 1633 1634 sc->gain[cp->dev][ESS_LEFT] = lgain; 1635 sc->gain[cp->dev][ESS_RIGHT] = rgain; 1636 ess_set_gain(sc, cp->dev, 1); 1637 return (0); 1638 1639 case ESS_MIC_PREAMP: 1640 if (cp->type != AUDIO_MIXER_ENUM) 1641 return EINVAL; 1642 1643 if (cp->un.ord) 1644 /* Enable microphone preamp */ 1645 ess_set_xreg_bits(sc, ESS_XCMD_PREAMP_CTRL, 1646 ESS_PREAMP_CTRL_ENABLE); 1647 else 1648 /* Disable microphone preamp */ 1649 ess_clear_xreg_bits(sc, ESS_XCMD_PREAMP_CTRL, 1650 ESS_PREAMP_CTRL_ENABLE); 1651 return (0); 1652 } 1653 1654 return (EINVAL); 1655 } 1656 1657 int 1658 ess_get_port(void *addr, mixer_ctrl_t *cp) 1659 { 1660 struct ess_softc *sc = addr; 1661 1662 DPRINTFN(5,("ess_get_port: port=%d\n", cp->dev)); 1663 1664 switch (cp->dev) { 1665 case ESS_MASTER_VOL: 1666 case ESS_DAC_PLAY_VOL: 1667 case ESS_MIC_PLAY_VOL: 1668 case ESS_LINE_PLAY_VOL: 1669 case ESS_SYNTH_PLAY_VOL: 1670 case ESS_CD_PLAY_VOL: 1671 case ESS_AUXB_PLAY_VOL: 1672 case ESS_RECORD_VOL: 1673 switch (cp->un.value.num_channels) { 1674 case 1: 1675 cp->un.value.level[AUDIO_MIXER_LEVEL_MONO] = 1676 sc->gain[cp->dev][ESS_LEFT]; 1677 break; 1678 case 2: 1679 cp->un.value.level[AUDIO_MIXER_LEVEL_LEFT] = 1680 sc->gain[cp->dev][ESS_LEFT]; 1681 cp->un.value.level[AUDIO_MIXER_LEVEL_RIGHT] = 1682 sc->gain[cp->dev][ESS_RIGHT]; 1683 break; 1684 default: 1685 return EINVAL; 1686 } 1687 return (0); 1688 1689 case ESS_PCSPEAKER_VOL: 1690 if (cp->un.value.num_channels != 1) 1691 return EINVAL; 1692 1693 cp->un.value.level[AUDIO_MIXER_LEVEL_MONO] = 1694 sc->gain[cp->dev][ESS_LEFT]; 1695 return (0); 1696 1697 case ESS_RECORD_SOURCE: 1698 if (ESS_USE_AUDIO1(sc->sc_model)) 1699 cp->un.ord = sc->in_port; 1700 else 1701 cp->un.mask = sc->in_mask; 1702 return (0); 1703 1704 case ESS_RECORD_MONITOR: 1705 cp->un.ord = (ess_read_x_reg(sc, ESS_XCMD_AUDIO_CTRL) & 1706 ESS_AUDIO_CTRL_MONITOR) ? 1 : 0; 1707 return (0); 1708 } 1709 1710 if (ESS_USE_AUDIO1(sc->sc_model)) 1711 return (EINVAL); 1712 1713 switch (cp->dev) { 1714 case ESS_DAC_REC_VOL: 1715 case ESS_MIC_REC_VOL: 1716 case ESS_LINE_REC_VOL: 1717 case ESS_SYNTH_REC_VOL: 1718 case ESS_CD_REC_VOL: 1719 case ESS_AUXB_REC_VOL: 1720 switch (cp->un.value.num_channels) { 1721 case 1: 1722 cp->un.value.level[AUDIO_MIXER_LEVEL_MONO] = 1723 sc->gain[cp->dev][ESS_LEFT]; 1724 break; 1725 case 2: 1726 cp->un.value.level[AUDIO_MIXER_LEVEL_LEFT] = 1727 sc->gain[cp->dev][ESS_LEFT]; 1728 cp->un.value.level[AUDIO_MIXER_LEVEL_RIGHT] = 1729 sc->gain[cp->dev][ESS_RIGHT]; 1730 break; 1731 default: 1732 return EINVAL; 1733 } 1734 return (0); 1735 1736 case ESS_MIC_PREAMP: 1737 cp->un.ord = (ess_read_x_reg(sc, ESS_XCMD_PREAMP_CTRL) & 1738 ESS_PREAMP_CTRL_ENABLE) ? 1 : 0; 1739 return (0); 1740 } 1741 1742 return (EINVAL); 1743 } 1744 1745 int 1746 ess_query_devinfo(void *addr, mixer_devinfo_t *dip) 1747 { 1748 struct ess_softc *sc = addr; 1749 1750 DPRINTFN(5,("ess_query_devinfo: model=%d index=%d\n", 1751 sc->sc_model, dip->index)); 1752 1753 /* 1754 * REVISIT: There are some slight differences between the 1755 * mixers on the different ESS chips, which can 1756 * be sorted out using the chip model rather than a 1757 * separate mixer model. 1758 * This is currently coded assuming an ES1887; we 1759 * need to work out which bits are not applicable to 1760 * the other models (1888 and 888). 1761 */ 1762 switch (dip->index) { 1763 case ESS_DAC_PLAY_VOL: 1764 dip->mixer_class = ESS_INPUT_CLASS; 1765 dip->next = dip->prev = AUDIO_MIXER_LAST; 1766 strlcpy(dip->label.name, AudioNdac, sizeof dip->label.name); 1767 dip->type = AUDIO_MIXER_VALUE; 1768 dip->un.v.num_channels = 2; 1769 strlcpy(dip->un.v.units.name, AudioNvolume, 1770 sizeof dip->un.v.units.name); 1771 return (0); 1772 1773 case ESS_MIC_PLAY_VOL: 1774 dip->mixer_class = ESS_INPUT_CLASS; 1775 dip->prev = AUDIO_MIXER_LAST; 1776 if (ESS_USE_AUDIO1(sc->sc_model)) 1777 dip->next = AUDIO_MIXER_LAST; 1778 else 1779 dip->next = ESS_MIC_PREAMP; 1780 strlcpy(dip->label.name, AudioNmicrophone, 1781 sizeof dip->label.name); 1782 dip->type = AUDIO_MIXER_VALUE; 1783 dip->un.v.num_channels = 2; 1784 strlcpy(dip->un.v.units.name, AudioNvolume, 1785 sizeof dip->un.v.units.name); 1786 return (0); 1787 1788 case ESS_LINE_PLAY_VOL: 1789 dip->mixer_class = ESS_INPUT_CLASS; 1790 dip->next = dip->prev = AUDIO_MIXER_LAST; 1791 strlcpy(dip->label.name, AudioNline, sizeof dip->label.name); 1792 dip->type = AUDIO_MIXER_VALUE; 1793 dip->un.v.num_channels = 2; 1794 strlcpy(dip->un.v.units.name, AudioNvolume, 1795 sizeof dip->un.v.units.name); 1796 return (0); 1797 1798 case ESS_SYNTH_PLAY_VOL: 1799 dip->mixer_class = ESS_INPUT_CLASS; 1800 dip->next = dip->prev = AUDIO_MIXER_LAST; 1801 strlcpy(dip->label.name, AudioNfmsynth, 1802 sizeof dip->label.name); 1803 dip->type = AUDIO_MIXER_VALUE; 1804 dip->un.v.num_channels = 2; 1805 strlcpy(dip->un.v.units.name, AudioNvolume, 1806 sizeof dip->un.v.units.name); 1807 return (0); 1808 1809 case ESS_CD_PLAY_VOL: 1810 dip->mixer_class = ESS_INPUT_CLASS; 1811 dip->next = dip->prev = AUDIO_MIXER_LAST; 1812 strlcpy(dip->label.name, AudioNcd, sizeof dip->label.name); 1813 dip->type = AUDIO_MIXER_VALUE; 1814 dip->un.v.num_channels = 2; 1815 strlcpy(dip->un.v.units.name, AudioNvolume, 1816 sizeof dip->un.v.units.name); 1817 return (0); 1818 1819 case ESS_AUXB_PLAY_VOL: 1820 dip->mixer_class = ESS_INPUT_CLASS; 1821 dip->next = dip->prev = AUDIO_MIXER_LAST; 1822 strlcpy(dip->label.name, "auxb", sizeof dip->label.name); 1823 dip->type = AUDIO_MIXER_VALUE; 1824 dip->un.v.num_channels = 2; 1825 strlcpy(dip->un.v.units.name, AudioNvolume, 1826 sizeof dip->un.v.units.name); 1827 return (0); 1828 1829 case ESS_INPUT_CLASS: 1830 dip->mixer_class = ESS_INPUT_CLASS; 1831 dip->next = dip->prev = AUDIO_MIXER_LAST; 1832 strlcpy(dip->label.name, AudioCinputs, sizeof dip->label.name); 1833 dip->type = AUDIO_MIXER_CLASS; 1834 return (0); 1835 1836 case ESS_MASTER_VOL: 1837 dip->mixer_class = ESS_OUTPUT_CLASS; 1838 dip->next = dip->prev = AUDIO_MIXER_LAST; 1839 strlcpy(dip->label.name, AudioNmaster, sizeof dip->label.name); 1840 dip->type = AUDIO_MIXER_VALUE; 1841 dip->un.v.num_channels = 2; 1842 strlcpy(dip->un.v.units.name, AudioNvolume, 1843 sizeof dip->un.v.units.name); 1844 return (0); 1845 1846 case ESS_PCSPEAKER_VOL: 1847 dip->mixer_class = ESS_OUTPUT_CLASS; 1848 dip->next = dip->prev = AUDIO_MIXER_LAST; 1849 strlcpy(dip->label.name, "pc_speaker", sizeof dip->label.name); 1850 dip->type = AUDIO_MIXER_VALUE; 1851 dip->un.v.num_channels = 1; 1852 strlcpy(dip->un.v.units.name, AudioNvolume, 1853 sizeof dip->un.v.units.name); 1854 return (0); 1855 1856 case ESS_OUTPUT_CLASS: 1857 dip->mixer_class = ESS_OUTPUT_CLASS; 1858 dip->next = dip->prev = AUDIO_MIXER_LAST; 1859 strlcpy(dip->label.name, AudioCoutputs, sizeof dip->label.name); 1860 dip->type = AUDIO_MIXER_CLASS; 1861 return (0); 1862 1863 case ESS_RECORD_VOL: 1864 dip->mixer_class = ESS_RECORD_CLASS; 1865 dip->next = dip->prev = AUDIO_MIXER_LAST; 1866 strlcpy(dip->label.name, AudioNrecord, sizeof dip->label.name); 1867 dip->type = AUDIO_MIXER_VALUE; 1868 dip->un.v.num_channels = 2; 1869 strlcpy(dip->un.v.units.name, AudioNvolume, 1870 sizeof dip->un.v.units.name); 1871 return (0); 1872 1873 case ESS_RECORD_SOURCE: 1874 dip->mixer_class = ESS_RECORD_CLASS; 1875 dip->next = dip->prev = AUDIO_MIXER_LAST; 1876 strlcpy(dip->label.name, AudioNsource, sizeof dip->label.name); 1877 if (ESS_USE_AUDIO1(sc->sc_model)) { 1878 /* 1879 * The 1788 doesn't use the input mixer control that 1880 * the 1888 uses, because it's a pain when you only 1881 * have one mixer. 1882 * Perhaps it could be emulated by keeping both sets of 1883 * gain values, and doing a `context switch' of the 1884 * mixer registers when shifting from playing to 1885 * recording. 1886 */ 1887 dip->type = AUDIO_MIXER_ENUM; 1888 dip->un.e.num_mem = 4; 1889 strlcpy(dip->un.e.member[0].label.name, 1890 AudioNmicrophone, 1891 sizeof dip->un.e.member[0].label.name); 1892 dip->un.e.member[0].ord = ESS_SOURCE_MIC; 1893 strlcpy(dip->un.e.member[1].label.name, AudioNline, 1894 sizeof dip->un.e.member[1].label.name); 1895 dip->un.e.member[1].ord = ESS_SOURCE_LINE; 1896 strlcpy(dip->un.e.member[2].label.name, AudioNcd, 1897 sizeof dip->un.e.member[2].label.name); 1898 dip->un.e.member[2].ord = ESS_SOURCE_CD; 1899 strlcpy(dip->un.e.member[3].label.name, AudioNmixerout, 1900 sizeof dip->un.e.member[3].label.name); 1901 dip->un.e.member[3].ord = ESS_SOURCE_MIXER; 1902 } else { 1903 dip->type = AUDIO_MIXER_SET; 1904 dip->un.s.num_mem = 6; 1905 strlcpy(dip->un.s.member[0].label.name, AudioNdac, 1906 sizeof dip->un.e.member[0].label.name); 1907 dip->un.s.member[0].mask = 1 << ESS_DAC_REC_VOL; 1908 strlcpy(dip->un.s.member[1].label.name, 1909 AudioNmicrophone, 1910 sizeof dip->un.e.member[1].label.name); 1911 dip->un.s.member[1].mask = 1 << ESS_MIC_REC_VOL; 1912 strlcpy(dip->un.s.member[2].label.name, AudioNline, 1913 sizeof dip->un.e.member[2].label.name); 1914 dip->un.s.member[2].mask = 1 << ESS_LINE_REC_VOL; 1915 strlcpy(dip->un.s.member[3].label.name, AudioNfmsynth, 1916 sizeof dip->un.e.member[3].label.name); 1917 dip->un.s.member[3].mask = 1 << ESS_SYNTH_REC_VOL; 1918 strlcpy(dip->un.s.member[4].label.name, AudioNcd, 1919 sizeof dip->un.e.member[4].label.name); 1920 dip->un.s.member[4].mask = 1 << ESS_CD_REC_VOL; 1921 strlcpy(dip->un.s.member[5].label.name, "auxb", 1922 sizeof dip->un.e.member[5].label.name); 1923 dip->un.s.member[5].mask = 1 << ESS_AUXB_REC_VOL; 1924 } 1925 return (0); 1926 1927 case ESS_RECORD_CLASS: 1928 dip->mixer_class = ESS_RECORD_CLASS; 1929 dip->next = dip->prev = AUDIO_MIXER_LAST; 1930 strlcpy(dip->label.name, AudioCrecord, sizeof dip->label.name); 1931 dip->type = AUDIO_MIXER_CLASS; 1932 return (0); 1933 1934 case ESS_RECORD_MONITOR: 1935 dip->prev = dip->next = AUDIO_MIXER_LAST; 1936 strlcpy(dip->label.name, AudioNmute, sizeof dip->label.name); 1937 dip->type = AUDIO_MIXER_ENUM; 1938 dip->mixer_class = ESS_MONITOR_CLASS; 1939 dip->un.e.num_mem = 2; 1940 strlcpy(dip->un.e.member[0].label.name, AudioNoff, 1941 sizeof dip->un.e.member[0].label.name); 1942 dip->un.e.member[0].ord = 0; 1943 strlcpy(dip->un.e.member[1].label.name, AudioNon, 1944 sizeof dip->un.e.member[1].label.name); 1945 dip->un.e.member[1].ord = 1; 1946 return (0); 1947 1948 case ESS_MONITOR_CLASS: 1949 dip->mixer_class = ESS_MONITOR_CLASS; 1950 dip->next = dip->prev = AUDIO_MIXER_LAST; 1951 strlcpy(dip->label.name, AudioCmonitor, 1952 sizeof dip->label.name); 1953 dip->type = AUDIO_MIXER_CLASS; 1954 return (0); 1955 } 1956 1957 if (ESS_USE_AUDIO1(sc->sc_model)) 1958 return (ENXIO); 1959 1960 switch (dip->index) { 1961 case ESS_DAC_REC_VOL: 1962 dip->mixer_class = ESS_RECORD_CLASS; 1963 dip->next = dip->prev = AUDIO_MIXER_LAST; 1964 strlcpy(dip->label.name, AudioNdac, sizeof dip->label.name); 1965 dip->type = AUDIO_MIXER_VALUE; 1966 dip->un.v.num_channels = 2; 1967 strlcpy(dip->un.v.units.name, AudioNvolume, 1968 sizeof dip->un.v.units.name); 1969 return (0); 1970 1971 case ESS_MIC_REC_VOL: 1972 dip->mixer_class = ESS_RECORD_CLASS; 1973 dip->next = dip->prev = AUDIO_MIXER_LAST; 1974 strlcpy(dip->label.name, AudioNmicrophone, 1975 sizeof dip->label.name); 1976 dip->type = AUDIO_MIXER_VALUE; 1977 dip->un.v.num_channels = 2; 1978 strlcpy(dip->un.v.units.name, AudioNvolume, 1979 sizeof dip->un.v.units.name); 1980 return (0); 1981 1982 case ESS_LINE_REC_VOL: 1983 dip->mixer_class = ESS_RECORD_CLASS; 1984 dip->next = dip->prev = AUDIO_MIXER_LAST; 1985 strlcpy(dip->label.name, AudioNline, sizeof dip->label.name); 1986 dip->type = AUDIO_MIXER_VALUE; 1987 dip->un.v.num_channels = 2; 1988 strlcpy(dip->un.v.units.name, AudioNvolume, 1989 sizeof dip->un.v.units.name); 1990 return (0); 1991 1992 case ESS_SYNTH_REC_VOL: 1993 dip->mixer_class = ESS_RECORD_CLASS; 1994 dip->next = dip->prev = AUDIO_MIXER_LAST; 1995 strlcpy(dip->label.name, AudioNfmsynth, 1996 sizeof dip->label.name); 1997 dip->type = AUDIO_MIXER_VALUE; 1998 dip->un.v.num_channels = 2; 1999 strlcpy(dip->un.v.units.name, AudioNvolume, 2000 sizeof dip->un.v.units.name); 2001 return (0); 2002 2003 case ESS_CD_REC_VOL: 2004 dip->mixer_class = ESS_RECORD_CLASS; 2005 dip->next = dip->prev = AUDIO_MIXER_LAST; 2006 strlcpy(dip->label.name, AudioNcd, sizeof dip->label.name); 2007 dip->type = AUDIO_MIXER_VALUE; 2008 dip->un.v.num_channels = 2; 2009 strlcpy(dip->un.v.units.name, AudioNvolume, 2010 sizeof dip->un.v.units.name); 2011 return (0); 2012 2013 case ESS_AUXB_REC_VOL: 2014 dip->mixer_class = ESS_RECORD_CLASS; 2015 dip->next = dip->prev = AUDIO_MIXER_LAST; 2016 strlcpy(dip->label.name, "auxb", sizeof dip->label.name); 2017 dip->type = AUDIO_MIXER_VALUE; 2018 dip->un.v.num_channels = 2; 2019 strlcpy(dip->un.v.units.name, AudioNvolume, 2020 sizeof dip->un.v.units.name); 2021 return (0); 2022 2023 case ESS_MIC_PREAMP: 2024 dip->mixer_class = ESS_INPUT_CLASS; 2025 dip->prev = ESS_MIC_PLAY_VOL; 2026 dip->next = AUDIO_MIXER_LAST; 2027 strlcpy(dip->label.name, AudioNpreamp, sizeof dip->label.name); 2028 dip->type = AUDIO_MIXER_ENUM; 2029 dip->un.e.num_mem = 2; 2030 strlcpy(dip->un.e.member[0].label.name, AudioNoff, 2031 sizeof dip->un.e.member[0].label.name); 2032 dip->un.e.member[0].ord = 0; 2033 strlcpy(dip->un.e.member[1].label.name, AudioNon, 2034 sizeof dip->un.e.member[1].label.name); 2035 dip->un.e.member[1].ord = 1; 2036 return (0); 2037 } 2038 2039 return (ENXIO); 2040 } 2041 2042 void * 2043 ess_malloc(void *addr, int direction, size_t size, int pool, int flags) 2044 { 2045 struct ess_softc *sc = addr; 2046 int drq; 2047 2048 if (!ESS_USE_AUDIO1(sc->sc_model)) 2049 drq = sc->sc_audio2.drq; 2050 else 2051 drq = sc->sc_audio1.drq; 2052 return (isa_malloc(sc->sc_isa, drq, size, pool, flags)); 2053 } 2054 2055 void 2056 ess_free(void *addr, void *ptr, int pool) 2057 { 2058 isa_free(ptr, pool); 2059 } 2060 2061 size_t 2062 ess_round_buffersize(void *addr, int direction, size_t size) 2063 { 2064 if (size > MAX_ISADMA) 2065 size = MAX_ISADMA; 2066 return (size); 2067 } 2068 2069 /* ============================================ 2070 * Generic functions for ess, not used by audio h/w i/f 2071 * ============================================= 2072 */ 2073 2074 /* 2075 * Reset the chip. 2076 * Return non-zero if the chip isn't detected. 2077 */ 2078 int 2079 ess_reset(struct ess_softc *sc) 2080 { 2081 bus_space_tag_t iot = sc->sc_iot; 2082 bus_space_handle_t ioh = sc->sc_ioh; 2083 2084 sc->sc_audio1.active = 0; 2085 sc->sc_audio2.active = 0; 2086 2087 EWRITE1(iot, ioh, ESS_DSP_RESET, ESS_RESET_EXT); 2088 delay(10000); 2089 EWRITE1(iot, ioh, ESS_DSP_RESET, 0); 2090 if (ess_rdsp(sc) != ESS_MAGIC) 2091 return (1); 2092 2093 /* Enable access to the ESS extension commands. */ 2094 ess_wdsp(sc, ESS_ACMD_ENABLE_EXT); 2095 2096 return (0); 2097 } 2098 2099 void 2100 ess_set_gain(struct ess_softc *sc, int port, int on) 2101 { 2102 int gain, left, right; 2103 int mix; 2104 int src; 2105 int stereo; 2106 2107 /* 2108 * Most gain controls are found in the mixer registers and 2109 * are stereo. Any that are not, must set mix and stereo as 2110 * required. 2111 */ 2112 mix = 1; 2113 stereo = 1; 2114 2115 switch (port) { 2116 case ESS_MASTER_VOL: 2117 src = ESS_MREG_VOLUME_MASTER; 2118 break; 2119 case ESS_DAC_PLAY_VOL: 2120 if (ESS_USE_AUDIO1(sc->sc_model)) 2121 src = ESS_MREG_VOLUME_VOICE; 2122 else 2123 src = 0x7C; 2124 break; 2125 case ESS_MIC_PLAY_VOL: 2126 src = ESS_MREG_VOLUME_MIC; 2127 break; 2128 case ESS_LINE_PLAY_VOL: 2129 src = ESS_MREG_VOLUME_LINE; 2130 break; 2131 case ESS_SYNTH_PLAY_VOL: 2132 src = ESS_MREG_VOLUME_SYNTH; 2133 break; 2134 case ESS_CD_PLAY_VOL: 2135 src = ESS_MREG_VOLUME_CD; 2136 break; 2137 case ESS_AUXB_PLAY_VOL: 2138 src = ESS_MREG_VOLUME_AUXB; 2139 break; 2140 case ESS_PCSPEAKER_VOL: 2141 src = ESS_MREG_VOLUME_PCSPKR; 2142 stereo = 0; 2143 break; 2144 case ESS_DAC_REC_VOL: 2145 src = 0x69; 2146 break; 2147 case ESS_MIC_REC_VOL: 2148 src = 0x68; 2149 break; 2150 case ESS_LINE_REC_VOL: 2151 src = 0x6E; 2152 break; 2153 case ESS_SYNTH_REC_VOL: 2154 src = 0x6B; 2155 break; 2156 case ESS_CD_REC_VOL: 2157 src = 0x6A; 2158 break; 2159 case ESS_AUXB_REC_VOL: 2160 src = 0x6C; 2161 break; 2162 case ESS_RECORD_VOL: 2163 src = ESS_XCMD_VOLIN_CTRL; 2164 mix = 0; 2165 break; 2166 default: 2167 return; 2168 } 2169 2170 /* 1788 doesn't have a separate recording mixer */ 2171 if (ESS_USE_AUDIO1(sc->sc_model) && mix && src > 0x62) 2172 return; 2173 2174 if (on) { 2175 left = sc->gain[port][ESS_LEFT]; 2176 right = sc->gain[port][ESS_RIGHT]; 2177 } else { 2178 left = right = 0; 2179 } 2180 2181 if (stereo) 2182 gain = ESS_STEREO_GAIN(left, right); 2183 else 2184 gain = ESS_MONO_GAIN(left); 2185 2186 if (mix) 2187 ess_write_mix_reg(sc, src, gain); 2188 else 2189 ess_write_x_reg(sc, src, gain); 2190 } 2191 2192 /* Set the input device on devices without an input mixer. */ 2193 int 2194 ess_set_in_port(struct ess_softc *sc, int ord) 2195 { 2196 mixer_devinfo_t di; 2197 int i; 2198 2199 DPRINTF(("ess_set_in_port: ord=0x%x\n", ord)); 2200 2201 /* 2202 * Get the device info for the record source control, 2203 * including the list of available sources. 2204 */ 2205 di.index = ESS_RECORD_SOURCE; 2206 if (ess_query_devinfo(sc, &di)) 2207 return EINVAL; 2208 2209 /* See if the given ord value was anywhere in the list. */ 2210 for (i = 0; i < di.un.e.num_mem; i++) { 2211 if (ord == di.un.e.member[i].ord) 2212 break; 2213 } 2214 if (i == di.un.e.num_mem) 2215 return EINVAL; 2216 2217 ess_write_mix_reg(sc, ESS_MREG_ADC_SOURCE, ord); 2218 2219 sc->in_port = ord; 2220 return (0); 2221 } 2222 2223 /* Set the input device levels on input-mixer-enabled devices. */ 2224 int 2225 ess_set_in_ports(struct ess_softc *sc, int mask) 2226 { 2227 mixer_devinfo_t di; 2228 int i, port; 2229 2230 DPRINTF(("ess_set_in_ports: mask=0x%x\n", mask)); 2231 2232 /* 2233 * Get the device info for the record source control, 2234 * including the list of available sources. 2235 */ 2236 di.index = ESS_RECORD_SOURCE; 2237 if (ess_query_devinfo(sc, &di)) 2238 return EINVAL; 2239 2240 /* 2241 * Set or disable the record volume control for each of the 2242 * possible sources. 2243 */ 2244 for (i = 0; i < di.un.s.num_mem; i++) { 2245 /* 2246 * Calculate the source port number from its mask. 2247 */ 2248 port = ffs(di.un.s.member[i].mask); 2249 2250 /* 2251 * Set the source gain: 2252 * to the current value if source is enabled 2253 * to zero if source is disabled 2254 */ 2255 ess_set_gain(sc, port, mask & di.un.s.member[i].mask); 2256 } 2257 2258 sc->in_mask = mask; 2259 return (0); 2260 } 2261 2262 void 2263 ess_speaker_on(struct ess_softc *sc) 2264 { 2265 /* Unmute the DAC. */ 2266 ess_set_gain(sc, ESS_DAC_PLAY_VOL, 1); 2267 } 2268 2269 void 2270 ess_speaker_off(struct ess_softc *sc) 2271 { 2272 /* Mute the DAC. */ 2273 ess_set_gain(sc, ESS_DAC_PLAY_VOL, 0); 2274 } 2275 2276 /* 2277 * Calculate the time constant for the requested sampling rate. 2278 */ 2279 u_int 2280 ess_srtotc(u_int rate) 2281 { 2282 u_int tc; 2283 2284 /* The following formulae are from the ESS data sheet. */ 2285 if (rate <= 22050) 2286 tc = 128 - 397700L / rate; 2287 else 2288 tc = 256 - 795500L / rate; 2289 2290 return (tc); 2291 } 2292 2293 2294 /* 2295 * Calculate the filter constant for the requested sampling rate. 2296 */ 2297 u_int 2298 ess_srtofc(u_int rate) 2299 { 2300 /* 2301 * The following formula is derived from the information in 2302 * the ES1887 data sheet, based on a roll-off frequency of 2303 * 87%. 2304 */ 2305 return (256 - 200279L / rate); 2306 } 2307 2308 2309 /* 2310 * Return the status of the DSP. 2311 */ 2312 u_char 2313 ess_get_dsp_status(struct ess_softc *sc) 2314 { 2315 return (EREAD1(sc->sc_iot, sc->sc_ioh, ESS_DSP_RW_STATUS)); 2316 } 2317 2318 2319 /* 2320 * Return the read status of the DSP: 1 -> DSP ready for reading 2321 * 0 -> DSP not ready for reading 2322 */ 2323 u_char 2324 ess_dsp_read_ready(struct ess_softc *sc) 2325 { 2326 return ((ess_get_dsp_status(sc) & ESS_DSP_READ_READY) ? 1 : 0); 2327 } 2328 2329 2330 /* 2331 * Return the write status of the DSP: 1 -> DSP ready for writing 2332 * 0 -> DSP not ready for writing 2333 */ 2334 u_char 2335 ess_dsp_write_ready(struct ess_softc *sc) 2336 { 2337 return ((ess_get_dsp_status(sc) & ESS_DSP_WRITE_BUSY) ? 0 : 1); 2338 } 2339 2340 2341 /* 2342 * Read a byte from the DSP. 2343 */ 2344 int 2345 ess_rdsp(struct ess_softc *sc) 2346 { 2347 bus_space_tag_t iot = sc->sc_iot; 2348 bus_space_handle_t ioh = sc->sc_ioh; 2349 int i; 2350 2351 for (i = ESS_READ_TIMEOUT; i > 0; --i) { 2352 if (ess_dsp_read_ready(sc)) { 2353 i = EREAD1(iot, ioh, ESS_DSP_READ); 2354 DPRINTFN(8,("ess_rdsp() = 0x%02x\n", i)); 2355 return i; 2356 } else 2357 delay(10); 2358 } 2359 2360 DPRINTF(("ess_rdsp: timed out\n")); 2361 return (-1); 2362 } 2363 2364 /* 2365 * Write a byte to the DSP. 2366 */ 2367 int 2368 ess_wdsp(struct ess_softc *sc, u_char v) 2369 { 2370 bus_space_tag_t iot = sc->sc_iot; 2371 bus_space_handle_t ioh = sc->sc_ioh; 2372 int i; 2373 2374 DPRINTFN(8,("ess_wdsp(0x%02x)\n", v)); 2375 2376 for (i = ESS_WRITE_TIMEOUT; i > 0; --i) { 2377 if (ess_dsp_write_ready(sc)) { 2378 EWRITE1(iot, ioh, ESS_DSP_WRITE, v); 2379 return (0); 2380 } else 2381 delay(10); 2382 } 2383 2384 DPRINTF(("ess_wdsp(0x%02x): timed out\n", v)); 2385 return (-1); 2386 } 2387 2388 /* 2389 * Write a value to one of the ESS extended registers. 2390 */ 2391 int 2392 ess_write_x_reg(struct ess_softc *sc, u_char reg, u_char val) 2393 { 2394 int error; 2395 2396 DPRINTFN(2,("ess_write_x_reg: %02x=%02x\n", reg, val)); 2397 if ((error = ess_wdsp(sc, reg)) == 0) 2398 error = ess_wdsp(sc, val); 2399 2400 return error; 2401 } 2402 2403 /* 2404 * Read the value of one of the ESS extended registers. 2405 */ 2406 u_char 2407 ess_read_x_reg(struct ess_softc *sc, u_char reg) 2408 { 2409 int error; 2410 int val; 2411 2412 if ((error = ess_wdsp(sc, 0xC0)) == 0) 2413 error = ess_wdsp(sc, reg); 2414 if (error) 2415 DPRINTF(("Error reading extended register 0x%02x\n", reg)); 2416 /* REVISIT: what if an error is returned above? */ 2417 val = ess_rdsp(sc); 2418 DPRINTFN(2,("ess_read_x_reg: %02x=%02x\n", reg, val)); 2419 return val; 2420 } 2421 2422 void 2423 ess_clear_xreg_bits(struct ess_softc *sc, u_char reg, u_char mask) 2424 { 2425 if (ess_write_x_reg(sc, reg, ess_read_x_reg(sc, reg) & ~mask) == -1) 2426 DPRINTF(("Error clearing bits in extended register 0x%02x\n", 2427 reg)); 2428 } 2429 2430 void 2431 ess_set_xreg_bits(struct ess_softc *sc, u_char reg, u_char mask) 2432 { 2433 if (ess_write_x_reg(sc, reg, ess_read_x_reg(sc, reg) | mask) == -1) 2434 DPRINTF(("Error setting bits in extended register 0x%02x\n", 2435 reg)); 2436 } 2437 2438 2439 /* 2440 * Write a value to one of the ESS mixer registers. 2441 */ 2442 void 2443 ess_write_mix_reg(struct ess_softc *sc, u_char reg, u_char val) 2444 { 2445 bus_space_tag_t iot = sc->sc_iot; 2446 bus_space_handle_t ioh = sc->sc_ioh; 2447 2448 DPRINTFN(2,("ess_write_mix_reg: %x=%x\n", reg, val)); 2449 2450 mtx_enter(&audio_lock); 2451 EWRITE1(iot, ioh, ESS_MIX_REG_SELECT, reg); 2452 EWRITE1(iot, ioh, ESS_MIX_REG_DATA, val); 2453 mtx_leave(&audio_lock); 2454 } 2455 2456 /* 2457 * Read the value of one of the ESS mixer registers. 2458 */ 2459 u_char 2460 ess_read_mix_reg(struct ess_softc *sc, u_char reg) 2461 { 2462 bus_space_tag_t iot = sc->sc_iot; 2463 bus_space_handle_t ioh = sc->sc_ioh; 2464 u_char val; 2465 2466 mtx_enter(&audio_lock); 2467 EWRITE1(iot, ioh, ESS_MIX_REG_SELECT, reg); 2468 val = EREAD1(iot, ioh, ESS_MIX_REG_DATA); 2469 mtx_leave(&audio_lock); 2470 2471 DPRINTFN(2,("ess_read_mix_reg: %x=%x\n", reg, val)); 2472 return val; 2473 } 2474 2475 void 2476 ess_clear_mreg_bits(struct ess_softc *sc, u_char reg, u_char mask) 2477 { 2478 ess_write_mix_reg(sc, reg, ess_read_mix_reg(sc, reg) & ~mask); 2479 } 2480 2481 void 2482 ess_set_mreg_bits(struct ess_softc *sc, u_char reg, u_char mask) 2483 { 2484 ess_write_mix_reg(sc, reg, ess_read_mix_reg(sc, reg) | mask); 2485 } 2486 2487 void 2488 ess_read_multi_mix_reg(struct ess_softc *sc, u_char reg, u_int8_t *datap, 2489 bus_size_t count) 2490 { 2491 bus_space_tag_t iot = sc->sc_iot; 2492 bus_space_handle_t ioh = sc->sc_ioh; 2493 2494 mtx_enter(&audio_lock); 2495 EWRITE1(iot, ioh, ESS_MIX_REG_SELECT, reg); 2496 bus_space_read_multi_1(iot, ioh, ESS_MIX_REG_DATA, datap, count); 2497 mtx_leave(&audio_lock); 2498 } 2499