1 /* $OpenBSD: neo.c,v 1.7 2001/06/18 19:27:18 deraadt 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, WHETHERIN 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 THEPOSSIBILITY 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 secodn 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(pc, pa->pa_intrtag, pa->pa_intrpin, 580 pa->pa_intrline, &ih)) { 581 printf("\n%s: couldn't map interrupt\n", sc->dev.dv_xname); 582 return; 583 } 584 intrstr = pci_intr_string(pc, ih); 585 sc->ih = pci_intr_establish(pc, ih, IPL_AUDIO, neo_intr, sc, 586 sc->dev.dv_xname); 587 588 if (sc->ih == NULL) { 589 printf("\n%s: couldn't establish interrupt", 590 sc->dev.dv_xname); 591 if (intrstr != NULL) 592 printf(" at %s", intrstr); 593 printf("\n"); 594 return; 595 } 596 printf(": %s\n", intrstr); 597 598 if ((error = nm_init(sc)) != 0) 599 return; 600 601 /* Enable the device. */ 602 csr = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG); 603 pci_conf_write(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG, 604 csr | PCI_COMMAND_MASTER_ENABLE); 605 606 sc->host_if.arg = sc; 607 608 sc->host_if.attach = neo_attach_codec; 609 sc->host_if.read = neo_read_codec; 610 sc->host_if.write = neo_write_codec; 611 sc->host_if.reset = neo_reset_codec; 612 sc->host_if.flags = neo_flags_codec; 613 614 if ((error = ac97_attach(&sc->host_if)) != 0) 615 return; 616 617 audio_attach_mi(&neo_hw_if, sc, &sc->dev); 618 619 return; 620 } 621 622 int 623 neo_match(parent, match, aux) 624 struct device *parent; 625 void *match; 626 void *aux; 627 { 628 struct pci_attach_args *pa = (struct pci_attach_args *) aux; 629 #if 0 630 u_int32_t subdev, badcard; 631 #endif 632 633 if (PCI_VENDOR(pa->pa_id) != PCI_VENDOR_NEOMAGIC) 634 return (0); 635 636 #if 0 637 subdev = (pci_get_subdevice(dev) << 16) | pci_get_subvendor(dev); 638 #endif 639 switch (PCI_PRODUCT(pa->pa_id)) { 640 case PCI_PRODUCT_NEOMAGIC_NM256AV: 641 #if 0 642 i = 0; 643 while ((i < NUM_BADCARDS) && (badcards[i] != subdev)) 644 i++; 645 if (i == NUM_BADCARDS) 646 s = "NeoMagic 256AV"; 647 DEB(else) 648 DEB(device_printf(dev, "this is a non-ac97 NM256AV, not attaching\n")); 649 return (1); 650 #endif 651 case PCI_PRODUCT_NEOMAGIC_NM256ZX: 652 return (1); 653 } 654 655 return (0); 656 } 657 658 int 659 neo_read_codec(sc_, a, d) 660 void *sc_; 661 u_int8_t a; 662 u_int16_t *d; 663 { 664 struct neo_softc *sc = sc_; 665 666 if (!nm_waitcd(sc)) { 667 *d = nm_rd(sc, sc->ac97_base + a, 2); 668 DELAY(1000); 669 return 0; 670 } 671 672 return (ENXIO); 673 } 674 675 676 int 677 neo_write_codec(sc_, a, d) 678 void *sc_; 679 u_int8_t a; 680 u_int16_t d; 681 { 682 struct neo_softc *sc = sc_; 683 int cnt = 3; 684 685 if (!nm_waitcd(sc)) { 686 while (cnt-- > 0) { 687 nm_wr(sc, sc->ac97_base + a, d, 2); 688 if (!nm_waitcd(sc)) { 689 DELAY(1000); 690 return (0); 691 } 692 } 693 } 694 695 return (ENXIO); 696 } 697 698 699 int 700 neo_attach_codec(sc_, codec_if) 701 void *sc_; 702 struct ac97_codec_if *codec_if; 703 { 704 struct neo_softc *sc = sc_; 705 706 sc->codec_if = codec_if; 707 return (0); 708 } 709 710 void 711 neo_reset_codec(sc) 712 void *sc; 713 { 714 nm_wr(sc, 0x6c0, 0x01, 1); 715 nm_wr(sc, 0x6cc, 0x87, 1); 716 nm_wr(sc, 0x6cc, 0x80, 1); 717 nm_wr(sc, 0x6cc, 0x00, 1); 718 719 return; 720 } 721 722 723 enum ac97_host_flags 724 neo_flags_codec(sc) 725 void *sc; 726 { 727 return (AC97_HOST_DONT_READANY); 728 } 729 730 int 731 neo_open(addr, flags) 732 void *addr; 733 int flags; 734 { 735 return (0); 736 } 737 738 /* 739 * Close function is called at splaudio(). 740 */ 741 void 742 neo_close(addr) 743 void *addr; 744 { 745 struct neo_softc *sc = addr; 746 747 neo_halt_output(sc); 748 neo_halt_input(sc); 749 750 sc->pintr = 0; 751 sc->rintr = 0; 752 } 753 754 int 755 neo_query_encoding(addr, fp) 756 void *addr; 757 struct audio_encoding *fp; 758 { 759 switch (fp->index) { 760 case 0: 761 strcpy(fp->name, AudioEulinear); 762 fp->encoding = AUDIO_ENCODING_ULINEAR; 763 fp->precision = 8; 764 fp->flags = 0; 765 return (0); 766 case 1: 767 strcpy(fp->name, AudioEmulaw); 768 fp->encoding = AUDIO_ENCODING_ULAW; 769 fp->precision = 8; 770 fp->flags = AUDIO_ENCODINGFLAG_EMULATED; 771 return (0); 772 case 2: 773 strcpy(fp->name, AudioEalaw); 774 fp->encoding = AUDIO_ENCODING_ALAW; 775 fp->precision = 8; 776 fp->flags = AUDIO_ENCODINGFLAG_EMULATED; 777 return (0); 778 case 3: 779 strcpy(fp->name, AudioEslinear); 780 fp->encoding = AUDIO_ENCODING_SLINEAR; 781 fp->precision = 8; 782 fp->flags = AUDIO_ENCODINGFLAG_EMULATED; 783 return (0); 784 case 4: 785 strcpy(fp->name, AudioEslinear_le); 786 fp->encoding = AUDIO_ENCODING_SLINEAR_LE; 787 fp->precision = 16; 788 fp->flags = 0; 789 return (0); 790 case 5: 791 strcpy(fp->name, AudioEulinear_le); 792 fp->encoding = AUDIO_ENCODING_ULINEAR_LE; 793 fp->precision = 16; 794 fp->flags = AUDIO_ENCODINGFLAG_EMULATED; 795 return (0); 796 case 6: 797 strcpy(fp->name, AudioEslinear_be); 798 fp->encoding = AUDIO_ENCODING_SLINEAR_BE; 799 fp->precision = 16; 800 fp->flags = AUDIO_ENCODINGFLAG_EMULATED; 801 return (0); 802 case 7: 803 strcpy(fp->name, AudioEulinear_be); 804 fp->encoding = AUDIO_ENCODING_ULINEAR_BE; 805 fp->precision = 16; 806 fp->flags = AUDIO_ENCODINGFLAG_EMULATED; 807 return (0); 808 default: 809 return (EINVAL); 810 } 811 } 812 813 /* Todo: don't commit settings to card until we've verified all parameters */ 814 int 815 neo_set_params(addr, setmode, usemode, play, rec) 816 void *addr; 817 int setmode, usemode; 818 struct audio_params *play, *rec; 819 { 820 struct neo_softc *sc = addr; 821 u_int32_t base; 822 u_int8_t x; 823 int mode; 824 struct audio_params *p; 825 826 for (mode = AUMODE_RECORD; mode != -1; 827 mode = mode == AUMODE_RECORD ? AUMODE_PLAY : -1) { 828 if ((setmode & mode) == 0) 829 continue; 830 831 p = mode == AUMODE_PLAY ? play : rec; 832 833 if (p == NULL) continue; 834 835 for (x = 0; x < 8; x++) 836 if (p->sample_rate < (samplerates[x] + samplerates[x + 1]) / 2) 837 break; 838 839 if (x == 8) return (EINVAL); 840 841 p->sample_rate = samplerates[x]; 842 nm_loadcoeff(sc, mode, x); 843 844 x <<= 4; 845 x &= NM_RATE_MASK; 846 if (p->precision == 16) x |= NM_RATE_BITS_16; 847 if (p->channels == 2) x |= NM_RATE_STEREO; 848 849 base = (mode == AUMODE_PLAY)? 850 NM_PLAYBACK_REG_OFFSET : NM_RECORD_REG_OFFSET; 851 nm_wr(sc, base + NM_RATE_REG_OFFSET, x, 1); 852 853 p->factor = 1; 854 p->sw_code = 0; 855 switch (p->encoding) { 856 case AUDIO_ENCODING_SLINEAR_BE: 857 if (p->precision == 16) 858 p->sw_code = swap_bytes; 859 else 860 p->sw_code = change_sign8; 861 break; 862 case AUDIO_ENCODING_SLINEAR_LE: 863 if (p->precision != 16) 864 p->sw_code = change_sign8; 865 break; 866 case AUDIO_ENCODING_ULINEAR_BE: 867 if (p->precision == 16) { 868 if (mode == AUMODE_PLAY) 869 p->sw_code = swap_bytes_change_sign16; 870 else 871 p->sw_code = change_sign16_swap_bytes; 872 } 873 break; 874 case AUDIO_ENCODING_ULINEAR_LE: 875 if (p->precision == 16) 876 p->sw_code = change_sign16; 877 break; 878 case AUDIO_ENCODING_ULAW: 879 if (mode == AUMODE_PLAY) { 880 p->factor = 2; 881 p->sw_code = mulaw_to_slinear16; 882 } else 883 p->sw_code = ulinear8_to_mulaw; 884 break; 885 case AUDIO_ENCODING_ALAW: 886 if (mode == AUMODE_PLAY) { 887 p->factor = 2; 888 p->sw_code = alaw_to_slinear16; 889 } else 890 p->sw_code = ulinear8_to_alaw; 891 break; 892 default: 893 return (EINVAL); 894 } 895 } 896 897 898 return (0); 899 } 900 901 int 902 neo_round_blocksize(addr, blk) 903 void *addr; 904 int blk; 905 { 906 return (NM_BUFFSIZE / 2); 907 } 908 909 int 910 neo_trigger_output(addr, start, end, blksize, intr, arg, param) 911 void *addr; 912 void *start, *end; 913 int blksize; 914 void (*intr) __P((void *)); 915 void *arg; 916 struct audio_params *param; 917 { 918 struct neo_softc *sc = addr; 919 int ssz; 920 921 sc->pintr = intr; 922 sc->parg = arg; 923 924 ssz = (param->precision * param->factor == 16)? 2 : 1; 925 if (param->channels == 2) 926 ssz <<= 1; 927 928 sc->pbufsize = ((char*)end - (char *)start); 929 sc->pblksize = blksize; 930 sc->pwmark = blksize; 931 932 nm_wr(sc, NM_PBUFFER_START, sc->pbuf, 4); 933 nm_wr(sc, NM_PBUFFER_END, sc->pbuf + sc->pbufsize - ssz, 4); 934 nm_wr(sc, NM_PBUFFER_CURRP, sc->pbuf, 4); 935 nm_wr(sc, NM_PBUFFER_WMARK, sc->pbuf + sc->pwmark, 4); 936 nm_wr(sc, NM_PLAYBACK_ENABLE_REG, NM_PLAYBACK_FREERUN | 937 NM_PLAYBACK_ENABLE_FLAG, 1); 938 nm_wr(sc, NM_AUDIO_MUTE_REG, 0, 2); 939 940 return (0); 941 } 942 943 944 945 int 946 neo_trigger_input(addr, start, end, blksize, intr, arg, param) 947 void *addr; 948 void *start, *end; 949 int blksize; 950 void (*intr) __P((void *)); 951 void *arg; 952 struct audio_params *param; 953 { 954 struct neo_softc *sc = addr; 955 int ssz; 956 957 sc->rintr = intr; 958 sc->rarg = arg; 959 960 ssz = (param->precision * param->factor == 16)? 2 : 1; 961 if (param->channels == 2) 962 ssz <<= 1; 963 964 sc->rbufsize = ((char*)end - (char *)start); 965 sc->rblksize = blksize; 966 sc->rwmark = blksize; 967 968 nm_wr(sc, NM_RBUFFER_START, sc->rbuf, 4); 969 nm_wr(sc, NM_RBUFFER_END, sc->rbuf + sc->rbufsize, 4); 970 nm_wr(sc, NM_RBUFFER_CURRP, sc->rbuf, 4); 971 nm_wr(sc, NM_RBUFFER_WMARK, sc->rbuf + sc->rwmark, 4); 972 nm_wr(sc, NM_RECORD_ENABLE_REG, NM_RECORD_FREERUN | 973 NM_RECORD_ENABLE_FLAG, 1); 974 975 return (0); 976 } 977 978 int 979 neo_halt_output(addr) 980 void *addr; 981 { 982 struct neo_softc *sc = (struct neo_softc *)addr; 983 984 nm_wr(sc, NM_PLAYBACK_ENABLE_REG, 0, 1); 985 nm_wr(sc, NM_AUDIO_MUTE_REG, NM_AUDIO_MUTE_BOTH, 2); 986 987 sc->pintr = 0; 988 989 return (0); 990 } 991 992 int 993 neo_halt_input(addr) 994 void *addr; 995 { 996 struct neo_softc *sc = (struct neo_softc *)addr; 997 998 nm_wr(sc, NM_RECORD_ENABLE_REG, 0, 1); 999 1000 sc->rintr = 0; 1001 1002 return (0); 1003 } 1004 1005 int 1006 neo_getdev(addr, retp) 1007 void *addr; 1008 struct audio_device *retp; 1009 { 1010 *retp = neo_device; 1011 return (0); 1012 } 1013 1014 int 1015 neo_mixer_set_port(addr, cp) 1016 void *addr; 1017 mixer_ctrl_t *cp; 1018 { 1019 struct neo_softc *sc = addr; 1020 1021 return ((sc->codec_if->vtbl->mixer_set_port)(sc->codec_if, 1022 cp)); 1023 } 1024 1025 int 1026 neo_mixer_get_port(addr, cp) 1027 void *addr; 1028 mixer_ctrl_t *cp; 1029 { 1030 struct neo_softc *sc = addr; 1031 1032 return ((sc->codec_if->vtbl->mixer_get_port)(sc->codec_if, 1033 cp)); 1034 } 1035 1036 int 1037 neo_query_devinfo(addr, dip) 1038 void *addr; 1039 mixer_devinfo_t *dip; 1040 { 1041 struct neo_softc *sc = addr; 1042 1043 return ((sc->codec_if->vtbl->query_devinfo)(sc->codec_if, dip)); 1044 } 1045 1046 void * 1047 neo_malloc(addr, direction, size, pool, flags) 1048 void *addr; 1049 int direction; 1050 size_t size; 1051 int pool, flags; 1052 { 1053 struct neo_softc *sc = addr; 1054 void *rv = 0; 1055 1056 switch (direction) { 1057 case AUMODE_PLAY: 1058 rv = (char *)sc->bufioh + sc->pbuf; 1059 break; 1060 case AUMODE_RECORD: 1061 rv = (char *)sc->bufioh + sc->rbuf; 1062 break; 1063 default: 1064 break; 1065 } 1066 1067 return (rv); 1068 } 1069 1070 void 1071 neo_free(addr, ptr, pool) 1072 void *addr; 1073 void *ptr; 1074 int pool; 1075 { 1076 return; 1077 } 1078 1079 size_t 1080 neo_round_buffersize(addr, direction, size) 1081 void *addr; 1082 int direction; 1083 size_t size; 1084 { 1085 return (NM_BUFFSIZE); 1086 } 1087 1088 1089 int 1090 neo_get_props(addr) 1091 void *addr; 1092 { 1093 1094 return (AUDIO_PROP_INDEPENDENT | 1095 AUDIO_PROP_FULLDUPLEX); 1096 } 1097