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