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