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