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