1 /* $OpenBSD: neo.c,v 1.10 2002/01/20 19:56:53 ericj Exp $ */ 2 3 /* 4 * Copyright (c) 1999 Cameron Grant <gandalf@vilnya.demon.co.uk> 5 * All rights reserved. 6 * 7 * Derived from the public domain Linux driver 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 28 * SUCH DAMAGE. 29 * 30 * $FreeBSD: src/sys/dev/sound/pci/neomagic.c,v 1.8 2000/03/20 15:30:50 cg Exp $ 31 */ 32 33 34 35 #include <sys/param.h> 36 #include <sys/systm.h> 37 #include <sys/kernel.h> 38 #include <sys/malloc.h> 39 #include <sys/device.h> 40 41 #include <dev/pci/pcidevs.h> 42 #include <dev/pci/pcivar.h> 43 44 #include <sys/audioio.h> 45 #include <dev/audio_if.h> 46 #include <dev/mulaw.h> 47 #include <dev/auconv.h> 48 #include <dev/ic/ac97.h> 49 50 #include <dev/pci/neoreg.h> 51 #include <dev/microcode/neomagic/neo-coeff.h> 52 53 /* -------------------------------------------------------------------- */ 54 /* 55 * As of 04/13/00, public documentation on the Neomagic 256 is not available. 56 * These comments were gleaned by looking at the driver carefully. 57 * 58 * The Neomagic 256 AV/ZX chips provide both video and audio capabilities 59 * on one chip. About 2-6 megabytes of memory are associated with 60 * the chip. Most of this goes to video frame buffers, but some is used for 61 * audio buffering 62 * 63 * Unlike most PCI audio chips, the Neomagic chip does not rely on DMA. 64 * Instead, the chip allows you to carve out two ring buffers out of its 65 * memory. However you carve this and how much you can carve seems to be 66 * voodoo. The algorithm is in nm_init. 67 * 68 * Most Neomagic audio chips use the AC-97 codec interface. However, there 69 * seem to be a select few chips 256AV chips that do not support AC-97. 70 * This driver does not support them but there are rumors that it 71 * mgiht work with wss isa drivers. This might require some playing around 72 * with your BIOS. 73 * 74 * The Neomagic 256 AV/ZX have 2 PCI I/O region descriptors. Both of 75 * them describe a memory region. The frame buffer is the first region 76 * and the register set is the second region. 77 * 78 * The register manipulation logic is taken from the Linux driver, 79 * which is in the public domain. 80 * 81 * The Neomagic is even nice enough to map the AC-97 codec registers into 82 * the register space to allow direct manipulation. Watch out, accessing 83 * AC-97 registers on the Neomagic requires great delicateness, otherwise 84 * the thing will hang the PCI bus, rendering your system frozen. 85 * 86 * For one, it seems the Neomagic status register that reports AC-97 87 * readiness should NOT be polled more often than once each 1ms. 88 * 89 * Also, writes to the AC-97 register space may take order 40us to 90 * complete. 91 * 92 * Unlike many sound engines, the Neomagic does not support (as fas as 93 * we know :) the notion of interrupting every n bytes transferred, 94 * unlike many DMA engines. Instead, it allows you to specify one 95 * location in each ring buffer (called the watermark). When the chip 96 * passes that location while playing, it signals an interrupt. 97 * 98 * The ring buffer size is currently 16k. That is about 100ms of audio 99 * at 44.1khz/stero/16 bit. However, to keep the buffer full, interrupts 100 * are generated more often than that, so 20-40 interrupts per second 101 * should not be unexpected. Increasing BUFFSIZE should help minimize 102 * of glitches due to drivers that spend to much time looping at high 103 * privelege levels as well as the impact of badly written audio 104 * interface clients. 105 * 106 * TO-DO list: 107 * neo_malloc/neo_free are still seriously broken. 108 * 109 * Figure out interaction with video stuff (look at Xfree86 driver?) 110 * 111 * Power management (neoactivate) 112 * 113 * Fix detect of Neo devices that don't work this driver (see neo_attach) 114 * 115 * Figure out how to shrink that huge table neo-coeff.h 116 */ 117 118 #define NM_BUFFSIZE 16384 119 120 #define NM256AV_PCI_ID 0x800510c8 121 #define NM256ZX_PCI_ID 0x800610c8 122 123 /* device private data */ 124 struct neo_softc { 125 struct device dev; 126 127 bus_space_tag_t bufiot; 128 bus_space_handle_t bufioh; 129 130 bus_space_tag_t regiot; 131 bus_space_handle_t regioh; 132 133 u_int32_t type; 134 void *ih; 135 136 void (*pintr)(void *); /* dma completion intr handler */ 137 void *parg; /* arg for intr() */ 138 139 void (*rintr)(void *); /* dma completion intr handler */ 140 void *rarg; /* arg for intr() */ 141 142 u_int32_t ac97_base, ac97_status, ac97_busy; 143 u_int32_t buftop, pbuf, rbuf, cbuf, acbuf; 144 u_int32_t playint, recint, misc1int, misc2int; 145 u_int32_t irsz, badintr; 146 147 u_int32_t pbufsize; 148 u_int32_t rbufsize; 149 150 u_int32_t pblksize; 151 u_int32_t rblksize; 152 153 u_int32_t pwmark; 154 u_int32_t rwmark; 155 156 struct ac97_codec_if *codec_if; 157 struct ac97_host_if host_if; 158 }; 159 160 /* -------------------------------------------------------------------- */ 161 162 /* 163 * prototypes 164 */ 165 166 static int nm_waitcd(struct neo_softc *sc); 167 static int nm_loadcoeff(struct neo_softc *sc, int dir, int num); 168 static int nm_init(struct neo_softc *); 169 170 int nmchan_getptr(struct neo_softc *, int); 171 /* talk to the card */ 172 static u_int32_t nm_rd(struct neo_softc *, int, int); 173 static void nm_wr(struct neo_softc *, int, u_int32_t, int); 174 static u_int32_t nm_rdbuf(struct neo_softc *, int, int); 175 static void nm_wrbuf(struct neo_softc *, int, u_int32_t, int); 176 177 int neo_match __P((struct device *, void *, void *)); 178 void neo_attach __P((struct device *, struct device *, void *)); 179 int neo_intr __P((void *)); 180 181 int neo_open __P((void *, int)); 182 void neo_close __P((void *)); 183 int neo_query_encoding __P((void *, struct audio_encoding *)); 184 int neo_set_params __P((void *, int, int, struct audio_params *, struct audio_params *)); 185 int neo_round_blocksize __P((void *, int)); 186 int neo_trigger_output __P((void *, void *, void *, int, void (*)(void *), 187 void *, struct audio_params *)); 188 int neo_trigger_input __P((void *, void *, void *, int, void (*)(void *), 189 void *, struct audio_params *)); 190 int neo_halt_output __P((void *)); 191 int neo_halt_input __P((void *)); 192 int neo_getdev __P((void *, struct audio_device *)); 193 int neo_mixer_set_port __P((void *, mixer_ctrl_t *)); 194 int neo_mixer_get_port __P((void *, mixer_ctrl_t *)); 195 int neo_attach_codec __P((void *sc, struct ac97_codec_if *)); 196 int neo_read_codec __P((void *sc, u_int8_t a, u_int16_t *d)); 197 int neo_write_codec __P((void *sc, u_int8_t a, u_int16_t d)); 198 void neo_reset_codec __P((void *sc)); 199 enum ac97_host_flags neo_flags_codec __P((void *sc)); 200 int neo_query_devinfo __P((void *, mixer_devinfo_t *)); 201 void *neo_malloc __P((void *, int, size_t, int, int)); 202 void neo_free __P((void *, void *, int)); 203 size_t neo_round_buffersize __P((void *, int, size_t)); 204 int neo_get_props __P((void *)); 205 void neo_set_mixer __P((struct neo_softc *sc, int a, int d)); 206 207 208 209 struct cfdriver neo_cd = { 210 NULL, "neo", DV_DULL 211 }; 212 213 214 struct cfattach neo_ca = { 215 sizeof(struct neo_softc), neo_match, neo_attach 216 }; 217 218 219 struct audio_device neo_device = { 220 "NeoMagic 256", 221 "", 222 "neo" 223 }; 224 225 #if 0 226 static u_int32_t badcards[] = { 227 0x0007103c, 228 0x008f1028, 229 }; 230 #endif 231 232 #define NUM_BADCARDS (sizeof(badcards) / sizeof(u_int32_t)) 233 234 /* The actual rates supported by the card. */ 235 static int samplerates[9] = { 236 8000, 237 11025, 238 16000, 239 22050, 240 24000, 241 32000, 242 44100, 243 48000, 244 99999999 245 }; 246 247 /* -------------------------------------------------------------------- */ 248 249 struct audio_hw_if neo_hw_if = { 250 neo_open, 251 neo_close, 252 NULL, 253 neo_query_encoding, 254 neo_set_params, 255 #if 1 256 neo_round_blocksize, 257 #else 258 NULL, 259 #endif 260 NULL, 261 NULL, 262 NULL, 263 NULL, 264 NULL, 265 neo_halt_output, 266 neo_halt_input, 267 NULL, 268 neo_getdev, 269 NULL, 270 neo_mixer_set_port, 271 neo_mixer_get_port, 272 neo_query_devinfo, 273 neo_malloc, 274 neo_free, 275 neo_round_buffersize, 276 0, /* neo_mappage, */ 277 neo_get_props, 278 neo_trigger_output, 279 neo_trigger_input, 280 281 }; 282 283 /* -------------------------------------------------------------------- */ 284 285 /* Hardware */ 286 static u_int32_t 287 nm_rd(struct neo_softc *sc, int regno, int size) 288 { 289 bus_space_tag_t st = sc->regiot; 290 bus_space_handle_t sh = sc->regioh; 291 292 switch (size) { 293 case 1: 294 return bus_space_read_1(st, sh, regno); 295 case 2: 296 return bus_space_read_2(st, sh, regno); 297 case 4: 298 return bus_space_read_4(st, sh, regno); 299 default: 300 return 0xffffffff; 301 } 302 } 303 304 static void 305 nm_wr(struct neo_softc *sc, int regno, u_int32_t data, int size) 306 { 307 bus_space_tag_t st = sc->regiot; 308 bus_space_handle_t sh = sc->regioh; 309 310 switch (size) { 311 case 1: 312 bus_space_write_1(st, sh, regno, data); 313 break; 314 case 2: 315 bus_space_write_2(st, sh, regno, data); 316 break; 317 case 4: 318 bus_space_write_4(st, sh, regno, data); 319 break; 320 } 321 } 322 323 static u_int32_t 324 nm_rdbuf(struct neo_softc *sc, int regno, int size) 325 { 326 bus_space_tag_t st = sc->bufiot; 327 bus_space_handle_t sh = sc->bufioh; 328 329 switch (size) { 330 case 1: 331 return bus_space_read_1(st, sh, regno); 332 case 2: 333 return bus_space_read_2(st, sh, regno); 334 case 4: 335 return bus_space_read_4(st, sh, regno); 336 default: 337 return 0xffffffff; 338 } 339 } 340 341 static void 342 nm_wrbuf(struct neo_softc *sc, int regno, u_int32_t data, int size) 343 { 344 bus_space_tag_t st = sc->bufiot; 345 bus_space_handle_t sh = sc->bufioh; 346 347 switch (size) { 348 case 1: 349 bus_space_write_1(st, sh, regno, data); 350 break; 351 case 2: 352 bus_space_write_2(st, sh, regno, data); 353 break; 354 case 4: 355 bus_space_write_4(st, sh, regno, data); 356 break; 357 } 358 } 359 360 /* ac97 codec */ 361 static int 362 nm_waitcd(struct neo_softc *sc) 363 { 364 int cnt = 10; 365 int fail = 1; 366 367 while (cnt-- > 0) { 368 if (nm_rd(sc, sc->ac97_status, 2) & sc->ac97_busy) 369 DELAY(100); 370 else { 371 fail = 0; 372 break; 373 } 374 } 375 return (fail); 376 } 377 378 379 static void 380 nm_ackint(struct neo_softc *sc, u_int32_t num) 381 { 382 if (sc->type == NM256AV_PCI_ID) { 383 nm_wr(sc, NM_INT_REG, num << 1, 2); 384 } else if (sc->type == NM256ZX_PCI_ID) { 385 nm_wr(sc, NM_INT_REG, num, 4); 386 } 387 } 388 389 static int 390 nm_loadcoeff(struct neo_softc *sc, int dir, int num) 391 { 392 int ofs, sz, i; 393 u_int32_t addr; 394 395 addr = (dir == AUMODE_PLAY)? 0x01c : 0x21c; 396 if (dir == AUMODE_RECORD) 397 num += 8; 398 sz = coefficientSizes[num]; 399 ofs = 0; 400 while (num-- > 0) 401 ofs+= coefficientSizes[num]; 402 for (i = 0; i < sz; i++) 403 nm_wrbuf(sc, sc->cbuf + i, coefficients[ofs + i], 1); 404 nm_wr(sc, addr, sc->cbuf, 4); 405 if (dir == AUMODE_PLAY) 406 sz--; 407 nm_wr(sc, addr + 4, sc->cbuf + sz, 4); 408 return 0; 409 } 410 411 int 412 nmchan_getptr(sc, mode) 413 struct neo_softc *sc; 414 int mode; 415 { 416 if (mode == AUMODE_PLAY) 417 return nm_rd(sc, NM_PBUFFER_CURRP, 4) - sc->pbuf; 418 else 419 return nm_rd(sc, NM_RBUFFER_CURRP, 4) - sc->rbuf; 420 } 421 422 423 /* The interrupt handler */ 424 int 425 neo_intr(void *p) 426 { 427 struct neo_softc *sc = (struct neo_softc *)p; 428 int status, x, active; 429 int rv = 0; 430 431 active = (sc->pintr || sc->rintr); 432 status = nm_rd(sc, NM_INT_REG, sc->irsz); 433 434 if (status & sc->playint) { 435 status &= ~sc->playint; 436 437 sc->pwmark += sc->pblksize; 438 sc->pwmark %= sc->pbufsize; 439 440 nm_wr(sc, NM_PBUFFER_WMARK, sc->pbuf + sc->pwmark, 4); 441 442 nm_ackint(sc, sc->playint); 443 444 if (sc->pintr) 445 (*sc->pintr)(sc->parg); 446 447 rv = 1; 448 } 449 if (status & sc->recint) { 450 status &= ~sc->recint; 451 452 sc->rwmark += sc->rblksize; 453 sc->rwmark %= sc->rbufsize; 454 455 nm_ackint(sc, sc->recint); 456 if (sc->rintr) 457 (*sc->rintr)(sc->rarg); 458 459 rv = 1; 460 } 461 if (status & sc->misc1int) { 462 status &= ~sc->misc1int; 463 nm_ackint(sc, sc->misc1int); 464 x = nm_rd(sc, 0x400, 1); 465 nm_wr(sc, 0x400, x | 2, 1); 466 printf("%s: misc int 1\n", sc->dev.dv_xname); 467 rv = 1; 468 } 469 if (status & sc->misc2int) { 470 status &= ~sc->misc2int; 471 nm_ackint(sc, sc->misc2int); 472 x = nm_rd(sc, 0x400, 1); 473 nm_wr(sc, 0x400, x & ~2, 1); 474 printf("%s: misc int 2\n", sc->dev.dv_xname); 475 rv = 1; 476 } 477 if (status) { 478 status &= ~sc->misc2int; 479 nm_ackint(sc, sc->misc2int); 480 printf("%s: unknown int\n", sc->dev.dv_xname); 481 rv = 1; 482 } 483 484 return (rv); 485 } 486 487 /* -------------------------------------------------------------------- */ 488 489 /* 490 * Probe and attach the card 491 */ 492 493 static int 494 nm_init(struct neo_softc *sc) 495 { 496 u_int32_t ofs, i; 497 498 if (sc->type == NM256AV_PCI_ID) { 499 sc->ac97_base = NM_MIXER_OFFSET; 500 sc->ac97_status = NM_MIXER_STATUS_OFFSET; 501 sc->ac97_busy = NM_MIXER_READY_MASK; 502 503 sc->buftop = 2560 * 1024; 504 505 sc->irsz = 2; 506 sc->playint = NM_PLAYBACK_INT; 507 sc->recint = NM_RECORD_INT; 508 sc->misc1int = NM_MISC_INT_1; 509 sc->misc2int = NM_MISC_INT_2; 510 } else if (sc->type == NM256ZX_PCI_ID) { 511 sc->ac97_base = NM_MIXER_OFFSET; 512 sc->ac97_status = NM2_MIXER_STATUS_OFFSET; 513 sc->ac97_busy = NM2_MIXER_READY_MASK; 514 515 sc->buftop = (nm_rd(sc, 0xa0b, 2)? 6144 : 4096) * 1024; 516 517 sc->irsz = 4; 518 sc->playint = NM2_PLAYBACK_INT; 519 sc->recint = NM2_RECORD_INT; 520 sc->misc1int = NM2_MISC_INT_1; 521 sc->misc2int = NM2_MISC_INT_2; 522 } else return -1; 523 sc->badintr = 0; 524 ofs = sc->buftop - 0x0400; 525 sc->buftop -= 0x1400; 526 527 if ((nm_rdbuf(sc, ofs, 4) & NM_SIG_MASK) == NM_SIGNATURE) { 528 i = nm_rdbuf(sc, ofs + 4, 4); 529 if (i != 0 && i != 0xffffffff) 530 sc->buftop = i; 531 } 532 533 sc->cbuf = sc->buftop - NM_MAX_COEFFICIENT; 534 sc->rbuf = sc->cbuf - NM_BUFFSIZE; 535 sc->pbuf = sc->rbuf - NM_BUFFSIZE; 536 sc->acbuf = sc->pbuf - (NM_TOTAL_COEFF_COUNT * 4); 537 538 nm_wr(sc, 0, 0x11, 1); 539 nm_wr(sc, NM_RECORD_ENABLE_REG, 0, 1); 540 nm_wr(sc, 0x214, 0, 2); 541 542 return 0; 543 } 544 545 546 void 547 neo_attach(parent, self, aux) 548 struct device *parent; 549 struct device *self; 550 void *aux; 551 { 552 struct neo_softc *sc = (struct neo_softc *)self; 553 struct pci_attach_args *pa = (struct pci_attach_args *)aux; 554 pci_chipset_tag_t pc = pa->pa_pc; 555 char const *intrstr; 556 pci_intr_handle_t ih; 557 pcireg_t csr; 558 int error; 559 560 sc->type = pa->pa_id; 561 562 /* Map I/O register */ 563 if (pci_mapreg_map(pa, PCI_MAPS, PCI_MAPREG_TYPE_MEM, 0, 564 &sc->bufiot, &sc->bufioh, NULL, NULL, 0)) { 565 printf("\n%s: can't map i/o space\n", sc->dev.dv_xname); 566 return; 567 } 568 569 570 if (pci_mapreg_map(pa, PCI_MAPS + 4, PCI_MAPREG_TYPE_MEM, 0, 571 &sc->regiot, &sc->regioh, NULL, NULL, 0)) { 572 printf("\n%s: can't map i/o space\n", sc->dev.dv_xname); 573 return; 574 } 575 576 /* Map and establish the interrupt. */ 577 if (pci_intr_map(pa, &ih)) { 578 printf("\n%s: couldn't map interrupt\n", sc->dev.dv_xname); 579 return; 580 } 581 intrstr = pci_intr_string(pc, ih); 582 sc->ih = pci_intr_establish(pc, ih, IPL_AUDIO, neo_intr, sc, 583 sc->dev.dv_xname); 584 585 if (sc->ih == NULL) { 586 printf("\n%s: couldn't establish interrupt", 587 sc->dev.dv_xname); 588 if (intrstr != NULL) 589 printf(" at %s", intrstr); 590 printf("\n"); 591 return; 592 } 593 printf(": %s\n", intrstr); 594 595 if ((error = nm_init(sc)) != 0) 596 return; 597 598 /* Enable the device. */ 599 csr = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG); 600 pci_conf_write(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG, 601 csr | PCI_COMMAND_MASTER_ENABLE); 602 603 sc->host_if.arg = sc; 604 605 sc->host_if.attach = neo_attach_codec; 606 sc->host_if.read = neo_read_codec; 607 sc->host_if.write = neo_write_codec; 608 sc->host_if.reset = neo_reset_codec; 609 sc->host_if.flags = neo_flags_codec; 610 611 if ((error = ac97_attach(&sc->host_if)) != 0) 612 return; 613 614 audio_attach_mi(&neo_hw_if, sc, &sc->dev); 615 616 return; 617 } 618 619 int 620 neo_match(parent, match, aux) 621 struct device *parent; 622 void *match; 623 void *aux; 624 { 625 struct pci_attach_args *pa = (struct pci_attach_args *) aux; 626 #if 0 627 u_int32_t subdev, badcard; 628 #endif 629 630 if (PCI_VENDOR(pa->pa_id) != PCI_VENDOR_NEOMAGIC) 631 return (0); 632 633 #if 0 634 subdev = (pci_get_subdevice(dev) << 16) | pci_get_subvendor(dev); 635 #endif 636 switch (PCI_PRODUCT(pa->pa_id)) { 637 case PCI_PRODUCT_NEOMAGIC_NM256AV: 638 #if 0 639 i = 0; 640 while ((i < NUM_BADCARDS) && (badcards[i] != subdev)) 641 i++; 642 if (i == NUM_BADCARDS) 643 s = "NeoMagic 256AV"; 644 DEB(else) 645 DEB(device_printf(dev, "this is a non-ac97 NM256AV, not attaching\n")); 646 return (1); 647 #endif 648 case PCI_PRODUCT_NEOMAGIC_NM256ZX: 649 return (1); 650 } 651 652 return (0); 653 } 654 655 int 656 neo_read_codec(sc_, a, d) 657 void *sc_; 658 u_int8_t a; 659 u_int16_t *d; 660 { 661 struct neo_softc *sc = sc_; 662 663 if (!nm_waitcd(sc)) { 664 *d = nm_rd(sc, sc->ac97_base + a, 2); 665 DELAY(1000); 666 return 0; 667 } 668 669 return (ENXIO); 670 } 671 672 673 int 674 neo_write_codec(sc_, a, d) 675 void *sc_; 676 u_int8_t a; 677 u_int16_t d; 678 { 679 struct neo_softc *sc = sc_; 680 int cnt = 3; 681 682 if (!nm_waitcd(sc)) { 683 while (cnt-- > 0) { 684 nm_wr(sc, sc->ac97_base + a, d, 2); 685 if (!nm_waitcd(sc)) { 686 DELAY(1000); 687 return (0); 688 } 689 } 690 } 691 692 return (ENXIO); 693 } 694 695 696 int 697 neo_attach_codec(sc_, codec_if) 698 void *sc_; 699 struct ac97_codec_if *codec_if; 700 { 701 struct neo_softc *sc = sc_; 702 703 sc->codec_if = codec_if; 704 return (0); 705 } 706 707 void 708 neo_reset_codec(sc) 709 void *sc; 710 { 711 nm_wr(sc, 0x6c0, 0x01, 1); 712 nm_wr(sc, 0x6cc, 0x87, 1); 713 nm_wr(sc, 0x6cc, 0x80, 1); 714 nm_wr(sc, 0x6cc, 0x00, 1); 715 716 return; 717 } 718 719 720 enum ac97_host_flags 721 neo_flags_codec(sc) 722 void *sc; 723 { 724 return (AC97_HOST_DONT_READANY); 725 } 726 727 int 728 neo_open(addr, flags) 729 void *addr; 730 int flags; 731 { 732 return (0); 733 } 734 735 /* 736 * Close function is called at splaudio(). 737 */ 738 void 739 neo_close(addr) 740 void *addr; 741 { 742 struct neo_softc *sc = addr; 743 744 neo_halt_output(sc); 745 neo_halt_input(sc); 746 747 sc->pintr = 0; 748 sc->rintr = 0; 749 } 750 751 int 752 neo_query_encoding(addr, fp) 753 void *addr; 754 struct audio_encoding *fp; 755 { 756 switch (fp->index) { 757 case 0: 758 strcpy(fp->name, AudioEulinear); 759 fp->encoding = AUDIO_ENCODING_ULINEAR; 760 fp->precision = 8; 761 fp->flags = 0; 762 return (0); 763 case 1: 764 strcpy(fp->name, AudioEmulaw); 765 fp->encoding = AUDIO_ENCODING_ULAW; 766 fp->precision = 8; 767 fp->flags = AUDIO_ENCODINGFLAG_EMULATED; 768 return (0); 769 case 2: 770 strcpy(fp->name, AudioEalaw); 771 fp->encoding = AUDIO_ENCODING_ALAW; 772 fp->precision = 8; 773 fp->flags = AUDIO_ENCODINGFLAG_EMULATED; 774 return (0); 775 case 3: 776 strcpy(fp->name, AudioEslinear); 777 fp->encoding = AUDIO_ENCODING_SLINEAR; 778 fp->precision = 8; 779 fp->flags = AUDIO_ENCODINGFLAG_EMULATED; 780 return (0); 781 case 4: 782 strcpy(fp->name, AudioEslinear_le); 783 fp->encoding = AUDIO_ENCODING_SLINEAR_LE; 784 fp->precision = 16; 785 fp->flags = 0; 786 return (0); 787 case 5: 788 strcpy(fp->name, AudioEulinear_le); 789 fp->encoding = AUDIO_ENCODING_ULINEAR_LE; 790 fp->precision = 16; 791 fp->flags = AUDIO_ENCODINGFLAG_EMULATED; 792 return (0); 793 case 6: 794 strcpy(fp->name, AudioEslinear_be); 795 fp->encoding = AUDIO_ENCODING_SLINEAR_BE; 796 fp->precision = 16; 797 fp->flags = AUDIO_ENCODINGFLAG_EMULATED; 798 return (0); 799 case 7: 800 strcpy(fp->name, AudioEulinear_be); 801 fp->encoding = AUDIO_ENCODING_ULINEAR_BE; 802 fp->precision = 16; 803 fp->flags = AUDIO_ENCODINGFLAG_EMULATED; 804 return (0); 805 default: 806 return (EINVAL); 807 } 808 } 809 810 /* Todo: don't commit settings to card until we've verified all parameters */ 811 int 812 neo_set_params(addr, setmode, usemode, play, rec) 813 void *addr; 814 int setmode, usemode; 815 struct audio_params *play, *rec; 816 { 817 struct neo_softc *sc = addr; 818 u_int32_t base; 819 u_int8_t x; 820 int mode; 821 struct audio_params *p; 822 823 for (mode = AUMODE_RECORD; mode != -1; 824 mode = mode == AUMODE_RECORD ? AUMODE_PLAY : -1) { 825 if ((setmode & mode) == 0) 826 continue; 827 828 p = mode == AUMODE_PLAY ? play : rec; 829 830 if (p == NULL) continue; 831 832 for (x = 0; x < 8; x++) 833 if (p->sample_rate < (samplerates[x] + samplerates[x + 1]) / 2) 834 break; 835 836 if (x == 8) return (EINVAL); 837 838 p->sample_rate = samplerates[x]; 839 nm_loadcoeff(sc, mode, x); 840 841 x <<= 4; 842 x &= NM_RATE_MASK; 843 if (p->precision == 16) x |= NM_RATE_BITS_16; 844 if (p->channels == 2) x |= NM_RATE_STEREO; 845 846 base = (mode == AUMODE_PLAY)? 847 NM_PLAYBACK_REG_OFFSET : NM_RECORD_REG_OFFSET; 848 nm_wr(sc, base + NM_RATE_REG_OFFSET, x, 1); 849 850 p->factor = 1; 851 p->sw_code = 0; 852 switch (p->encoding) { 853 case AUDIO_ENCODING_SLINEAR_BE: 854 if (p->precision == 16) 855 p->sw_code = swap_bytes; 856 else 857 p->sw_code = change_sign8; 858 break; 859 case AUDIO_ENCODING_SLINEAR_LE: 860 if (p->precision != 16) 861 p->sw_code = change_sign8; 862 break; 863 case AUDIO_ENCODING_ULINEAR_BE: 864 if (p->precision == 16) { 865 if (mode == AUMODE_PLAY) 866 p->sw_code = swap_bytes_change_sign16; 867 else 868 p->sw_code = change_sign16_swap_bytes; 869 } 870 break; 871 case AUDIO_ENCODING_ULINEAR_LE: 872 if (p->precision == 16) 873 p->sw_code = change_sign16; 874 break; 875 case AUDIO_ENCODING_ULAW: 876 if (mode == AUMODE_PLAY) { 877 p->factor = 2; 878 p->sw_code = mulaw_to_slinear16; 879 } else 880 p->sw_code = ulinear8_to_mulaw; 881 break; 882 case AUDIO_ENCODING_ALAW: 883 if (mode == AUMODE_PLAY) { 884 p->factor = 2; 885 p->sw_code = alaw_to_slinear16; 886 } else 887 p->sw_code = ulinear8_to_alaw; 888 break; 889 default: 890 return (EINVAL); 891 } 892 } 893 894 895 return (0); 896 } 897 898 int 899 neo_round_blocksize(addr, blk) 900 void *addr; 901 int blk; 902 { 903 return (NM_BUFFSIZE / 2); 904 } 905 906 int 907 neo_trigger_output(addr, start, end, blksize, intr, arg, param) 908 void *addr; 909 void *start, *end; 910 int blksize; 911 void (*intr) __P((void *)); 912 void *arg; 913 struct audio_params *param; 914 { 915 struct neo_softc *sc = addr; 916 int ssz; 917 918 sc->pintr = intr; 919 sc->parg = arg; 920 921 ssz = (param->precision * param->factor == 16)? 2 : 1; 922 if (param->channels == 2) 923 ssz <<= 1; 924 925 sc->pbufsize = ((char*)end - (char *)start); 926 sc->pblksize = blksize; 927 sc->pwmark = blksize; 928 929 nm_wr(sc, NM_PBUFFER_START, sc->pbuf, 4); 930 nm_wr(sc, NM_PBUFFER_END, sc->pbuf + sc->pbufsize - ssz, 4); 931 nm_wr(sc, NM_PBUFFER_CURRP, sc->pbuf, 4); 932 nm_wr(sc, NM_PBUFFER_WMARK, sc->pbuf + sc->pwmark, 4); 933 nm_wr(sc, NM_PLAYBACK_ENABLE_REG, NM_PLAYBACK_FREERUN | 934 NM_PLAYBACK_ENABLE_FLAG, 1); 935 nm_wr(sc, NM_AUDIO_MUTE_REG, 0, 2); 936 937 return (0); 938 } 939 940 941 942 int 943 neo_trigger_input(addr, start, end, blksize, intr, arg, param) 944 void *addr; 945 void *start, *end; 946 int blksize; 947 void (*intr) __P((void *)); 948 void *arg; 949 struct audio_params *param; 950 { 951 struct neo_softc *sc = addr; 952 int ssz; 953 954 sc->rintr = intr; 955 sc->rarg = arg; 956 957 ssz = (param->precision * param->factor == 16)? 2 : 1; 958 if (param->channels == 2) 959 ssz <<= 1; 960 961 sc->rbufsize = ((char*)end - (char *)start); 962 sc->rblksize = blksize; 963 sc->rwmark = blksize; 964 965 nm_wr(sc, NM_RBUFFER_START, sc->rbuf, 4); 966 nm_wr(sc, NM_RBUFFER_END, sc->rbuf + sc->rbufsize, 4); 967 nm_wr(sc, NM_RBUFFER_CURRP, sc->rbuf, 4); 968 nm_wr(sc, NM_RBUFFER_WMARK, sc->rbuf + sc->rwmark, 4); 969 nm_wr(sc, NM_RECORD_ENABLE_REG, NM_RECORD_FREERUN | 970 NM_RECORD_ENABLE_FLAG, 1); 971 972 return (0); 973 } 974 975 int 976 neo_halt_output(addr) 977 void *addr; 978 { 979 struct neo_softc *sc = (struct neo_softc *)addr; 980 981 nm_wr(sc, NM_PLAYBACK_ENABLE_REG, 0, 1); 982 nm_wr(sc, NM_AUDIO_MUTE_REG, NM_AUDIO_MUTE_BOTH, 2); 983 984 sc->pintr = 0; 985 986 return (0); 987 } 988 989 int 990 neo_halt_input(addr) 991 void *addr; 992 { 993 struct neo_softc *sc = (struct neo_softc *)addr; 994 995 nm_wr(sc, NM_RECORD_ENABLE_REG, 0, 1); 996 997 sc->rintr = 0; 998 999 return (0); 1000 } 1001 1002 int 1003 neo_getdev(addr, retp) 1004 void *addr; 1005 struct audio_device *retp; 1006 { 1007 *retp = neo_device; 1008 return (0); 1009 } 1010 1011 int 1012 neo_mixer_set_port(addr, cp) 1013 void *addr; 1014 mixer_ctrl_t *cp; 1015 { 1016 struct neo_softc *sc = addr; 1017 1018 return ((sc->codec_if->vtbl->mixer_set_port)(sc->codec_if, 1019 cp)); 1020 } 1021 1022 int 1023 neo_mixer_get_port(addr, cp) 1024 void *addr; 1025 mixer_ctrl_t *cp; 1026 { 1027 struct neo_softc *sc = addr; 1028 1029 return ((sc->codec_if->vtbl->mixer_get_port)(sc->codec_if, 1030 cp)); 1031 } 1032 1033 int 1034 neo_query_devinfo(addr, dip) 1035 void *addr; 1036 mixer_devinfo_t *dip; 1037 { 1038 struct neo_softc *sc = addr; 1039 1040 return ((sc->codec_if->vtbl->query_devinfo)(sc->codec_if, dip)); 1041 } 1042 1043 void * 1044 neo_malloc(addr, direction, size, pool, flags) 1045 void *addr; 1046 int direction; 1047 size_t size; 1048 int pool, flags; 1049 { 1050 struct neo_softc *sc = addr; 1051 void *rv = 0; 1052 1053 switch (direction) { 1054 case AUMODE_PLAY: 1055 rv = (char *)sc->bufioh + sc->pbuf; 1056 break; 1057 case AUMODE_RECORD: 1058 rv = (char *)sc->bufioh + sc->rbuf; 1059 break; 1060 default: 1061 break; 1062 } 1063 1064 return (rv); 1065 } 1066 1067 void 1068 neo_free(addr, ptr, pool) 1069 void *addr; 1070 void *ptr; 1071 int pool; 1072 { 1073 return; 1074 } 1075 1076 size_t 1077 neo_round_buffersize(addr, direction, size) 1078 void *addr; 1079 int direction; 1080 size_t size; 1081 { 1082 return (NM_BUFFSIZE); 1083 } 1084 1085 1086 int 1087 neo_get_props(addr) 1088 void *addr; 1089 { 1090 1091 return (AUDIO_PROP_INDEPENDENT | 1092 AUDIO_PROP_FULLDUPLEX); 1093 } 1094