eso.c revision 1.20
1/* $OpenBSD: eso.c,v 1.20 2003/05/01 22:44:21 jason Exp $ */ 2/* $NetBSD: eso.c,v 1.3 1999/08/02 17:37:43 augustss Exp $ */ 3 4/* 5 * Copyright (c) 1999 Klaus J. Klein 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 3. The name of the author may not be used to endorse or promote products 17 * derived from this software without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 20 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 21 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 22 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 23 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 24 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 25 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 26 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 27 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29 * SUCH DAMAGE. 30 */ 31 32/* 33 * ESS Technology Inc. Solo-1 PCI AudioDrive (ES1938/1946) device driver. 34 */ 35 36#ifdef __OpenBSD__ 37#define HIDE 38#define MATCH_ARG_2_T void * 39#else 40#define HIDE static 41#define MATCH_ARG_2_T struct cfdata * 42#endif 43 44#include <sys/param.h> 45#include <sys/systm.h> 46#include <sys/kernel.h> 47#include <sys/malloc.h> 48#include <sys/device.h> 49#include <sys/proc.h> 50 51#include <dev/pci/pcidevs.h> 52#include <dev/pci/pcivar.h> 53 54#include <sys/audioio.h> 55#include <dev/audio_if.h> 56#include <dev/midi_if.h> 57 58#include <dev/mulaw.h> 59#include <dev/auconv.h> 60 61#include <dev/ic/mpuvar.h> 62#include <dev/ic/i8237reg.h> 63#include <dev/pci/esoreg.h> 64#include <dev/pci/esovar.h> 65#include <dev/audiovar.h> 66 67#include <machine/bus.h> 68#include <machine/intr.h> 69 70#if defined(AUDIO_DEBUG) || defined(DEBUG) 71#define DPRINTF(x) printf x 72#else 73#define DPRINTF(x) 74#endif 75 76struct eso_dma { 77 bus_dmamap_t ed_map; 78 caddr_t ed_addr; 79 bus_dma_segment_t ed_segs[1]; 80 int ed_nsegs; 81 size_t ed_size; 82 struct eso_dma * ed_next; 83}; 84 85#define KVADDR(dma) ((void *)(dma)->ed_addr) 86#define DMAADDR(dma) ((dma)->ed_map->dm_segs[0].ds_addr) 87 88/* Autoconfiguration interface */ 89HIDE int eso_match(struct device *, MATCH_ARG_2_T, void *); 90HIDE void eso_attach(struct device *, struct device *, void *); 91HIDE void eso_defer(struct device *); 92 93struct cfattach eso_ca = { 94 sizeof (struct eso_softc), eso_match, eso_attach 95}; 96 97#ifdef __OpenBSD__ 98struct cfdriver eso_cd = { 99 NULL, "eso", DV_DULL 100}; 101#endif 102 103/* PCI interface */ 104HIDE int eso_intr(void *); 105 106/* MI audio layer interface */ 107HIDE int eso_open(void *, int); 108HIDE void eso_close(void *); 109HIDE int eso_query_encoding(void *, struct audio_encoding *); 110HIDE int eso_set_params(void *, int, int, struct audio_params *, 111 struct audio_params *); 112HIDE int eso_round_blocksize(void *, int); 113HIDE int eso_halt_output(void *); 114HIDE int eso_halt_input(void *); 115HIDE int eso_getdev(void *, struct audio_device *); 116HIDE int eso_set_port(void *, mixer_ctrl_t *); 117HIDE int eso_get_port(void *, mixer_ctrl_t *); 118HIDE int eso_query_devinfo(void *, mixer_devinfo_t *); 119HIDE void * eso_allocm(void *, int, size_t, int, int); 120HIDE void eso_freem(void *, void *, int); 121HIDE size_t eso_round_buffersize(void *, int, size_t); 122HIDE paddr_t eso_mappage(void *, void *, off_t, int); 123HIDE int eso_get_props(void *); 124HIDE int eso_trigger_output(void *, void *, void *, int, 125 void (*)(void *), void *, struct audio_params *); 126HIDE int eso_trigger_input(void *, void *, void *, int, 127 void (*)(void *), void *, struct audio_params *); 128HIDE void eso_setup(struct eso_softc *, int); 129 130HIDE void eso_powerhook(int, void *); 131 132 133HIDE struct audio_hw_if eso_hw_if = { 134 eso_open, 135 eso_close, 136 NULL, /* drain */ 137 eso_query_encoding, 138 eso_set_params, 139 eso_round_blocksize, 140 NULL, /* commit_settings */ 141 NULL, /* init_output */ 142 NULL, /* init_input */ 143 NULL, /* start_output */ 144 NULL, /* start_input */ 145 eso_halt_output, 146 eso_halt_input, 147 NULL, /* speaker_ctl */ 148 eso_getdev, 149 NULL, /* setfd */ 150 eso_set_port, 151 eso_get_port, 152 eso_query_devinfo, 153 eso_allocm, 154 eso_freem, 155 eso_round_buffersize, 156 eso_mappage, 157 eso_get_props, 158 eso_trigger_output, 159 eso_trigger_input, 160}; 161 162HIDE const char * const eso_rev2model[] = { 163 "ES1938", 164 "ES1946", 165 "ES1946 rev E" 166}; 167 168 169/* 170 * Utility routines 171 */ 172/* Register access etc. */ 173HIDE uint8_t eso_read_ctlreg(struct eso_softc *, uint8_t); 174HIDE uint8_t eso_read_mixreg(struct eso_softc *, uint8_t); 175HIDE uint8_t eso_read_rdr(struct eso_softc *); 176HIDE int eso_reset(struct eso_softc *); 177HIDE void eso_set_gain(struct eso_softc *, unsigned int); 178HIDE int eso_set_recsrc(struct eso_softc *, unsigned int); 179HIDE void eso_write_cmd(struct eso_softc *, uint8_t); 180HIDE void eso_write_ctlreg(struct eso_softc *, uint8_t, uint8_t); 181HIDE void eso_write_mixreg(struct eso_softc *, uint8_t, uint8_t); 182/* DMA memory allocation */ 183HIDE int eso_allocmem(struct eso_softc *, size_t, size_t, size_t, 184 int, struct eso_dma *); 185HIDE void eso_freemem(struct eso_softc *, struct eso_dma *); 186 187 188HIDE int 189eso_match(parent, match, aux) 190 struct device *parent; 191 MATCH_ARG_2_T match; 192 void *aux; 193{ 194 struct pci_attach_args *pa = aux; 195 196 if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_ESSTECH && 197 PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_ESSTECH_SOLO1) 198 return (1); 199 200 return (0); 201} 202 203HIDE void 204eso_attach(parent, self, aux) 205 struct device *parent, *self; 206 void *aux; 207{ 208 struct eso_softc *sc = (struct eso_softc *)self; 209 struct pci_attach_args *pa = aux; 210 struct audio_attach_args aa; 211 pci_intr_handle_t ih; 212 bus_addr_t vcbase; 213 const char *intrstring; 214 215 sc->sc_revision = PCI_REVISION(pa->pa_class); 216 217 if (sc->sc_revision < 218 sizeof (eso_rev2model) / sizeof (eso_rev2model[0])) 219 printf(": %s", eso_rev2model[sc->sc_revision]); 220 else 221 printf(": (unknown rev. 0x%02x)", sc->sc_revision); 222 223 /* Map I/O registers. */ 224 if (pci_mapreg_map(pa, ESO_PCI_BAR_IO, PCI_MAPREG_TYPE_IO, 0, 225 &sc->sc_iot, &sc->sc_ioh, NULL, NULL, 0)) { 226 printf(", can't map I/O space\n"); 227 return; 228 } 229 if (pci_mapreg_map(pa, ESO_PCI_BAR_SB, PCI_MAPREG_TYPE_IO, 0, 230 &sc->sc_sb_iot, &sc->sc_sb_ioh, NULL, NULL, 0)) { 231 printf(", can't map SB I/O space\n"); 232 return; 233 } 234 if (pci_mapreg_map(pa, ESO_PCI_BAR_VC, PCI_MAPREG_TYPE_IO, 0, 235 &sc->sc_dmac_iot, &sc->sc_dmac_ioh, &vcbase, &sc->sc_vcsize, 0)) { 236 vcbase = 0; 237 sc->sc_vcsize = 0x10; /* From the data sheet. */ 238 } 239 240 if (pci_mapreg_map(pa, ESO_PCI_BAR_MPU, PCI_MAPREG_TYPE_IO, 0, 241 &sc->sc_mpu_iot, &sc->sc_mpu_ioh, NULL, NULL, 0)) { 242 printf(", can't map MPU I/O space\n"); 243 return; 244 } 245 if (pci_mapreg_map(pa, ESO_PCI_BAR_GAME, PCI_MAPREG_TYPE_IO, 0, 246 &sc->sc_game_iot, &sc->sc_game_ioh, NULL, NULL, 0)) { 247 printf(", can't map Game I/O space\n"); 248 return; 249 } 250 251 sc->sc_dmat = pa->pa_dmat; 252 sc->sc_dmas = NULL; 253 sc->sc_dmac_configured = 0; 254 255 sc->sc_pa = *pa; 256 257 /* Enable bus mastering. */ 258 pci_conf_write(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG, 259 pci_conf_read(pa->pa_pc, pa->pa_tag, 260 PCI_COMMAND_STATUS_REG) | 261 PCI_COMMAND_MASTER_ENABLE); 262 263 eso_setup(sc, 1); 264 265 /* map and establish the interrupt. */ 266 if (pci_intr_map(pa, &ih)) { 267 printf(", couldn't map interrupt\n"); 268 return; 269 } 270 intrstring = pci_intr_string(pa->pa_pc, ih); 271#ifdef __OpenBSD__ 272 sc->sc_ih = pci_intr_establish(pa->pa_pc, ih, IPL_AUDIO, eso_intr, sc, 273 sc->sc_dev.dv_xname); 274#else 275 sc->sc_ih = pci_intr_establish(pa->pa_pc, ih, IPL_AUDIO, eso_intr, sc); 276#endif 277 if (sc->sc_ih == NULL) { 278 printf(", couldn't establish interrupt"); 279 if (intrstring != NULL) 280 printf(" at %s", intrstring); 281 printf("\n"); 282 return; 283 } 284 printf(", %s\n", intrstring); 285 286 /* 287 * Set up the DDMA Control register; a suitable I/O region has been 288 * supposedly mapped in the VC base address register. 289 * 290 * The Solo-1 has an ... interesting silicon bug that causes it to 291 * not respond to I/O space accesses to the Audio 1 DMA controller 292 * if the latter's mapping base address is aligned on a 1K boundary. 293 * As a consequence, it is quite possible for the mapping provided 294 * in the VC BAR to be useless. To work around this, we defer this 295 * part until all autoconfiguration on our parent bus is completed 296 * and then try to map it ourselves in fulfillment of the constraint. 297 * 298 * According to the register map we may write to the low 16 bits 299 * only, but experimenting has shown we're safe. 300 * -kjk 301 */ 302 303 if (ESO_VALID_DDMAC_BASE(vcbase)) { 304 pci_conf_write(pa->pa_pc, pa->pa_tag, ESO_PCI_DDMAC, 305 vcbase | ESO_PCI_DDMAC_DE); 306 sc->sc_dmac_configured = 1; 307 308 printf("%s: mapping Audio 1 DMA using VC I/O space at 0x%lx\n", 309 sc->sc_dev.dv_xname, (unsigned long)vcbase); 310 } else { 311 DPRINTF(("%s: VC I/O space at 0x%lx not suitable, deferring\n", 312 sc->sc_dev.dv_xname, (unsigned long)vcbase)); 313 config_defer((struct device *)sc, eso_defer); 314 } 315 316 audio_attach_mi(&eso_hw_if, sc, &sc->sc_dev); 317 318 aa.type = AUDIODEV_TYPE_OPL; 319 aa.hwif = NULL; 320 aa.hdl = NULL; 321 (void)config_found(&sc->sc_dev, &aa, audioprint); 322 323 sc->sc_powerhook = powerhook_establish(&eso_powerhook, sc); 324 325#if 0 326 aa.type = AUDIODEV_TYPE_MPU; 327 aa.hwif = NULL; 328 aa.hdl = NULL; 329 sc->sc_mpudev = config_found(&sc->sc_dev, &aa, audioprint); 330#endif 331} 332 333HIDE void 334eso_setup(sc, verbose) 335 struct eso_softc *sc; 336 int verbose; 337{ 338 struct pci_attach_args *pa = &sc->sc_pa; 339 uint8_t a2mode; 340 int idx; 341 342 /* Reset the device; bail out upon failure. */ 343 if (eso_reset(sc) != 0) { 344 if (verbose) printf(", can't reset\n"); 345 return; 346 } 347 348 /* Select the DMA/IRQ policy: DDMA, ISA IRQ emulation disabled. */ 349 pci_conf_write(pa->pa_pc, pa->pa_tag, ESO_PCI_S1C, 350 pci_conf_read(pa->pa_pc, pa->pa_tag, ESO_PCI_S1C) & 351 ~(ESO_PCI_S1C_IRQP_MASK | ESO_PCI_S1C_DMAP_MASK)); 352 353 /* Enable the relevant DMA interrupts. */ 354 bus_space_write_1(sc->sc_iot, sc->sc_ioh, ESO_IO_IRQCTL, 355 ESO_IO_IRQCTL_A1IRQ | ESO_IO_IRQCTL_A2IRQ); 356 357 /* Set up A1's sample rate generator for new-style parameters. */ 358 a2mode = eso_read_mixreg(sc, ESO_MIXREG_A2MODE); 359 a2mode |= ESO_MIXREG_A2MODE_NEWA1 | ESO_MIXREG_A2MODE_ASYNC; 360 eso_write_mixreg(sc, ESO_MIXREG_A2MODE, a2mode); 361 362 /* Set mixer regs to something reasonable, needs work. */ 363 for (idx = 0; idx < ESO_NGAINDEVS; idx++) { 364 int v; 365 366 switch (idx) { 367 case ESO_MIC_PLAY_VOL: 368 case ESO_LINE_PLAY_VOL: 369 case ESO_CD_PLAY_VOL: 370 case ESO_MONO_PLAY_VOL: 371 case ESO_AUXB_PLAY_VOL: 372 case ESO_DAC_REC_VOL: 373 case ESO_LINE_REC_VOL: 374 case ESO_SYNTH_REC_VOL: 375 case ESO_CD_REC_VOL: 376 case ESO_MONO_REC_VOL: 377 case ESO_AUXB_REC_VOL: 378 case ESO_SPATIALIZER: 379 v = 0; 380 break; 381 case ESO_MASTER_VOL: 382 v = ESO_GAIN_TO_6BIT(AUDIO_MAX_GAIN / 2); 383 break; 384 default: 385 v = ESO_GAIN_TO_4BIT(AUDIO_MAX_GAIN / 2); 386 break; 387 } 388 sc->sc_gain[idx][ESO_LEFT] = sc->sc_gain[idx][ESO_RIGHT] = v; 389 eso_set_gain(sc, idx); 390 } 391 eso_set_recsrc(sc, ESO_MIXREG_ERS_MIC); 392} 393 394HIDE void 395eso_defer(self) 396 struct device *self; 397{ 398 struct eso_softc *sc = (struct eso_softc *)self; 399 struct pci_attach_args *pa = &sc->sc_pa; 400 bus_addr_t addr, start; 401 402 printf("%s: ", sc->sc_dev.dv_xname); 403 404 /* 405 * This is outright ugly, but since we must not make assumptions 406 * on the underlying allocator's behaviour it's the most straight- 407 * forward way to implement it. Note that we skip over the first 408 * 1K region, which is typically occupied by an attached ISA bus. 409 */ 410 for (start = 0x0400; start < 0xffff; start += 0x0400) { 411 if (bus_space_alloc(sc->sc_iot, 412 start + sc->sc_vcsize, start + 0x0400 - 1, 413 sc->sc_vcsize, sc->sc_vcsize, 0, 0, &addr, 414 &sc->sc_dmac_ioh) != 0) 415 continue; 416 417 pci_conf_write(pa->pa_pc, pa->pa_tag, ESO_PCI_DDMAC, 418 addr | ESO_PCI_DDMAC_DE); 419 sc->sc_dmac_iot = sc->sc_iot; 420 sc->sc_dmac_configured = 1; 421 printf("mapping Audio 1 DMA using I/O space at 0x%lx\n", 422 (unsigned long)addr); 423 424 return; 425 } 426 427 printf("can't map Audio 1 DMA into I/O space\n"); 428} 429 430HIDE void 431eso_write_cmd(sc, cmd) 432 struct eso_softc *sc; 433 uint8_t cmd; 434{ 435 int i; 436 437 /* Poll for busy indicator to become clear. */ 438 for (i = 0; i < ESO_WDR_TIMEOUT; i++) { 439 if ((bus_space_read_1(sc->sc_sb_iot, sc->sc_sb_ioh, ESO_SB_RSR) 440 & ESO_SB_RSR_BUSY) == 0) { 441 bus_space_write_1(sc->sc_sb_iot, sc->sc_sb_ioh, 442 ESO_SB_WDR, cmd); 443 return; 444 } else { 445 delay(10); 446 } 447 } 448 449 printf("%s: WDR timeout\n", sc->sc_dev.dv_xname); 450 return; 451} 452 453/* Write to a controller register */ 454HIDE void 455eso_write_ctlreg(sc, reg, val) 456 struct eso_softc *sc; 457 uint8_t reg, val; 458{ 459 460 /* DPRINTF(("ctlreg 0x%02x = 0x%02x\n", reg, val)); */ 461 462 eso_write_cmd(sc, reg); 463 eso_write_cmd(sc, val); 464} 465 466/* Read out the Read Data Register */ 467HIDE uint8_t 468eso_read_rdr(sc) 469 struct eso_softc *sc; 470{ 471 int i; 472 473 for (i = 0; i < ESO_RDR_TIMEOUT; i++) { 474 if (bus_space_read_1(sc->sc_sb_iot, sc->sc_sb_ioh, 475 ESO_SB_RBSR) & ESO_SB_RBSR_RDAV) { 476 return (bus_space_read_1(sc->sc_sb_iot, 477 sc->sc_sb_ioh, ESO_SB_RDR)); 478 } else { 479 delay(10); 480 } 481 } 482 483 printf("%s: RDR timeout\n", sc->sc_dev.dv_xname); 484 return (-1); 485} 486 487 488HIDE uint8_t 489eso_read_ctlreg(sc, reg) 490 struct eso_softc *sc; 491 uint8_t reg; 492{ 493 494 eso_write_cmd(sc, ESO_CMD_RCR); 495 eso_write_cmd(sc, reg); 496 return (eso_read_rdr(sc)); 497} 498 499HIDE void 500eso_write_mixreg(sc, reg, val) 501 struct eso_softc *sc; 502 uint8_t reg, val; 503{ 504 int s; 505 506 /* DPRINTF(("mixreg 0x%02x = 0x%02x\n", reg, val)); */ 507 508 s = splaudio(); 509 bus_space_write_1(sc->sc_sb_iot, sc->sc_sb_ioh, ESO_SB_MIXERADDR, reg); 510 bus_space_write_1(sc->sc_sb_iot, sc->sc_sb_ioh, ESO_SB_MIXERDATA, val); 511 splx(s); 512} 513 514HIDE uint8_t 515eso_read_mixreg(sc, reg) 516 struct eso_softc *sc; 517 uint8_t reg; 518{ 519 int s; 520 uint8_t val; 521 522 s = splaudio(); 523 bus_space_write_1(sc->sc_sb_iot, sc->sc_sb_ioh, ESO_SB_MIXERADDR, reg); 524 val = bus_space_read_1(sc->sc_sb_iot, sc->sc_sb_ioh, ESO_SB_MIXERDATA); 525 splx(s); 526 527 return (val); 528} 529 530HIDE int 531eso_intr(hdl) 532 void *hdl; 533{ 534 struct eso_softc *sc = hdl; 535 uint8_t irqctl; 536 537 irqctl = bus_space_read_1(sc->sc_iot, sc->sc_ioh, ESO_IO_IRQCTL); 538 539 /* If it wasn't ours, that's all she wrote. */ 540 if ((irqctl & (ESO_IO_IRQCTL_A1IRQ | ESO_IO_IRQCTL_A2IRQ)) == 0) 541 return (0); 542 543 if (irqctl & ESO_IO_IRQCTL_A1IRQ) { 544 /* Clear interrupt. */ 545 (void)bus_space_read_1(sc->sc_sb_iot, sc->sc_sb_ioh, 546 ESO_SB_RBSR); 547 548 if (sc->sc_rintr) 549 sc->sc_rintr(sc->sc_rarg); 550 else 551 wakeup(&sc->sc_rintr); 552 } 553 554 if (irqctl & ESO_IO_IRQCTL_A2IRQ) { 555 /* 556 * Clear the A2 IRQ latch: the cached value reflects the 557 * current DAC settings with the IRQ latch bit not set. 558 */ 559 eso_write_mixreg(sc, ESO_MIXREG_A2C2, sc->sc_a2c2); 560 561 if (sc->sc_pintr) 562 sc->sc_pintr(sc->sc_parg); 563 else 564 wakeup(&sc->sc_pintr); 565 } 566 567#if 0 568 if ((irqctl & ESO_IO_IRQCTL_MPUIRQ) && sc->sc_mpudev != 0) 569 mpu_intr(sc->sc_mpudev); 570#endif 571 572 return (1); 573} 574 575/* Perform a software reset, including DMA FIFOs. */ 576HIDE int 577eso_reset(sc) 578 struct eso_softc *sc; 579{ 580 int i; 581 582 bus_space_write_1(sc->sc_sb_iot, sc->sc_sb_ioh, ESO_SB_RESET, 583 ESO_SB_RESET_SW | ESO_SB_RESET_FIFO); 584 /* `Delay' suggested in the data sheet. */ 585 (void)bus_space_read_1(sc->sc_sb_iot, sc->sc_sb_ioh, ESO_SB_STATUS); 586 bus_space_write_1(sc->sc_sb_iot, sc->sc_sb_ioh, ESO_SB_RESET, 0); 587 588 /* Wait for reset to take effect. */ 589 for (i = 0; i < ESO_RESET_TIMEOUT; i++) { 590 /* Poll for data to become available. */ 591 if ((bus_space_read_1(sc->sc_sb_iot, sc->sc_sb_ioh, 592 ESO_SB_RBSR) & ESO_SB_RBSR_RDAV) != 0 && 593 bus_space_read_1(sc->sc_sb_iot, sc->sc_sb_ioh, 594 ESO_SB_RDR) == ESO_SB_RDR_RESETMAGIC) { 595 596 /* Activate Solo-1 extension commands. */ 597 eso_write_cmd(sc, ESO_CMD_EXTENB); 598 /* Reset mixer registers. */ 599 eso_write_mixreg(sc, ESO_MIXREG_RESET, 600 ESO_MIXREG_RESET_RESET); 601 602 return (0); 603 } else { 604 delay(1000); 605 } 606 } 607 608 printf("%s: reset timeout\n", sc->sc_dev.dv_xname); 609 return (-1); 610} 611 612 613/* ARGSUSED */ 614HIDE int 615eso_open(hdl, flags) 616 void *hdl; 617 int flags; 618{ 619 struct eso_softc *sc = hdl; 620 621 DPRINTF(("%s: open\n", sc->sc_dev.dv_xname)); 622 623 sc->sc_pintr = NULL; 624 sc->sc_rintr = NULL; 625 626 return (0); 627} 628 629HIDE void 630eso_close(hdl) 631 void *hdl; 632{ 633 634 DPRINTF(("%s: close\n", ((struct eso_softc *)hdl)->sc_dev.dv_xname)); 635} 636 637HIDE int 638eso_query_encoding(hdl, fp) 639 void *hdl; 640 struct audio_encoding *fp; 641{ 642 643 switch (fp->index) { 644 case 0: 645 strlcpy(fp->name, AudioEulinear, sizeof fp->name); 646 fp->encoding = AUDIO_ENCODING_ULINEAR; 647 fp->precision = 8; 648 fp->flags = 0; 649 break; 650 case 1: 651 strlcpy(fp->name, AudioEslinear, sizeof fp->name); 652 fp->encoding = AUDIO_ENCODING_SLINEAR; 653 fp->precision = 8; 654 fp->flags = 0; 655 break; 656 case 2: 657 fp->precision = 16; 658 if (fp->flags & AUOPEN_READ) { 659 strlcpy(fp->name, AudioEslinear_be, sizeof fp->name); 660 fp->encoding = AUDIO_ENCODING_SLINEAR_BE; 661 if (fp->flags & AUOPEN_WRITE) 662 fp->flags = AUDIO_ENCODINGFLAG_EMULATED; 663 else 664 fp->flags = 0; 665 } else { 666 strlcpy(fp->name, AudioEslinear_le, sizeof fp->name); 667 fp->encoding = AUDIO_ENCODING_SLINEAR_LE; 668 fp->flags = 0; 669 } 670 break; 671 case 3: 672 fp->precision = 16; 673 if (fp->flags & AUOPEN_READ) { 674 strlcpy(fp->name, AudioEulinear_be, sizeof fp->name); 675 fp->encoding = AUDIO_ENCODING_ULINEAR_BE; 676 if (fp->flags & AUOPEN_WRITE) 677 fp->flags = AUDIO_ENCODINGFLAG_EMULATED; 678 else 679 fp->flags = 0; 680 } else { 681 strlcpy(fp->name, AudioEulinear_le, sizeof fp->name); 682 fp->encoding = AUDIO_ENCODING_ULINEAR_LE; 683 fp->flags = 0; 684 } 685 break; 686 case 4: 687 fp->precision = 16; 688 if (fp->flags & AUOPEN_READ) { 689 strlcpy(fp->name, AudioEslinear_le, sizeof fp->name); 690 fp->encoding = AUDIO_ENCODING_SLINEAR_LE; 691 } else { 692 strlcpy(fp->name, AudioEslinear_be, sizeof fp->name); 693 fp->encoding = AUDIO_ENCODING_SLINEAR_BE; 694 } 695 fp->flags = AUDIO_ENCODINGFLAG_EMULATED; 696 break; 697 case 5: 698 fp->precision = 16; 699 if (fp->flags & AUOPEN_READ) { 700 strlcpy(fp->name, AudioEulinear_le, sizeof fp->name); 701 fp->encoding = AUDIO_ENCODING_ULINEAR_LE; 702 } else { 703 strlcpy(fp->name, AudioEulinear_be, sizeof fp->name); 704 fp->encoding = AUDIO_ENCODING_ULINEAR_BE; 705 } 706 fp->flags = AUDIO_ENCODINGFLAG_EMULATED; 707 break; 708 case 6: 709 strlcpy(fp->name, AudioEmulaw, sizeof fp->name); 710 fp->encoding = AUDIO_ENCODING_ULAW; 711 fp->precision = 8; 712 fp->flags = AUDIO_ENCODINGFLAG_EMULATED; 713 break; 714 case 7: 715 strlcpy(fp->name, AudioEalaw, sizeof fp->name); 716 fp->encoding = AUDIO_ENCODING_ALAW; 717 fp->precision = 8; 718 fp->flags = AUDIO_ENCODINGFLAG_EMULATED; 719 break; 720 default: 721 return (EINVAL); 722 } 723 724 return (0); 725} 726 727HIDE int 728eso_set_params(hdl, setmode, usemode, play, rec) 729 void *hdl; 730 int setmode, usemode; 731 struct audio_params *play, *rec; 732{ 733 struct eso_softc *sc = hdl; 734 struct audio_params *p; 735 int mode, r[2], rd[2], clk; 736 unsigned int srg, fltdiv; 737 738 for (mode = AUMODE_RECORD; mode != -1; 739 mode = mode == AUMODE_RECORD ? AUMODE_PLAY : -1) { 740 if ((setmode & mode) == 0) 741 continue; 742 743 p = (mode == AUMODE_PLAY) ? play : rec; 744 745 if (p->sample_rate < ESO_MINRATE || 746 p->sample_rate > ESO_MAXRATE || 747 (p->precision != 8 && p->precision != 16) || 748 (p->channels != 1 && p->channels != 2)) 749 return (EINVAL); 750 751 p->factor = 1; 752 p->sw_code = NULL; 753 switch (p->encoding) { 754 case AUDIO_ENCODING_SLINEAR_BE: 755 case AUDIO_ENCODING_ULINEAR_BE: 756 if (mode == AUMODE_PLAY && p->precision == 16) 757 p->sw_code = swap_bytes; 758 break; 759 case AUDIO_ENCODING_SLINEAR_LE: 760 case AUDIO_ENCODING_ULINEAR_LE: 761 if (mode == AUMODE_RECORD && p->precision == 16) 762 p->sw_code = swap_bytes; 763 break; 764 case AUDIO_ENCODING_ULAW: 765 if (mode == AUMODE_PLAY) { 766 p->factor = 2; 767 p->sw_code = mulaw_to_ulinear16; 768 } else { 769 p->sw_code = ulinear8_to_mulaw; 770 } 771 break; 772 case AUDIO_ENCODING_ALAW: 773 if (mode == AUMODE_PLAY) { 774 p->factor = 2; 775 p->sw_code = alaw_to_ulinear16; 776 } else { 777 p->sw_code = ulinear8_to_alaw; 778 } 779 break; 780 default: 781 return (EINVAL); 782 } 783 784 /* 785 * We'll compute both possible sample rate dividers and pick 786 * the one with the least error. 787 */ 788#define ABS(x) ((x) < 0 ? -(x) : (x)) 789 r[0] = ESO_CLK0 / 790 (128 - (rd[0] = 128 - ESO_CLK0 / p->sample_rate)); 791 r[1] = ESO_CLK1 / 792 (128 - (rd[1] = 128 - ESO_CLK1 / p->sample_rate)); 793 794 clk = ABS(p->sample_rate - r[0]) > ABS(p->sample_rate - r[1]); 795 srg = rd[clk] | (clk == 1 ? ESO_CLK1_SELECT : 0x00); 796 797 /* Roll-off frequency of 87%, as in the ES1888 driver. */ 798 fltdiv = 256 - 200279L / p->sample_rate; 799 800 /* Update to reflect the possibly inexact rate. */ 801 p->sample_rate = r[clk]; 802 803 if (mode == AUMODE_RECORD) { 804 /* Audio 1 */ 805 DPRINTF(("A1 srg 0x%02x fdiv 0x%02x\n", srg, fltdiv)); 806 eso_write_ctlreg(sc, ESO_CTLREG_SRG, srg); 807 eso_write_ctlreg(sc, ESO_CTLREG_FLTDIV, fltdiv); 808 } else { 809 /* Audio 2 */ 810 DPRINTF(("A2 srg 0x%02x fdiv 0x%02x\n", srg, fltdiv)); 811 eso_write_mixreg(sc, ESO_MIXREG_A2SRG, srg); 812 eso_write_mixreg(sc, ESO_MIXREG_A2FLTDIV, fltdiv); 813 } 814#undef ABS 815 816 } 817 818 return (0); 819} 820 821HIDE int 822eso_round_blocksize(hdl, blk) 823 void *hdl; 824 int blk; 825{ 826 827 return (blk & -32); /* keep good alignment; at least 16 req'd */ 828} 829 830HIDE int 831eso_halt_output(hdl) 832 void *hdl; 833{ 834 struct eso_softc *sc = hdl; 835 int error, s; 836 837 DPRINTF(("%s: halt_output\n", sc->sc_dev.dv_xname)); 838 839 /* 840 * Disable auto-initialize DMA, allowing the FIFO to drain and then 841 * stop. The interrupt callback pointer is cleared at this 842 * point so that an outstanding FIFO interrupt for the remaining data 843 * will be acknowledged without further processing. 844 * 845 * This does not immediately `abort' an operation in progress (c.f. 846 * audio(9)) but is the method to leave the FIFO behind in a clean 847 * state with the least hair. (Besides, that item needs to be 848 * rephrased for trigger_*()-based DMA environments.) 849 */ 850 s = splaudio(); 851 eso_write_mixreg(sc, ESO_MIXREG_A2C1, 852 ESO_MIXREG_A2C1_FIFOENB | ESO_MIXREG_A2C1_DMAENB); 853 bus_space_write_1(sc->sc_iot, sc->sc_ioh, ESO_IO_A2DMAM, 854 ESO_IO_A2DMAM_DMAENB); 855 856 sc->sc_pintr = NULL; 857 error = tsleep(&sc->sc_pintr, PCATCH | PWAIT, "esoho", hz); 858 splx(s); 859 860 /* Shut down DMA completely. */ 861 eso_write_mixreg(sc, ESO_MIXREG_A2C1, 0); 862 bus_space_write_1(sc->sc_iot, sc->sc_ioh, ESO_IO_A2DMAM, 0); 863 864 return (error == EWOULDBLOCK ? 0 : error); 865} 866 867HIDE int 868eso_halt_input(hdl) 869 void *hdl; 870{ 871 struct eso_softc *sc = hdl; 872 int error, s; 873 874 DPRINTF(("%s: halt_input\n", sc->sc_dev.dv_xname)); 875 876 /* Just like eso_halt_output(), but for Audio 1. */ 877 s = splaudio(); 878 eso_write_ctlreg(sc, ESO_CTLREG_A1C2, 879 ESO_CTLREG_A1C2_READ | ESO_CTLREG_A1C2_ADC | 880 ESO_CTLREG_A1C2_DMAENB); 881 bus_space_write_1(sc->sc_dmac_iot, sc->sc_dmac_ioh, ESO_DMAC_MODE, 882 DMA37MD_WRITE | DMA37MD_DEMAND); 883 884 sc->sc_rintr = NULL; 885 error = tsleep(&sc->sc_rintr, PCATCH | PWAIT, "esohi", hz); 886 splx(s); 887 888 /* Shut down DMA completely. */ 889 eso_write_ctlreg(sc, ESO_CTLREG_A1C2, 890 ESO_CTLREG_A1C2_READ | ESO_CTLREG_A1C2_ADC); 891 bus_space_write_1(sc->sc_dmac_iot, sc->sc_dmac_ioh, ESO_DMAC_MASK, 892 ESO_DMAC_MASK_MASK); 893 894 return (error == EWOULDBLOCK ? 0 : error); 895} 896 897/* ARGSUSED */ 898HIDE int 899eso_getdev(hdl, retp) 900 void *hdl; 901 struct audio_device *retp; 902{ 903 struct eso_softc *sc = hdl; 904 905 strlcpy(retp->name, "ESS Solo-1", sizeof retp->name); 906 snprintf(retp->version, sizeof retp->version, "0x%02x", 907 sc->sc_revision); 908 if (sc->sc_revision <= 909 sizeof (eso_rev2model) / sizeof (eso_rev2model[0])) 910 strlcpy(retp->config, eso_rev2model[sc->sc_revision], 911 sizeof retp->config); 912 else 913 strlcpy(retp->config, "unknown", sizeof retp->config); 914 915 return (0); 916} 917 918HIDE int 919eso_set_port(hdl, cp) 920 void *hdl; 921 mixer_ctrl_t *cp; 922{ 923 struct eso_softc *sc = hdl; 924 unsigned int lgain, rgain; 925 uint8_t tmp; 926 927 switch (cp->dev) { 928 case ESO_DAC_PLAY_VOL: 929 case ESO_MIC_PLAY_VOL: 930 case ESO_LINE_PLAY_VOL: 931 case ESO_SYNTH_PLAY_VOL: 932 case ESO_CD_PLAY_VOL: 933 case ESO_AUXB_PLAY_VOL: 934 case ESO_RECORD_VOL: 935 case ESO_DAC_REC_VOL: 936 case ESO_MIC_REC_VOL: 937 case ESO_LINE_REC_VOL: 938 case ESO_SYNTH_REC_VOL: 939 case ESO_CD_REC_VOL: 940 case ESO_AUXB_REC_VOL: 941 if (cp->type != AUDIO_MIXER_VALUE) 942 return (EINVAL); 943 944 /* 945 * Stereo-capable mixer ports: if we get a single-channel 946 * gain value passed in, then we duplicate it to both left 947 * and right channels. 948 */ 949 switch (cp->un.value.num_channels) { 950 case 1: 951 lgain = rgain = ESO_GAIN_TO_4BIT( 952 cp->un.value.level[AUDIO_MIXER_LEVEL_MONO]); 953 break; 954 case 2: 955 lgain = ESO_GAIN_TO_4BIT( 956 cp->un.value.level[AUDIO_MIXER_LEVEL_LEFT]); 957 rgain = ESO_GAIN_TO_4BIT( 958 cp->un.value.level[AUDIO_MIXER_LEVEL_RIGHT]); 959 break; 960 default: 961 return (EINVAL); 962 } 963 964 sc->sc_gain[cp->dev][ESO_LEFT] = lgain; 965 sc->sc_gain[cp->dev][ESO_RIGHT] = rgain; 966 eso_set_gain(sc, cp->dev); 967 break; 968 969 case ESO_MASTER_VOL: 970 if (cp->type != AUDIO_MIXER_VALUE) 971 return (EINVAL); 972 973 /* Like above, but a precision of 6 bits. */ 974 switch (cp->un.value.num_channels) { 975 case 1: 976 lgain = rgain = ESO_GAIN_TO_6BIT( 977 cp->un.value.level[AUDIO_MIXER_LEVEL_MONO]); 978 break; 979 case 2: 980 lgain = ESO_GAIN_TO_6BIT( 981 cp->un.value.level[AUDIO_MIXER_LEVEL_LEFT]); 982 rgain = ESO_GAIN_TO_6BIT( 983 cp->un.value.level[AUDIO_MIXER_LEVEL_RIGHT]); 984 break; 985 default: 986 return (EINVAL); 987 } 988 989 sc->sc_gain[cp->dev][ESO_LEFT] = lgain; 990 sc->sc_gain[cp->dev][ESO_RIGHT] = rgain; 991 eso_set_gain(sc, cp->dev); 992 break; 993 994 case ESO_SPATIALIZER: 995 if (cp->type != AUDIO_MIXER_VALUE || 996 cp->un.value.num_channels != 1) 997 return (EINVAL); 998 999 sc->sc_gain[cp->dev][ESO_LEFT] = 1000 sc->sc_gain[cp->dev][ESO_RIGHT] = 1001 ESO_GAIN_TO_6BIT( 1002 cp->un.value.level[AUDIO_MIXER_LEVEL_MONO]); 1003 eso_set_gain(sc, cp->dev); 1004 break; 1005 1006 case ESO_MONO_PLAY_VOL: 1007 case ESO_MONO_REC_VOL: 1008 if (cp->type != AUDIO_MIXER_VALUE || 1009 cp->un.value.num_channels != 1) 1010 return (EINVAL); 1011 1012 sc->sc_gain[cp->dev][ESO_LEFT] = 1013 sc->sc_gain[cp->dev][ESO_RIGHT] = 1014 ESO_GAIN_TO_4BIT( 1015 cp->un.value.level[AUDIO_MIXER_LEVEL_MONO]); 1016 eso_set_gain(sc, cp->dev); 1017 break; 1018 1019 case ESO_PCSPEAKER_VOL: 1020 if (cp->type != AUDIO_MIXER_VALUE || 1021 cp->un.value.num_channels != 1) 1022 return (EINVAL); 1023 1024 sc->sc_gain[cp->dev][ESO_LEFT] = 1025 sc->sc_gain[cp->dev][ESO_RIGHT] = 1026 ESO_GAIN_TO_3BIT( 1027 cp->un.value.level[AUDIO_MIXER_LEVEL_MONO]); 1028 eso_set_gain(sc, cp->dev); 1029 break; 1030 1031 case ESO_SPATIALIZER_ENABLE: 1032 if (cp->type != AUDIO_MIXER_ENUM) 1033 return (EINVAL); 1034 1035 sc->sc_spatializer = (cp->un.ord != 0); 1036 1037 tmp = eso_read_mixreg(sc, ESO_MIXREG_SPAT); 1038 if (sc->sc_spatializer) 1039 tmp |= ESO_MIXREG_SPAT_ENB; 1040 else 1041 tmp &= ~ESO_MIXREG_SPAT_ENB; 1042 eso_write_mixreg(sc, ESO_MIXREG_SPAT, 1043 tmp | ESO_MIXREG_SPAT_RSTREL); 1044 break; 1045 1046 case ESO_MONOOUT_SOURCE: 1047 if (cp->type != AUDIO_MIXER_ENUM) 1048 return (EINVAL); 1049 1050 sc->sc_monooutsrc = cp->un.ord; 1051 1052 tmp = eso_read_mixreg(sc, ESO_MIXREG_MPM); 1053 tmp &= ~ESO_MIXREG_MPM_MOMASK; 1054 tmp |= sc->sc_monooutsrc; 1055 eso_write_mixreg(sc, ESO_MIXREG_MPM, tmp); 1056 break; 1057 1058 case ESO_RECORD_MONITOR: 1059 if (cp->type != AUDIO_MIXER_ENUM) 1060 return (EINVAL); 1061 1062 sc->sc_recmon = (cp->un.ord != 0); 1063 1064 tmp = eso_read_ctlreg(sc, ESO_CTLREG_ACTL); 1065 if (sc->sc_recmon) 1066 tmp |= ESO_CTLREG_ACTL_RECMON; 1067 else 1068 tmp &= ~ESO_CTLREG_ACTL_RECMON; 1069 eso_write_ctlreg(sc, ESO_CTLREG_ACTL, tmp); 1070 break; 1071 1072 case ESO_RECORD_SOURCE: 1073 if (cp->type != AUDIO_MIXER_ENUM) 1074 return (EINVAL); 1075 1076 return (eso_set_recsrc(sc, cp->un.ord)); 1077 1078 case ESO_MIC_PREAMP: 1079 if (cp->type != AUDIO_MIXER_ENUM) 1080 return (EINVAL); 1081 1082 sc->sc_preamp = (cp->un.ord != 0); 1083 1084 tmp = eso_read_mixreg(sc, ESO_MIXREG_MPM); 1085 tmp &= ~ESO_MIXREG_MPM_RESV0; 1086 if (sc->sc_preamp) 1087 tmp |= ESO_MIXREG_MPM_PREAMP; 1088 else 1089 tmp &= ~ESO_MIXREG_MPM_PREAMP; 1090 eso_write_mixreg(sc, ESO_MIXREG_MPM, tmp); 1091 break; 1092 1093 default: 1094 return (EINVAL); 1095 } 1096 1097 return (0); 1098} 1099 1100HIDE int 1101eso_get_port(hdl, cp) 1102 void *hdl; 1103 mixer_ctrl_t *cp; 1104{ 1105 struct eso_softc *sc = hdl; 1106 1107 switch (cp->dev) { 1108 case ESO_DAC_PLAY_VOL: 1109 case ESO_MIC_PLAY_VOL: 1110 case ESO_LINE_PLAY_VOL: 1111 case ESO_SYNTH_PLAY_VOL: 1112 case ESO_CD_PLAY_VOL: 1113 case ESO_AUXB_PLAY_VOL: 1114 case ESO_MASTER_VOL: 1115 case ESO_RECORD_VOL: 1116 case ESO_DAC_REC_VOL: 1117 case ESO_MIC_REC_VOL: 1118 case ESO_LINE_REC_VOL: 1119 case ESO_SYNTH_REC_VOL: 1120 case ESO_CD_REC_VOL: 1121 case ESO_AUXB_REC_VOL: 1122 /* 1123 * Stereo-capable ports: if a single-channel query is made, 1124 * just return the left channel's value (since single-channel 1125 * settings themselves are applied to both channels). 1126 */ 1127 switch (cp->un.value.num_channels) { 1128 case 1: 1129 cp->un.value.level[AUDIO_MIXER_LEVEL_MONO] = 1130 sc->sc_gain[cp->dev][ESO_LEFT]; 1131 break; 1132 case 2: 1133 cp->un.value.level[AUDIO_MIXER_LEVEL_LEFT] = 1134 sc->sc_gain[cp->dev][ESO_LEFT]; 1135 cp->un.value.level[AUDIO_MIXER_LEVEL_RIGHT] = 1136 sc->sc_gain[cp->dev][ESO_RIGHT]; 1137 break; 1138 default: 1139 return (EINVAL); 1140 } 1141 break; 1142 1143 case ESO_MONO_PLAY_VOL: 1144 case ESO_PCSPEAKER_VOL: 1145 case ESO_MONO_REC_VOL: 1146 case ESO_SPATIALIZER: 1147 if (cp->un.value.num_channels != 1) 1148 return (EINVAL); 1149 cp->un.value.level[AUDIO_MIXER_LEVEL_MONO] = 1150 sc->sc_gain[cp->dev][ESO_LEFT]; 1151 break; 1152 1153 case ESO_RECORD_MONITOR: 1154 cp->un.ord = sc->sc_recmon; 1155 break; 1156 1157 case ESO_RECORD_SOURCE: 1158 cp->un.ord = sc->sc_recsrc; 1159 break; 1160 1161 case ESO_MONOOUT_SOURCE: 1162 cp->un.ord = sc->sc_monooutsrc; 1163 break; 1164 1165 case ESO_SPATIALIZER_ENABLE: 1166 cp->un.ord = sc->sc_spatializer; 1167 break; 1168 1169 case ESO_MIC_PREAMP: 1170 cp->un.ord = sc->sc_preamp; 1171 break; 1172 1173 default: 1174 return (EINVAL); 1175 } 1176 1177 1178 return (0); 1179 1180} 1181 1182HIDE int 1183eso_query_devinfo(hdl, dip) 1184 void *hdl; 1185 mixer_devinfo_t *dip; 1186{ 1187 1188 switch (dip->index) { 1189 case ESO_DAC_PLAY_VOL: 1190 dip->mixer_class = ESO_INPUT_CLASS; 1191 dip->next = dip->prev = AUDIO_MIXER_LAST; 1192 strlcpy(dip->label.name, AudioNdac, sizeof dip->label.name); 1193 dip->type = AUDIO_MIXER_VALUE; 1194 dip->un.v.num_channels = 2; 1195 strlcpy(dip->un.v.units.name, AudioNvolume, 1196 sizeof dip->un.v.units.name); 1197 break; 1198 case ESO_MIC_PLAY_VOL: 1199 dip->mixer_class = ESO_INPUT_CLASS; 1200 dip->next = dip->prev = AUDIO_MIXER_LAST; 1201 strlcpy(dip->label.name, AudioNmicrophone, 1202 sizeof dip->label.name); 1203 dip->type = AUDIO_MIXER_VALUE; 1204 dip->un.v.num_channels = 2; 1205 strlcpy(dip->un.v.units.name, AudioNvolume, 1206 sizeof dip->un.v.units.name); 1207 break; 1208 case ESO_LINE_PLAY_VOL: 1209 dip->mixer_class = ESO_INPUT_CLASS; 1210 dip->next = dip->prev = AUDIO_MIXER_LAST; 1211 strlcpy(dip->label.name, AudioNline, sizeof dip->label.name); 1212 dip->type = AUDIO_MIXER_VALUE; 1213 dip->un.v.num_channels = 2; 1214 strlcpy(dip->un.v.units.name, AudioNvolume, 1215 sizeof dip->un.v.units.name); 1216 break; 1217 case ESO_SYNTH_PLAY_VOL: 1218 dip->mixer_class = ESO_INPUT_CLASS; 1219 dip->next = dip->prev = AUDIO_MIXER_LAST; 1220 strlcpy(dip->label.name, AudioNfmsynth, 1221 sizeof dip->label.name); 1222 dip->type = AUDIO_MIXER_VALUE; 1223 dip->un.v.num_channels = 2; 1224 strlcpy(dip->un.v.units.name, AudioNvolume, 1225 sizeof dip->un.v.units.name); 1226 break; 1227 case ESO_MONO_PLAY_VOL: 1228 dip->mixer_class = ESO_INPUT_CLASS; 1229 dip->next = dip->prev = AUDIO_MIXER_LAST; 1230 strlcpy(dip->label.name, "mono_in", sizeof dip->label.name); 1231 dip->type = AUDIO_MIXER_VALUE; 1232 dip->un.v.num_channels = 1; 1233 strlcpy(dip->un.v.units.name, AudioNvolume, 1234 sizeof dip->un.v.units.name); 1235 break; 1236 case ESO_CD_PLAY_VOL: 1237 dip->mixer_class = ESO_INPUT_CLASS; 1238 dip->next = dip->prev = AUDIO_MIXER_LAST; 1239 strlcpy(dip->label.name, AudioNcd, sizeof dip->label.name); 1240 dip->type = AUDIO_MIXER_VALUE; 1241 dip->un.v.num_channels = 2; 1242 strlcpy(dip->un.v.units.name, AudioNvolume, 1243 sizeof dip->un.v.units.name); 1244 break; 1245 case ESO_AUXB_PLAY_VOL: 1246 dip->mixer_class = ESO_INPUT_CLASS; 1247 dip->next = dip->prev = AUDIO_MIXER_LAST; 1248 strlcpy(dip->label.name, "auxb", sizeof dip->label.name); 1249 dip->type = AUDIO_MIXER_VALUE; 1250 dip->un.v.num_channels = 2; 1251 strlcpy(dip->un.v.units.name, AudioNvolume, 1252 sizeof dip->un.v.units.name); 1253 break; 1254 1255 case ESO_MIC_PREAMP: 1256 dip->mixer_class = ESO_MICROPHONE_CLASS; 1257 dip->next = dip->prev = AUDIO_MIXER_LAST; 1258 strlcpy(dip->label.name, AudioNpreamp, sizeof dip->label.name); 1259 dip->type = AUDIO_MIXER_ENUM; 1260 dip->un.e.num_mem = 2; 1261 strlcpy(dip->un.e.member[0].label.name, AudioNoff, 1262 sizeof dip->un.e.member[0].label.name); 1263 dip->un.e.member[0].ord = 0; 1264 strlcpy(dip->un.e.member[1].label.name, AudioNon, 1265 sizeof dip->un.e.member[1].label.name); 1266 dip->un.e.member[1].ord = 1; 1267 break; 1268 case ESO_MICROPHONE_CLASS: 1269 dip->mixer_class = ESO_MICROPHONE_CLASS; 1270 dip->next = dip->prev = AUDIO_MIXER_LAST; 1271 strlcpy(dip->label.name, AudioNmicrophone, 1272 sizeof dip->label.name); 1273 dip->type = AUDIO_MIXER_CLASS; 1274 break; 1275 1276 case ESO_INPUT_CLASS: 1277 dip->mixer_class = ESO_INPUT_CLASS; 1278 dip->next = dip->prev = AUDIO_MIXER_LAST; 1279 strlcpy(dip->label.name, AudioCinputs, sizeof dip->label.name); 1280 dip->type = AUDIO_MIXER_CLASS; 1281 break; 1282 1283 case ESO_MASTER_VOL: 1284 dip->mixer_class = ESO_OUTPUT_CLASS; 1285 dip->next = dip->prev = AUDIO_MIXER_LAST; 1286 strlcpy(dip->label.name, AudioNmaster, sizeof dip->label.name); 1287 dip->type = AUDIO_MIXER_VALUE; 1288 dip->un.v.num_channels = 2; 1289 strlcpy(dip->un.v.units.name, AudioNvolume, 1290 sizeof dip->un.v.units.name); 1291 break; 1292 case ESO_PCSPEAKER_VOL: 1293 dip->mixer_class = ESO_OUTPUT_CLASS; 1294 dip->next = dip->prev = AUDIO_MIXER_LAST; 1295 strlcpy(dip->label.name, "pc_speaker", sizeof dip->label.name); 1296 dip->type = AUDIO_MIXER_VALUE; 1297 dip->un.v.num_channels = 1; 1298 strlcpy(dip->un.v.units.name, AudioNvolume, 1299 sizeof dip->un.v.units.name); 1300 break; 1301 case ESO_MONOOUT_SOURCE: 1302 dip->mixer_class = ESO_OUTPUT_CLASS; 1303 dip->next = dip->prev = AUDIO_MIXER_LAST; 1304 strlcpy(dip->label.name, "mono_out", sizeof dip->label.name); 1305 dip->type = AUDIO_MIXER_ENUM; 1306 dip->un.e.num_mem = 3; 1307 strlcpy(dip->un.e.member[0].label.name, AudioNmute, 1308 sizeof dip->un.e.member[0].label.name); 1309 dip->un.e.member[0].ord = ESO_MIXREG_MPM_MOMUTE; 1310 strlcpy(dip->un.e.member[1].label.name, AudioNdac, 1311 sizeof dip->un.e.member[1].label.name); 1312 dip->un.e.member[1].ord = ESO_MIXREG_MPM_MOA2R; 1313 strlcpy(dip->un.e.member[2].label.name, AudioNmixerout, 1314 sizeof dip->un.e.member[2].label.name); 1315 dip->un.e.member[2].ord = ESO_MIXREG_MPM_MOREC; 1316 break; 1317 case ESO_SPATIALIZER: 1318 dip->mixer_class = ESO_OUTPUT_CLASS; 1319 dip->prev = AUDIO_MIXER_LAST; 1320 dip->next = ESO_SPATIALIZER_ENABLE; 1321 strlcpy(dip->label.name, AudioNspatial, 1322 sizeof dip->label.name); 1323 dip->type = AUDIO_MIXER_VALUE; 1324 dip->un.v.num_channels = 1; 1325 strlcpy(dip->un.v.units.name, "level", 1326 sizeof dip->un.v.units.name); 1327 break; 1328 case ESO_SPATIALIZER_ENABLE: 1329 dip->mixer_class = ESO_OUTPUT_CLASS; 1330 dip->prev = ESO_SPATIALIZER; 1331 dip->next = AUDIO_MIXER_LAST; 1332 strlcpy(dip->label.name, "enable", sizeof dip->label.name); 1333 dip->type = AUDIO_MIXER_ENUM; 1334 dip->un.e.num_mem = 2; 1335 strlcpy(dip->un.e.member[0].label.name, AudioNoff, 1336 sizeof dip->un.e.member[0].label.name); 1337 dip->un.e.member[0].ord = 0; 1338 strlcpy(dip->un.e.member[1].label.name, AudioNon, 1339 sizeof dip->un.e.member[1].label.name); 1340 dip->un.e.member[1].ord = 1; 1341 break; 1342 1343 case ESO_OUTPUT_CLASS: 1344 dip->mixer_class = ESO_OUTPUT_CLASS; 1345 dip->next = dip->prev = AUDIO_MIXER_LAST; 1346 strlcpy(dip->label.name, AudioCoutputs, 1347 sizeof dip->label.name); 1348 dip->type = AUDIO_MIXER_CLASS; 1349 break; 1350 1351 case ESO_RECORD_MONITOR: 1352 dip->mixer_class = ESO_MONITOR_CLASS; 1353 dip->next = dip->prev = AUDIO_MIXER_LAST; 1354 strlcpy(dip->label.name, AudioNmute, sizeof dip->label.name); 1355 dip->type = AUDIO_MIXER_ENUM; 1356 dip->un.e.num_mem = 2; 1357 strlcpy(dip->un.e.member[0].label.name, AudioNoff, 1358 sizeof dip->un.e.member[0].label.name); 1359 dip->un.e.member[0].ord = 0; 1360 strlcpy(dip->un.e.member[1].label.name, AudioNon, 1361 sizeof dip->un.e.member[1].label.name); 1362 dip->un.e.member[1].ord = 1; 1363 break; 1364 case ESO_MONITOR_CLASS: 1365 dip->mixer_class = ESO_MONITOR_CLASS; 1366 dip->next = dip->prev = AUDIO_MIXER_LAST; 1367 strlcpy(dip->label.name, AudioCmonitor, 1368 sizeof dip->label.name); 1369 dip->type = AUDIO_MIXER_CLASS; 1370 break; 1371 1372 case ESO_RECORD_VOL: 1373 dip->mixer_class = ESO_RECORD_CLASS; 1374 dip->next = dip->prev = AUDIO_MIXER_LAST; 1375 strlcpy(dip->label.name, AudioNrecord, sizeof dip->label.name); 1376 dip->type = AUDIO_MIXER_VALUE; 1377 strlcpy(dip->un.v.units.name, AudioNvolume, 1378 sizeof dip->un.v.units.name); 1379 break; 1380 case ESO_RECORD_SOURCE: 1381 dip->mixer_class = ESO_RECORD_CLASS; 1382 dip->next = dip->prev = AUDIO_MIXER_LAST; 1383 strlcpy(dip->label.name, AudioNsource, sizeof dip->label.name); 1384 dip->type = AUDIO_MIXER_ENUM; 1385 dip->un.e.num_mem = 4; 1386 strlcpy(dip->un.e.member[0].label.name, AudioNmicrophone, 1387 sizeof dip->un.e.member[0].label.name); 1388 dip->un.e.member[0].ord = ESO_MIXREG_ERS_MIC; 1389 strlcpy(dip->un.e.member[1].label.name, AudioNline, 1390 sizeof dip->un.e.member[1].label.name); 1391 dip->un.e.member[1].ord = ESO_MIXREG_ERS_LINE; 1392 strlcpy(dip->un.e.member[2].label.name, AudioNcd, 1393 sizeof dip->un.e.member[2].label.name); 1394 dip->un.e.member[2].ord = ESO_MIXREG_ERS_CD; 1395 strlcpy(dip->un.e.member[3].label.name, AudioNmixerout, 1396 sizeof dip->un.e.member[3].label.name); 1397 dip->un.e.member[3].ord = ESO_MIXREG_ERS_MIXER; 1398 break; 1399 case ESO_DAC_REC_VOL: 1400 dip->mixer_class = ESO_RECORD_CLASS; 1401 dip->next = dip->prev = AUDIO_MIXER_LAST; 1402 strlcpy(dip->label.name, AudioNdac, sizeof dip->label.name); 1403 dip->type = AUDIO_MIXER_VALUE; 1404 dip->un.v.num_channels = 2; 1405 strlcpy(dip->un.v.units.name, AudioNvolume, 1406 sizeof dip->un.v.units.name); 1407 break; 1408 case ESO_MIC_REC_VOL: 1409 dip->mixer_class = ESO_RECORD_CLASS; 1410 dip->next = dip->prev = AUDIO_MIXER_LAST; 1411 strlcpy(dip->label.name, AudioNmicrophone, 1412 sizeof dip->label.name); 1413 dip->type = AUDIO_MIXER_VALUE; 1414 dip->un.v.num_channels = 2; 1415 strlcpy(dip->un.v.units.name, AudioNvolume, 1416 sizeof dip->un.v.units.name); 1417 break; 1418 case ESO_LINE_REC_VOL: 1419 dip->mixer_class = ESO_RECORD_CLASS; 1420 dip->next = dip->prev = AUDIO_MIXER_LAST; 1421 strlcpy(dip->label.name, AudioNline, sizeof dip->label.name); 1422 dip->type = AUDIO_MIXER_VALUE; 1423 dip->un.v.num_channels = 2; 1424 strlcpy(dip->un.v.units.name, AudioNvolume, 1425 sizeof dip->un.v.units.name); 1426 break; 1427 case ESO_SYNTH_REC_VOL: 1428 dip->mixer_class = ESO_RECORD_CLASS; 1429 dip->next = dip->prev = AUDIO_MIXER_LAST; 1430 strlcpy(dip->label.name, AudioNfmsynth, 1431 sizeof dip->label.name); 1432 dip->type = AUDIO_MIXER_VALUE; 1433 dip->un.v.num_channels = 2; 1434 strlcpy(dip->un.v.units.name, AudioNvolume, 1435 sizeof dip->un.v.units.name); 1436 break; 1437 case ESO_MONO_REC_VOL: 1438 dip->mixer_class = ESO_RECORD_CLASS; 1439 dip->next = dip->prev = AUDIO_MIXER_LAST; 1440 strlcpy(dip->label.name, "mono_in", sizeof dip->label.name); 1441 dip->type = AUDIO_MIXER_VALUE; 1442 dip->un.v.num_channels = 1; /* No lies */ 1443 strlcpy(dip->un.v.units.name, AudioNvolume, 1444 sizeof dip->un.v.units.name); 1445 break; 1446 case ESO_CD_REC_VOL: 1447 dip->mixer_class = ESO_RECORD_CLASS; 1448 dip->next = dip->prev = AUDIO_MIXER_LAST; 1449 strlcpy(dip->label.name, AudioNcd, sizeof dip->label.name); 1450 dip->type = AUDIO_MIXER_VALUE; 1451 dip->un.v.num_channels = 2; 1452 strlcpy(dip->un.v.units.name, AudioNvolume, 1453 sizeof dip->un.v.units.name); 1454 break; 1455 case ESO_AUXB_REC_VOL: 1456 dip->mixer_class = ESO_RECORD_CLASS; 1457 dip->next = dip->prev = AUDIO_MIXER_LAST; 1458 strlcpy(dip->label.name, "auxb", sizeof dip->label.name); 1459 dip->type = AUDIO_MIXER_VALUE; 1460 dip->un.v.num_channels = 2; 1461 strlcpy(dip->un.v.units.name, AudioNvolume, 1462 sizeof dip->un.v.units.name); 1463 break; 1464 case ESO_RECORD_CLASS: 1465 dip->mixer_class = ESO_RECORD_CLASS; 1466 dip->next = dip->prev = AUDIO_MIXER_LAST; 1467 strlcpy(dip->label.name, AudioCrecord, sizeof dip->label.name); 1468 dip->type = AUDIO_MIXER_CLASS; 1469 break; 1470 1471 default: 1472 return (ENXIO); 1473 } 1474 1475 return (0); 1476} 1477 1478HIDE int 1479eso_allocmem(sc, size, align, boundary, flags, ed) 1480 struct eso_softc *sc; 1481 size_t size; 1482 size_t align; 1483 size_t boundary; 1484 int flags; 1485 struct eso_dma *ed; 1486{ 1487 int error, wait; 1488 1489 wait = (flags & M_NOWAIT) ? BUS_DMA_NOWAIT : BUS_DMA_WAITOK; 1490 ed->ed_size = size; 1491 1492 error = bus_dmamem_alloc(sc->sc_dmat, ed->ed_size, align, boundary, 1493 ed->ed_segs, sizeof (ed->ed_segs) / sizeof (ed->ed_segs[0]), 1494 &ed->ed_nsegs, wait); 1495 if (error) 1496 goto out; 1497 1498 error = bus_dmamem_map(sc->sc_dmat, ed->ed_segs, ed->ed_nsegs, 1499 ed->ed_size, &ed->ed_addr, wait | BUS_DMA_COHERENT); 1500 if (error) 1501 goto free; 1502 1503 error = bus_dmamap_create(sc->sc_dmat, ed->ed_size, 1, ed->ed_size, 0, 1504 wait, &ed->ed_map); 1505 if (error) 1506 goto unmap; 1507 1508 error = bus_dmamap_load(sc->sc_dmat, ed->ed_map, ed->ed_addr, 1509 ed->ed_size, NULL, wait); 1510 if (error) 1511 goto destroy; 1512 1513 return (0); 1514 1515 destroy: 1516 bus_dmamap_destroy(sc->sc_dmat, ed->ed_map); 1517 unmap: 1518 bus_dmamem_unmap(sc->sc_dmat, ed->ed_addr, ed->ed_size); 1519 free: 1520 bus_dmamem_free(sc->sc_dmat, ed->ed_segs, ed->ed_nsegs); 1521 out: 1522 return (error); 1523} 1524 1525HIDE void 1526eso_freemem(sc, ed) 1527 struct eso_softc *sc; 1528 struct eso_dma *ed; 1529{ 1530 1531 bus_dmamap_unload(sc->sc_dmat, ed->ed_map); 1532 bus_dmamap_destroy(sc->sc_dmat, ed->ed_map); 1533 bus_dmamem_unmap(sc->sc_dmat, ed->ed_addr, ed->ed_size); 1534 bus_dmamem_free(sc->sc_dmat, ed->ed_segs, ed->ed_nsegs); 1535} 1536 1537HIDE void * 1538eso_allocm(hdl, direction, size, type, flags) 1539 void *hdl; 1540 int direction; 1541 size_t size; 1542 int type, flags; 1543{ 1544 struct eso_softc *sc = hdl; 1545 struct eso_dma *ed; 1546 size_t boundary; 1547 int error; 1548 1549 if ((ed = malloc(size, type, flags)) == NULL) 1550 return (NULL); 1551 1552 /* 1553 * Apparently the Audio 1 DMA controller's current address 1554 * register can't roll over a 64K address boundary, so we have to 1555 * take care of that ourselves. The second channel DMA controller 1556 * doesn't have that restriction, however. 1557 */ 1558 if (direction == AUMODE_RECORD) 1559 boundary = 0x10000; 1560 else 1561 boundary = 0; 1562 1563 1564 error = eso_allocmem(sc, size, 32, boundary, flags, ed); 1565 if (error) { 1566 free(ed, type); 1567 return (NULL); 1568 } 1569 ed->ed_next = sc->sc_dmas; 1570 sc->sc_dmas = ed; 1571 1572 return (KVADDR(ed)); 1573} 1574 1575HIDE void 1576eso_freem(hdl, addr, type) 1577 void *hdl; 1578 void *addr; 1579 int type; 1580{ 1581 struct eso_softc *sc = hdl; 1582 struct eso_dma *p, **pp; 1583 1584 for (pp = &sc->sc_dmas; (p = *pp) != NULL; pp = &p->ed_next) { 1585 if (KVADDR(p) == addr) { 1586 eso_freemem(sc, p); 1587 *pp = p->ed_next; 1588 free(p, type); 1589 return; 1590 } 1591 } 1592} 1593 1594HIDE size_t 1595eso_round_buffersize(hdl, direction, bufsize) 1596 void *hdl; 1597 int direction; 1598 size_t bufsize; 1599{ 1600 1601 /* 64K restriction: ISA at eleven? */ 1602 if (bufsize > 65536) 1603 bufsize = 65536; 1604 1605 return (bufsize); 1606} 1607 1608HIDE paddr_t 1609eso_mappage(hdl, addr, offs, prot) 1610 void *hdl; 1611 void *addr; 1612 off_t offs; 1613 int prot; 1614{ 1615 struct eso_softc *sc = hdl; 1616 struct eso_dma *ed; 1617 1618 if (offs < 0) 1619 return (-1); 1620 for (ed = sc->sc_dmas; ed != NULL && KVADDR(ed) == addr; 1621 ed = ed->ed_next) 1622 ; 1623 if (ed == NULL) 1624 return (-1); 1625 1626 return (bus_dmamem_mmap(sc->sc_dmat, ed->ed_segs, ed->ed_nsegs, 1627 offs, prot, BUS_DMA_WAITOK)); 1628} 1629 1630/* ARGSUSED */ 1631HIDE int 1632eso_get_props(hdl) 1633 void *hdl; 1634{ 1635 1636 return (AUDIO_PROP_MMAP | AUDIO_PROP_INDEPENDENT | 1637 AUDIO_PROP_FULLDUPLEX); 1638} 1639 1640HIDE int 1641eso_trigger_output(hdl, start, end, blksize, intr, arg, param) 1642 void *hdl; 1643 void *start, *end; 1644 int blksize; 1645 void (*intr)(void *); 1646 void *arg; 1647 struct audio_params *param; 1648{ 1649 struct eso_softc *sc = hdl; 1650 struct eso_dma *ed; 1651 uint8_t a2c1; 1652 1653 DPRINTF(( 1654 "%s: trigger_output: start %p, end %p, blksize %d, intr %p(%p)\n", 1655 sc->sc_dev.dv_xname, start, end, blksize, intr, arg)); 1656 DPRINTF(("%s: param: rate %lu, encoding %u, precision %u, channels %u, sw_code %p, factor %d\n", 1657 sc->sc_dev.dv_xname, param->sample_rate, param->encoding, 1658 param->precision, param->channels, param->sw_code, param->factor)); 1659 1660 /* Find DMA buffer. */ 1661 for (ed = sc->sc_dmas; ed != NULL && KVADDR(ed) != start; 1662 ed = ed->ed_next) 1663 ; 1664 if (ed == NULL) { 1665 printf("%s: trigger_output: bad addr %p\n", 1666 sc->sc_dev.dv_xname, start); 1667 return (EINVAL); 1668 } 1669 1670 sc->sc_pintr = intr; 1671 sc->sc_parg = arg; 1672 1673 /* DMA transfer count (in `words'!) reload using 2's complement. */ 1674 blksize = -(blksize >> 1); 1675 eso_write_mixreg(sc, ESO_MIXREG_A2TCRLO, blksize & 0xff); 1676 eso_write_mixreg(sc, ESO_MIXREG_A2TCRHI, blksize >> 8); 1677 1678 /* Update DAC to reflect DMA count and audio parameters. */ 1679 /* Note: we cache A2C2 in order to avoid r/m/w at interrupt time. */ 1680 if (param->precision * param->factor == 16) 1681 sc->sc_a2c2 |= ESO_MIXREG_A2C2_16BIT; 1682 else 1683 sc->sc_a2c2 &= ~ESO_MIXREG_A2C2_16BIT; 1684 if (param->channels == 2) 1685 sc->sc_a2c2 |= ESO_MIXREG_A2C2_STEREO; 1686 else 1687 sc->sc_a2c2 &= ~ESO_MIXREG_A2C2_STEREO; 1688 if (param->encoding == AUDIO_ENCODING_SLINEAR_BE || 1689 param->encoding == AUDIO_ENCODING_SLINEAR_LE) 1690 sc->sc_a2c2 |= ESO_MIXREG_A2C2_SIGNED; 1691 else 1692 sc->sc_a2c2 &= ~ESO_MIXREG_A2C2_SIGNED; 1693 /* Unmask IRQ. */ 1694 sc->sc_a2c2 |= ESO_MIXREG_A2C2_IRQM; 1695 eso_write_mixreg(sc, ESO_MIXREG_A2C2, sc->sc_a2c2); 1696 1697 /* Set up DMA controller. */ 1698 bus_space_write_4(sc->sc_iot, sc->sc_ioh, ESO_IO_A2DMAA, DMAADDR(ed)); 1699 bus_space_write_2(sc->sc_iot, sc->sc_ioh, ESO_IO_A2DMAC, 1700 (uint8_t *)end - (uint8_t *)start); 1701 bus_space_write_1(sc->sc_iot, sc->sc_ioh, ESO_IO_A2DMAM, 1702 ESO_IO_A2DMAM_DMAENB | ESO_IO_A2DMAM_AUTO); 1703 1704 /* Start DMA. */ 1705 a2c1 = eso_read_mixreg(sc, ESO_MIXREG_A2C1); 1706 a2c1 &= ~ESO_MIXREG_A2C1_RESV0; /* Paranoia? XXX bit 5 */ 1707 a2c1 |= ESO_MIXREG_A2C1_FIFOENB | ESO_MIXREG_A2C1_DMAENB | 1708 ESO_MIXREG_A2C1_AUTO; 1709 eso_write_mixreg(sc, ESO_MIXREG_A2C1, a2c1); 1710 1711 return (0); 1712} 1713 1714HIDE int 1715eso_trigger_input(hdl, start, end, blksize, intr, arg, param) 1716 void *hdl; 1717 void *start, *end; 1718 int blksize; 1719 void (*intr)(void *); 1720 void *arg; 1721 struct audio_params *param; 1722{ 1723 struct eso_softc *sc = hdl; 1724 struct eso_dma *ed; 1725 uint8_t actl, a1c1; 1726 1727 DPRINTF(( 1728 "%s: trigger_input: start %p, end %p, blksize %d, intr %p(%p)\n", 1729 sc->sc_dev.dv_xname, start, end, blksize, intr, arg)); 1730 DPRINTF(("%s: param: rate %lu, encoding %u, precision %u, channels %u, sw_code %p, factor %d\n", 1731 sc->sc_dev.dv_xname, param->sample_rate, param->encoding, 1732 param->precision, param->channels, param->sw_code, param->factor)); 1733 1734 /* 1735 * If we failed to configure the Audio 1 DMA controller, bail here 1736 * while retaining availability of the DAC direction (in Audio 2). 1737 */ 1738 if (!sc->sc_dmac_configured) 1739 return (EIO); 1740 1741 /* Find DMA buffer. */ 1742 for (ed = sc->sc_dmas; ed != NULL && KVADDR(ed) != start; 1743 ed = ed->ed_next) 1744 ; 1745 if (ed == NULL) { 1746 printf("%s: trigger_output: bad addr %p\n", 1747 sc->sc_dev.dv_xname, start); 1748 return (EINVAL); 1749 } 1750 1751 sc->sc_rintr = intr; 1752 sc->sc_rarg = arg; 1753 1754 /* Set up ADC DMA converter parameters. */ 1755 actl = eso_read_ctlreg(sc, ESO_CTLREG_ACTL); 1756 if (param->channels == 2) { 1757 actl &= ~ESO_CTLREG_ACTL_MONO; 1758 actl |= ESO_CTLREG_ACTL_STEREO; 1759 } else { 1760 actl &= ~ESO_CTLREG_ACTL_STEREO; 1761 actl |= ESO_CTLREG_ACTL_MONO; 1762 } 1763 eso_write_ctlreg(sc, ESO_CTLREG_ACTL, actl); 1764 1765 /* Set up Transfer Type: maybe move to attach time? */ 1766 eso_write_ctlreg(sc, ESO_CTLREG_A1TT, ESO_CTLREG_A1TT_DEMAND4); 1767 1768 /* DMA transfer count reload using 2's complement. */ 1769 blksize = -blksize; 1770 eso_write_ctlreg(sc, ESO_CTLREG_A1TCRLO, blksize & 0xff); 1771 eso_write_ctlreg(sc, ESO_CTLREG_A1TCRHI, blksize >> 8); 1772 1773 /* Set up and enable Audio 1 DMA FIFO. */ 1774 a1c1 = ESO_CTLREG_A1C1_RESV1 | ESO_CTLREG_A1C1_FIFOENB; 1775 if (param->precision * param->factor == 16) 1776 a1c1 |= ESO_CTLREG_A1C1_16BIT; 1777 if (param->channels == 2) 1778 a1c1 |= ESO_CTLREG_A1C1_STEREO; 1779 else 1780 a1c1 |= ESO_CTLREG_A1C1_MONO; 1781 if (param->encoding == AUDIO_ENCODING_SLINEAR_BE || 1782 param->encoding == AUDIO_ENCODING_SLINEAR_LE) 1783 a1c1 |= ESO_CTLREG_A1C1_SIGNED; 1784 eso_write_ctlreg(sc, ESO_CTLREG_A1C1, a1c1); 1785 1786 /* Set up ADC IRQ/DRQ parameters. */ 1787 eso_write_ctlreg(sc, ESO_CTLREG_LAIC, 1788 ESO_CTLREG_LAIC_PINENB | ESO_CTLREG_LAIC_EXTENB); 1789 eso_write_ctlreg(sc, ESO_CTLREG_DRQCTL, 1790 ESO_CTLREG_DRQCTL_ENB1 | ESO_CTLREG_DRQCTL_EXTENB); 1791 1792 /* Set up and enable DMA controller. */ 1793 bus_space_write_1(sc->sc_dmac_iot, sc->sc_dmac_ioh, ESO_DMAC_CLEAR, 0); 1794 bus_space_write_1(sc->sc_dmac_iot, sc->sc_dmac_ioh, ESO_DMAC_MASK, 1795 ESO_DMAC_MASK_MASK); 1796 bus_space_write_1(sc->sc_dmac_iot, sc->sc_dmac_ioh, ESO_DMAC_MODE, 1797 DMA37MD_WRITE | DMA37MD_LOOP | DMA37MD_DEMAND); 1798 bus_space_write_4(sc->sc_dmac_iot, sc->sc_dmac_ioh, ESO_DMAC_DMAA, 1799 DMAADDR(ed)); 1800 bus_space_write_2(sc->sc_dmac_iot, sc->sc_dmac_ioh, ESO_DMAC_DMAC, 1801 (uint8_t *)end - (uint8_t *)start - 1); 1802 bus_space_write_1(sc->sc_dmac_iot, sc->sc_dmac_ioh, ESO_DMAC_MASK, 0); 1803 1804 /* Start DMA. */ 1805 eso_write_ctlreg(sc, ESO_CTLREG_A1C2, 1806 ESO_CTLREG_A1C2_DMAENB | ESO_CTLREG_A1C2_READ | 1807 ESO_CTLREG_A1C2_AUTO | ESO_CTLREG_A1C2_ADC); 1808 1809 return (0); 1810} 1811 1812HIDE int 1813eso_set_recsrc(sc, recsrc) 1814 struct eso_softc *sc; 1815 unsigned int recsrc; 1816{ 1817 1818 eso_write_mixreg(sc, ESO_MIXREG_ERS, recsrc); 1819 sc->sc_recsrc = recsrc; 1820 return (0); 1821} 1822 1823HIDE void 1824eso_set_gain(sc, port) 1825 struct eso_softc *sc; 1826 unsigned int port; 1827{ 1828 uint8_t mixreg, tmp; 1829 1830 switch (port) { 1831 case ESO_DAC_PLAY_VOL: 1832 mixreg = ESO_MIXREG_PVR_A2; 1833 break; 1834 case ESO_MIC_PLAY_VOL: 1835 mixreg = ESO_MIXREG_PVR_MIC; 1836 break; 1837 case ESO_LINE_PLAY_VOL: 1838 mixreg = ESO_MIXREG_PVR_LINE; 1839 break; 1840 case ESO_SYNTH_PLAY_VOL: 1841 mixreg = ESO_MIXREG_PVR_SYNTH; 1842 break; 1843 case ESO_CD_PLAY_VOL: 1844 mixreg = ESO_MIXREG_PVR_CD; 1845 break; 1846 case ESO_AUXB_PLAY_VOL: 1847 mixreg = ESO_MIXREG_PVR_AUXB; 1848 break; 1849 1850 case ESO_DAC_REC_VOL: 1851 mixreg = ESO_MIXREG_RVR_A2; 1852 break; 1853 case ESO_MIC_REC_VOL: 1854 mixreg = ESO_MIXREG_RVR_MIC; 1855 break; 1856 case ESO_LINE_REC_VOL: 1857 mixreg = ESO_MIXREG_RVR_LINE; 1858 break; 1859 case ESO_SYNTH_REC_VOL: 1860 mixreg = ESO_MIXREG_RVR_SYNTH; 1861 break; 1862 case ESO_CD_REC_VOL: 1863 mixreg = ESO_MIXREG_RVR_CD; 1864 break; 1865 case ESO_AUXB_REC_VOL: 1866 mixreg = ESO_MIXREG_RVR_AUXB; 1867 break; 1868 case ESO_MONO_PLAY_VOL: 1869 mixreg = ESO_MIXREG_PVR_MONO; 1870 break; 1871 case ESO_MONO_REC_VOL: 1872 mixreg = ESO_MIXREG_RVR_MONO; 1873 break; 1874 1875 case ESO_PCSPEAKER_VOL: 1876 /* Special case - only 3-bit, mono, and reserved bits. */ 1877 tmp = eso_read_mixreg(sc, ESO_MIXREG_PCSVR); 1878 tmp &= ESO_MIXREG_PCSVR_RESV; 1879 /* Map bits 7:5 -> 2:0. */ 1880 tmp |= (sc->sc_gain[port][ESO_LEFT] >> 5); 1881 eso_write_mixreg(sc, ESO_MIXREG_PCSVR, tmp); 1882 return; 1883 1884 case ESO_MASTER_VOL: 1885 /* Special case - separate regs, and 6-bit precision. */ 1886 /* Map bits 7:2 -> 5:0. */ 1887 eso_write_mixreg(sc, ESO_MIXREG_LMVM, 1888 sc->sc_gain[port][ESO_LEFT] >> 2); 1889 eso_write_mixreg(sc, ESO_MIXREG_RMVM, 1890 sc->sc_gain[port][ESO_RIGHT] >> 2); 1891 return; 1892 1893 case ESO_SPATIALIZER: 1894 /* Special case - only `mono', and higher precision. */ 1895 eso_write_mixreg(sc, ESO_MIXREG_SPATLVL, 1896 sc->sc_gain[port][ESO_LEFT]); 1897 return; 1898 1899 case ESO_RECORD_VOL: 1900 /* Very Special case, controller register. */ 1901 eso_write_ctlreg(sc, ESO_CTLREG_RECLVL,ESO_4BIT_GAIN_TO_STEREO( 1902 sc->sc_gain[port][ESO_LEFT], sc->sc_gain[port][ESO_RIGHT])); 1903 return; 1904 1905 default: 1906#ifdef DIAGNOSTIC 1907 panic("eso_set_gain: bad port %u", port); 1908 /* NOTREACHED */ 1909#else 1910 return; 1911#endif 1912 } 1913 1914 eso_write_mixreg(sc, mixreg, ESO_4BIT_GAIN_TO_STEREO( 1915 sc->sc_gain[port][ESO_LEFT], sc->sc_gain[port][ESO_RIGHT])); 1916} 1917 1918 1919HIDE void 1920eso_powerhook(why, self) 1921 int why; 1922 void *self; 1923{ 1924 struct eso_softc *sc = (struct eso_softc *)self; 1925 1926 if (why != PWR_RESUME) { 1927 eso_halt_output(sc); 1928 eso_halt_input(sc); 1929 1930 bus_space_write_1(sc->sc_iot, sc->sc_ioh, ESO_IO_A2DMAM, 0); 1931 bus_space_write_1(sc->sc_dmac_iot, 1932 sc->sc_dmac_ioh, ESO_DMAC_CLEAR, 0); 1933 bus_space_write_1(sc->sc_sb_iot, 1934 sc->sc_sb_ioh, ESO_SB_STATUSFLAGS, 3); 1935 1936 /* shut down dma */ 1937 pci_conf_write(sc->sc_pa.pa_pc, 1938 sc->sc_pa.pa_tag, ESO_PCI_DDMAC, 0); 1939 } else 1940 eso_setup(sc, 0); 1941} 1942