1 /* $OpenBSD: neo.c,v 1.9 2001/09/16 18:32:34 art 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 NULL, /* neo_malloc_old, */ 274 neo_free, 275 NULL, /* neo_round_buffersize_old, */ 276 0, /* neo_mappage, */ 277 neo_get_props, 278 neo_trigger_output, 279 neo_trigger_input, 280 neo_malloc, 281 neo_round_buffersize, 282 283 }; 284 285 /* -------------------------------------------------------------------- */ 286 287 /* Hardware */ 288 static u_int32_t 289 nm_rd(struct neo_softc *sc, int regno, int size) 290 { 291 bus_space_tag_t st = sc->regiot; 292 bus_space_handle_t sh = sc->regioh; 293 294 switch (size) { 295 case 1: 296 return bus_space_read_1(st, sh, regno); 297 case 2: 298 return bus_space_read_2(st, sh, regno); 299 case 4: 300 return bus_space_read_4(st, sh, regno); 301 default: 302 return 0xffffffff; 303 } 304 } 305 306 static void 307 nm_wr(struct neo_softc *sc, int regno, u_int32_t data, int size) 308 { 309 bus_space_tag_t st = sc->regiot; 310 bus_space_handle_t sh = sc->regioh; 311 312 switch (size) { 313 case 1: 314 bus_space_write_1(st, sh, regno, data); 315 break; 316 case 2: 317 bus_space_write_2(st, sh, regno, data); 318 break; 319 case 4: 320 bus_space_write_4(st, sh, regno, data); 321 break; 322 } 323 } 324 325 static u_int32_t 326 nm_rdbuf(struct neo_softc *sc, int regno, int size) 327 { 328 bus_space_tag_t st = sc->bufiot; 329 bus_space_handle_t sh = sc->bufioh; 330 331 switch (size) { 332 case 1: 333 return bus_space_read_1(st, sh, regno); 334 case 2: 335 return bus_space_read_2(st, sh, regno); 336 case 4: 337 return bus_space_read_4(st, sh, regno); 338 default: 339 return 0xffffffff; 340 } 341 } 342 343 static void 344 nm_wrbuf(struct neo_softc *sc, int regno, u_int32_t data, int size) 345 { 346 bus_space_tag_t st = sc->bufiot; 347 bus_space_handle_t sh = sc->bufioh; 348 349 switch (size) { 350 case 1: 351 bus_space_write_1(st, sh, regno, data); 352 break; 353 case 2: 354 bus_space_write_2(st, sh, regno, data); 355 break; 356 case 4: 357 bus_space_write_4(st, sh, regno, data); 358 break; 359 } 360 } 361 362 /* ac97 codec */ 363 static int 364 nm_waitcd(struct neo_softc *sc) 365 { 366 int cnt = 10; 367 int fail = 1; 368 369 while (cnt-- > 0) { 370 if (nm_rd(sc, sc->ac97_status, 2) & sc->ac97_busy) 371 DELAY(100); 372 else { 373 fail = 0; 374 break; 375 } 376 } 377 return (fail); 378 } 379 380 381 static void 382 nm_ackint(struct neo_softc *sc, u_int32_t num) 383 { 384 if (sc->type == NM256AV_PCI_ID) { 385 nm_wr(sc, NM_INT_REG, num << 1, 2); 386 } else if (sc->type == NM256ZX_PCI_ID) { 387 nm_wr(sc, NM_INT_REG, num, 4); 388 } 389 } 390 391 static int 392 nm_loadcoeff(struct neo_softc *sc, int dir, int num) 393 { 394 int ofs, sz, i; 395 u_int32_t addr; 396 397 addr = (dir == AUMODE_PLAY)? 0x01c : 0x21c; 398 if (dir == AUMODE_RECORD) 399 num += 8; 400 sz = coefficientSizes[num]; 401 ofs = 0; 402 while (num-- > 0) 403 ofs+= coefficientSizes[num]; 404 for (i = 0; i < sz; i++) 405 nm_wrbuf(sc, sc->cbuf + i, coefficients[ofs + i], 1); 406 nm_wr(sc, addr, sc->cbuf, 4); 407 if (dir == AUMODE_PLAY) 408 sz--; 409 nm_wr(sc, addr + 4, sc->cbuf + sz, 4); 410 return 0; 411 } 412 413 int 414 nmchan_getptr(sc, mode) 415 struct neo_softc *sc; 416 int mode; 417 { 418 if (mode == AUMODE_PLAY) 419 return nm_rd(sc, NM_PBUFFER_CURRP, 4) - sc->pbuf; 420 else 421 return nm_rd(sc, NM_RBUFFER_CURRP, 4) - sc->rbuf; 422 } 423 424 425 /* The interrupt handler */ 426 int 427 neo_intr(void *p) 428 { 429 struct neo_softc *sc = (struct neo_softc *)p; 430 int status, x, active; 431 int rv = 0; 432 433 active = (sc->pintr || sc->rintr); 434 status = nm_rd(sc, NM_INT_REG, sc->irsz); 435 436 if (status & sc->playint) { 437 status &= ~sc->playint; 438 439 sc->pwmark += sc->pblksize; 440 sc->pwmark %= sc->pbufsize; 441 442 nm_wr(sc, NM_PBUFFER_WMARK, sc->pbuf + sc->pwmark, 4); 443 444 nm_ackint(sc, sc->playint); 445 446 if (sc->pintr) 447 (*sc->pintr)(sc->parg); 448 449 rv = 1; 450 } 451 if (status & sc->recint) { 452 status &= ~sc->recint; 453 454 sc->rwmark += sc->rblksize; 455 sc->rwmark %= sc->rbufsize; 456 457 nm_ackint(sc, sc->recint); 458 if (sc->rintr) 459 (*sc->rintr)(sc->rarg); 460 461 rv = 1; 462 } 463 if (status & sc->misc1int) { 464 status &= ~sc->misc1int; 465 nm_ackint(sc, sc->misc1int); 466 x = nm_rd(sc, 0x400, 1); 467 nm_wr(sc, 0x400, x | 2, 1); 468 printf("%s: misc int 1\n", sc->dev.dv_xname); 469 rv = 1; 470 } 471 if (status & sc->misc2int) { 472 status &= ~sc->misc2int; 473 nm_ackint(sc, sc->misc2int); 474 x = nm_rd(sc, 0x400, 1); 475 nm_wr(sc, 0x400, x & ~2, 1); 476 printf("%s: misc int 2\n", sc->dev.dv_xname); 477 rv = 1; 478 } 479 if (status) { 480 status &= ~sc->misc2int; 481 nm_ackint(sc, sc->misc2int); 482 printf("%s: unknown int\n", sc->dev.dv_xname); 483 rv = 1; 484 } 485 486 return (rv); 487 } 488 489 /* -------------------------------------------------------------------- */ 490 491 /* 492 * Probe and attach the card 493 */ 494 495 static int 496 nm_init(struct neo_softc *sc) 497 { 498 u_int32_t ofs, i; 499 500 if (sc->type == NM256AV_PCI_ID) { 501 sc->ac97_base = NM_MIXER_OFFSET; 502 sc->ac97_status = NM_MIXER_STATUS_OFFSET; 503 sc->ac97_busy = NM_MIXER_READY_MASK; 504 505 sc->buftop = 2560 * 1024; 506 507 sc->irsz = 2; 508 sc->playint = NM_PLAYBACK_INT; 509 sc->recint = NM_RECORD_INT; 510 sc->misc1int = NM_MISC_INT_1; 511 sc->misc2int = NM_MISC_INT_2; 512 } else if (sc->type == NM256ZX_PCI_ID) { 513 sc->ac97_base = NM_MIXER_OFFSET; 514 sc->ac97_status = NM2_MIXER_STATUS_OFFSET; 515 sc->ac97_busy = NM2_MIXER_READY_MASK; 516 517 sc->buftop = (nm_rd(sc, 0xa0b, 2)? 6144 : 4096) * 1024; 518 519 sc->irsz = 4; 520 sc->playint = NM2_PLAYBACK_INT; 521 sc->recint = NM2_RECORD_INT; 522 sc->misc1int = NM2_MISC_INT_1; 523 sc->misc2int = NM2_MISC_INT_2; 524 } else return -1; 525 sc->badintr = 0; 526 ofs = sc->buftop - 0x0400; 527 sc->buftop -= 0x1400; 528 529 if ((nm_rdbuf(sc, ofs, 4) & NM_SIG_MASK) == NM_SIGNATURE) { 530 i = nm_rdbuf(sc, ofs + 4, 4); 531 if (i != 0 && i != 0xffffffff) 532 sc->buftop = i; 533 } 534 535 sc->cbuf = sc->buftop - NM_MAX_COEFFICIENT; 536 sc->rbuf = sc->cbuf - NM_BUFFSIZE; 537 sc->pbuf = sc->rbuf - NM_BUFFSIZE; 538 sc->acbuf = sc->pbuf - (NM_TOTAL_COEFF_COUNT * 4); 539 540 nm_wr(sc, 0, 0x11, 1); 541 nm_wr(sc, NM_RECORD_ENABLE_REG, 0, 1); 542 nm_wr(sc, 0x214, 0, 2); 543 544 return 0; 545 } 546 547 548 void 549 neo_attach(parent, self, aux) 550 struct device *parent; 551 struct device *self; 552 void *aux; 553 { 554 struct neo_softc *sc = (struct neo_softc *)self; 555 struct pci_attach_args *pa = (struct pci_attach_args *)aux; 556 pci_chipset_tag_t pc = pa->pa_pc; 557 char const *intrstr; 558 pci_intr_handle_t ih; 559 pcireg_t csr; 560 int error; 561 562 sc->type = pa->pa_id; 563 564 /* Map I/O register */ 565 if (pci_mapreg_map(pa, PCI_MAPS, PCI_MAPREG_TYPE_MEM, 0, 566 &sc->bufiot, &sc->bufioh, NULL, NULL, 0)) { 567 printf("\n%s: can't map i/o space\n", sc->dev.dv_xname); 568 return; 569 } 570 571 572 if (pci_mapreg_map(pa, PCI_MAPS + 4, PCI_MAPREG_TYPE_MEM, 0, 573 &sc->regiot, &sc->regioh, NULL, NULL, 0)) { 574 printf("\n%s: can't map i/o space\n", sc->dev.dv_xname); 575 return; 576 } 577 578 /* Map and establish the interrupt. */ 579 if (pci_intr_map(pa, &ih)) { 580 printf("\n%s: couldn't map interrupt\n", sc->dev.dv_xname); 581 return; 582 } 583 intrstr = pci_intr_string(pc, ih); 584 sc->ih = pci_intr_establish(pc, ih, IPL_AUDIO, neo_intr, sc, 585 sc->dev.dv_xname); 586 587 if (sc->ih == NULL) { 588 printf("\n%s: couldn't establish interrupt", 589 sc->dev.dv_xname); 590 if (intrstr != NULL) 591 printf(" at %s", intrstr); 592 printf("\n"); 593 return; 594 } 595 printf(": %s\n", intrstr); 596 597 if ((error = nm_init(sc)) != 0) 598 return; 599 600 /* Enable the device. */ 601 csr = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG); 602 pci_conf_write(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG, 603 csr | PCI_COMMAND_MASTER_ENABLE); 604 605 sc->host_if.arg = sc; 606 607 sc->host_if.attach = neo_attach_codec; 608 sc->host_if.read = neo_read_codec; 609 sc->host_if.write = neo_write_codec; 610 sc->host_if.reset = neo_reset_codec; 611 sc->host_if.flags = neo_flags_codec; 612 613 if ((error = ac97_attach(&sc->host_if)) != 0) 614 return; 615 616 audio_attach_mi(&neo_hw_if, sc, &sc->dev); 617 618 return; 619 } 620 621 int 622 neo_match(parent, match, aux) 623 struct device *parent; 624 void *match; 625 void *aux; 626 { 627 struct pci_attach_args *pa = (struct pci_attach_args *) aux; 628 #if 0 629 u_int32_t subdev, badcard; 630 #endif 631 632 if (PCI_VENDOR(pa->pa_id) != PCI_VENDOR_NEOMAGIC) 633 return (0); 634 635 #if 0 636 subdev = (pci_get_subdevice(dev) << 16) | pci_get_subvendor(dev); 637 #endif 638 switch (PCI_PRODUCT(pa->pa_id)) { 639 case PCI_PRODUCT_NEOMAGIC_NM256AV: 640 #if 0 641 i = 0; 642 while ((i < NUM_BADCARDS) && (badcards[i] != subdev)) 643 i++; 644 if (i == NUM_BADCARDS) 645 s = "NeoMagic 256AV"; 646 DEB(else) 647 DEB(device_printf(dev, "this is a non-ac97 NM256AV, not attaching\n")); 648 return (1); 649 #endif 650 case PCI_PRODUCT_NEOMAGIC_NM256ZX: 651 return (1); 652 } 653 654 return (0); 655 } 656 657 int 658 neo_read_codec(sc_, a, d) 659 void *sc_; 660 u_int8_t a; 661 u_int16_t *d; 662 { 663 struct neo_softc *sc = sc_; 664 665 if (!nm_waitcd(sc)) { 666 *d = nm_rd(sc, sc->ac97_base + a, 2); 667 DELAY(1000); 668 return 0; 669 } 670 671 return (ENXIO); 672 } 673 674 675 int 676 neo_write_codec(sc_, a, d) 677 void *sc_; 678 u_int8_t a; 679 u_int16_t d; 680 { 681 struct neo_softc *sc = sc_; 682 int cnt = 3; 683 684 if (!nm_waitcd(sc)) { 685 while (cnt-- > 0) { 686 nm_wr(sc, sc->ac97_base + a, d, 2); 687 if (!nm_waitcd(sc)) { 688 DELAY(1000); 689 return (0); 690 } 691 } 692 } 693 694 return (ENXIO); 695 } 696 697 698 int 699 neo_attach_codec(sc_, codec_if) 700 void *sc_; 701 struct ac97_codec_if *codec_if; 702 { 703 struct neo_softc *sc = sc_; 704 705 sc->codec_if = codec_if; 706 return (0); 707 } 708 709 void 710 neo_reset_codec(sc) 711 void *sc; 712 { 713 nm_wr(sc, 0x6c0, 0x01, 1); 714 nm_wr(sc, 0x6cc, 0x87, 1); 715 nm_wr(sc, 0x6cc, 0x80, 1); 716 nm_wr(sc, 0x6cc, 0x00, 1); 717 718 return; 719 } 720 721 722 enum ac97_host_flags 723 neo_flags_codec(sc) 724 void *sc; 725 { 726 return (AC97_HOST_DONT_READANY); 727 } 728 729 int 730 neo_open(addr, flags) 731 void *addr; 732 int flags; 733 { 734 return (0); 735 } 736 737 /* 738 * Close function is called at splaudio(). 739 */ 740 void 741 neo_close(addr) 742 void *addr; 743 { 744 struct neo_softc *sc = addr; 745 746 neo_halt_output(sc); 747 neo_halt_input(sc); 748 749 sc->pintr = 0; 750 sc->rintr = 0; 751 } 752 753 int 754 neo_query_encoding(addr, fp) 755 void *addr; 756 struct audio_encoding *fp; 757 { 758 switch (fp->index) { 759 case 0: 760 strcpy(fp->name, AudioEulinear); 761 fp->encoding = AUDIO_ENCODING_ULINEAR; 762 fp->precision = 8; 763 fp->flags = 0; 764 return (0); 765 case 1: 766 strcpy(fp->name, AudioEmulaw); 767 fp->encoding = AUDIO_ENCODING_ULAW; 768 fp->precision = 8; 769 fp->flags = AUDIO_ENCODINGFLAG_EMULATED; 770 return (0); 771 case 2: 772 strcpy(fp->name, AudioEalaw); 773 fp->encoding = AUDIO_ENCODING_ALAW; 774 fp->precision = 8; 775 fp->flags = AUDIO_ENCODINGFLAG_EMULATED; 776 return (0); 777 case 3: 778 strcpy(fp->name, AudioEslinear); 779 fp->encoding = AUDIO_ENCODING_SLINEAR; 780 fp->precision = 8; 781 fp->flags = AUDIO_ENCODINGFLAG_EMULATED; 782 return (0); 783 case 4: 784 strcpy(fp->name, AudioEslinear_le); 785 fp->encoding = AUDIO_ENCODING_SLINEAR_LE; 786 fp->precision = 16; 787 fp->flags = 0; 788 return (0); 789 case 5: 790 strcpy(fp->name, AudioEulinear_le); 791 fp->encoding = AUDIO_ENCODING_ULINEAR_LE; 792 fp->precision = 16; 793 fp->flags = AUDIO_ENCODINGFLAG_EMULATED; 794 return (0); 795 case 6: 796 strcpy(fp->name, AudioEslinear_be); 797 fp->encoding = AUDIO_ENCODING_SLINEAR_BE; 798 fp->precision = 16; 799 fp->flags = AUDIO_ENCODINGFLAG_EMULATED; 800 return (0); 801 case 7: 802 strcpy(fp->name, AudioEulinear_be); 803 fp->encoding = AUDIO_ENCODING_ULINEAR_BE; 804 fp->precision = 16; 805 fp->flags = AUDIO_ENCODINGFLAG_EMULATED; 806 return (0); 807 default: 808 return (EINVAL); 809 } 810 } 811 812 /* Todo: don't commit settings to card until we've verified all parameters */ 813 int 814 neo_set_params(addr, setmode, usemode, play, rec) 815 void *addr; 816 int setmode, usemode; 817 struct audio_params *play, *rec; 818 { 819 struct neo_softc *sc = addr; 820 u_int32_t base; 821 u_int8_t x; 822 int mode; 823 struct audio_params *p; 824 825 for (mode = AUMODE_RECORD; mode != -1; 826 mode = mode == AUMODE_RECORD ? AUMODE_PLAY : -1) { 827 if ((setmode & mode) == 0) 828 continue; 829 830 p = mode == AUMODE_PLAY ? play : rec; 831 832 if (p == NULL) continue; 833 834 for (x = 0; x < 8; x++) 835 if (p->sample_rate < (samplerates[x] + samplerates[x + 1]) / 2) 836 break; 837 838 if (x == 8) return (EINVAL); 839 840 p->sample_rate = samplerates[x]; 841 nm_loadcoeff(sc, mode, x); 842 843 x <<= 4; 844 x &= NM_RATE_MASK; 845 if (p->precision == 16) x |= NM_RATE_BITS_16; 846 if (p->channels == 2) x |= NM_RATE_STEREO; 847 848 base = (mode == AUMODE_PLAY)? 849 NM_PLAYBACK_REG_OFFSET : NM_RECORD_REG_OFFSET; 850 nm_wr(sc, base + NM_RATE_REG_OFFSET, x, 1); 851 852 p->factor = 1; 853 p->sw_code = 0; 854 switch (p->encoding) { 855 case AUDIO_ENCODING_SLINEAR_BE: 856 if (p->precision == 16) 857 p->sw_code = swap_bytes; 858 else 859 p->sw_code = change_sign8; 860 break; 861 case AUDIO_ENCODING_SLINEAR_LE: 862 if (p->precision != 16) 863 p->sw_code = change_sign8; 864 break; 865 case AUDIO_ENCODING_ULINEAR_BE: 866 if (p->precision == 16) { 867 if (mode == AUMODE_PLAY) 868 p->sw_code = swap_bytes_change_sign16; 869 else 870 p->sw_code = change_sign16_swap_bytes; 871 } 872 break; 873 case AUDIO_ENCODING_ULINEAR_LE: 874 if (p->precision == 16) 875 p->sw_code = change_sign16; 876 break; 877 case AUDIO_ENCODING_ULAW: 878 if (mode == AUMODE_PLAY) { 879 p->factor = 2; 880 p->sw_code = mulaw_to_slinear16; 881 } else 882 p->sw_code = ulinear8_to_mulaw; 883 break; 884 case AUDIO_ENCODING_ALAW: 885 if (mode == AUMODE_PLAY) { 886 p->factor = 2; 887 p->sw_code = alaw_to_slinear16; 888 } else 889 p->sw_code = ulinear8_to_alaw; 890 break; 891 default: 892 return (EINVAL); 893 } 894 } 895 896 897 return (0); 898 } 899 900 int 901 neo_round_blocksize(addr, blk) 902 void *addr; 903 int blk; 904 { 905 return (NM_BUFFSIZE / 2); 906 } 907 908 int 909 neo_trigger_output(addr, start, end, blksize, intr, arg, param) 910 void *addr; 911 void *start, *end; 912 int blksize; 913 void (*intr) __P((void *)); 914 void *arg; 915 struct audio_params *param; 916 { 917 struct neo_softc *sc = addr; 918 int ssz; 919 920 sc->pintr = intr; 921 sc->parg = arg; 922 923 ssz = (param->precision * param->factor == 16)? 2 : 1; 924 if (param->channels == 2) 925 ssz <<= 1; 926 927 sc->pbufsize = ((char*)end - (char *)start); 928 sc->pblksize = blksize; 929 sc->pwmark = blksize; 930 931 nm_wr(sc, NM_PBUFFER_START, sc->pbuf, 4); 932 nm_wr(sc, NM_PBUFFER_END, sc->pbuf + sc->pbufsize - ssz, 4); 933 nm_wr(sc, NM_PBUFFER_CURRP, sc->pbuf, 4); 934 nm_wr(sc, NM_PBUFFER_WMARK, sc->pbuf + sc->pwmark, 4); 935 nm_wr(sc, NM_PLAYBACK_ENABLE_REG, NM_PLAYBACK_FREERUN | 936 NM_PLAYBACK_ENABLE_FLAG, 1); 937 nm_wr(sc, NM_AUDIO_MUTE_REG, 0, 2); 938 939 return (0); 940 } 941 942 943 944 int 945 neo_trigger_input(addr, start, end, blksize, intr, arg, param) 946 void *addr; 947 void *start, *end; 948 int blksize; 949 void (*intr) __P((void *)); 950 void *arg; 951 struct audio_params *param; 952 { 953 struct neo_softc *sc = addr; 954 int ssz; 955 956 sc->rintr = intr; 957 sc->rarg = arg; 958 959 ssz = (param->precision * param->factor == 16)? 2 : 1; 960 if (param->channels == 2) 961 ssz <<= 1; 962 963 sc->rbufsize = ((char*)end - (char *)start); 964 sc->rblksize = blksize; 965 sc->rwmark = blksize; 966 967 nm_wr(sc, NM_RBUFFER_START, sc->rbuf, 4); 968 nm_wr(sc, NM_RBUFFER_END, sc->rbuf + sc->rbufsize, 4); 969 nm_wr(sc, NM_RBUFFER_CURRP, sc->rbuf, 4); 970 nm_wr(sc, NM_RBUFFER_WMARK, sc->rbuf + sc->rwmark, 4); 971 nm_wr(sc, NM_RECORD_ENABLE_REG, NM_RECORD_FREERUN | 972 NM_RECORD_ENABLE_FLAG, 1); 973 974 return (0); 975 } 976 977 int 978 neo_halt_output(addr) 979 void *addr; 980 { 981 struct neo_softc *sc = (struct neo_softc *)addr; 982 983 nm_wr(sc, NM_PLAYBACK_ENABLE_REG, 0, 1); 984 nm_wr(sc, NM_AUDIO_MUTE_REG, NM_AUDIO_MUTE_BOTH, 2); 985 986 sc->pintr = 0; 987 988 return (0); 989 } 990 991 int 992 neo_halt_input(addr) 993 void *addr; 994 { 995 struct neo_softc *sc = (struct neo_softc *)addr; 996 997 nm_wr(sc, NM_RECORD_ENABLE_REG, 0, 1); 998 999 sc->rintr = 0; 1000 1001 return (0); 1002 } 1003 1004 int 1005 neo_getdev(addr, retp) 1006 void *addr; 1007 struct audio_device *retp; 1008 { 1009 *retp = neo_device; 1010 return (0); 1011 } 1012 1013 int 1014 neo_mixer_set_port(addr, cp) 1015 void *addr; 1016 mixer_ctrl_t *cp; 1017 { 1018 struct neo_softc *sc = addr; 1019 1020 return ((sc->codec_if->vtbl->mixer_set_port)(sc->codec_if, 1021 cp)); 1022 } 1023 1024 int 1025 neo_mixer_get_port(addr, cp) 1026 void *addr; 1027 mixer_ctrl_t *cp; 1028 { 1029 struct neo_softc *sc = addr; 1030 1031 return ((sc->codec_if->vtbl->mixer_get_port)(sc->codec_if, 1032 cp)); 1033 } 1034 1035 int 1036 neo_query_devinfo(addr, dip) 1037 void *addr; 1038 mixer_devinfo_t *dip; 1039 { 1040 struct neo_softc *sc = addr; 1041 1042 return ((sc->codec_if->vtbl->query_devinfo)(sc->codec_if, dip)); 1043 } 1044 1045 void * 1046 neo_malloc(addr, direction, size, pool, flags) 1047 void *addr; 1048 int direction; 1049 size_t size; 1050 int pool, flags; 1051 { 1052 struct neo_softc *sc = addr; 1053 void *rv = 0; 1054 1055 switch (direction) { 1056 case AUMODE_PLAY: 1057 rv = (char *)sc->bufioh + sc->pbuf; 1058 break; 1059 case AUMODE_RECORD: 1060 rv = (char *)sc->bufioh + sc->rbuf; 1061 break; 1062 default: 1063 break; 1064 } 1065 1066 return (rv); 1067 } 1068 1069 void 1070 neo_free(addr, ptr, pool) 1071 void *addr; 1072 void *ptr; 1073 int pool; 1074 { 1075 return; 1076 } 1077 1078 size_t 1079 neo_round_buffersize(addr, direction, size) 1080 void *addr; 1081 int direction; 1082 size_t size; 1083 { 1084 return (NM_BUFFSIZE); 1085 } 1086 1087 1088 int 1089 neo_get_props(addr) 1090 void *addr; 1091 { 1092 1093 return (AUDIO_PROP_INDEPENDENT | 1094 AUDIO_PROP_FULLDUPLEX); 1095 } 1096