1 /* $OpenBSD: maestro.c,v 1.16 2003/06/06 02:56:39 fgsch Exp $ */ 2 /* $FreeBSD: /c/ncvs/src/sys/dev/sound/pci/maestro.c,v 1.3 2000/11/21 12:22:11 julian Exp $ */ 3 /* 4 * FreeBSD's ESS Agogo/Maestro driver 5 * Converted from FreeBSD's pcm to OpenBSD's audio. 6 * Copyright (c) 2000, 2001 David Leonard & Marc Espie 7 * All rights reserved. 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 /*- 31 * (FreeBSD) Credits: 32 * Copyright (c) 2000 Taku YAMAMOTO <taku@cent.saitama-u.ac.jp> 33 * 34 * Part of this code (especially in many magic numbers) was heavily inspired 35 * by the Linux driver originally written by 36 * Alan Cox <alan.cox@linux.org>, modified heavily by 37 * Zach Brown <zab@zabbo.net>. 38 * 39 * busdma()-ize and buffer size reduction were suggested by 40 * Cameron Grant <gandalf@vilnya.demon.co.uk>. 41 * Also he showed me the way to use busdma() suite. 42 * 43 * Internal speaker problems on NEC VersaPro's and Dell Inspiron 7500 44 * were looked at by 45 * Munehiro Matsuda <haro@tk.kubota.co.jp>, 46 * who brought patches based on the Linux driver with some simplification. 47 */ 48 49 #include <sys/param.h> 50 #include <sys/systm.h> 51 #include <sys/kernel.h> 52 #include <sys/malloc.h> 53 #include <sys/device.h> 54 #include <sys/proc.h> 55 #include <sys/queue.h> 56 #include <sys/fcntl.h> 57 58 #include <dev/pci/pcidevs.h> 59 #include <dev/pci/pcivar.h> 60 61 #include <sys/audioio.h> 62 #include <dev/audio_if.h> 63 #include <dev/mulaw.h> 64 #include <dev/auconv.h> 65 66 #include <dev/ic/ac97.h> 67 #include <dev/pci/maestro_reg.h> 68 69 #ifdef AUDIO_DEBUG 70 #define DPRINTF(x) if (maestrodebug) printf x 71 #define DLPRINTF(i, x) if (maestrodebug & i) printf x 72 int maestrodebug = 0; 73 u_long maestrointr_called; 74 u_long maestrodma_effective; 75 76 #define MAESTRODEBUG_INTR 1 77 #define MAESTRODEBUG_TIMER 2 78 #else 79 #define DPRINTF(x) 80 #define DLPRINTF(i, x) 81 #endif 82 83 #define MAESTRO_BUFSIZ 0x4000 84 #define lengthof(array) (sizeof (array) / sizeof (array)[0]) 85 86 #define STEP_VOLUME 0x22 87 #define MIDDLE_VOLUME (STEP_VOLUME * 4) 88 89 typedef struct salloc_pool { 90 struct salloc_zone { 91 SLIST_ENTRY(salloc_zone) link; 92 caddr_t addr; 93 size_t size; 94 } *zones; 95 SLIST_HEAD(salloc_head, salloc_zone) free, used, spare; 96 } *salloc_t; 97 98 struct maestro_softc; 99 100 #define MAESTRO_PLAY 1 101 #define MAESTRO_STEREO 2 102 #define MAESTRO_8BIT 4 103 #define MAESTRO_UNSIGNED 8 104 #define MAESTRO_RUNNING 16 105 106 struct maestro_channel { 107 struct maestro_softc *sc; 108 int num; 109 u_int32_t blocksize; 110 u_int16_t mode; 111 u_int32_t speed; 112 u_int32_t dv; 113 u_int16_t start; 114 u_int16_t threshold; 115 u_int16_t end; 116 u_int16_t current; 117 u_int wpwa; 118 void (*intr)(void *); 119 void *intr_arg; 120 }; 121 122 struct maestro_softc { 123 struct device dev; 124 125 void *ih; 126 pci_chipset_tag_t pc; 127 pcitag_t pt; 128 129 #define MAESTRO_FLAG_SETUPGPIO 0x0001 130 int flags; 131 bus_space_tag_t iot; 132 bus_space_handle_t ioh; 133 bus_dma_tag_t dmat; 134 135 caddr_t dmabase; 136 bus_addr_t physaddr; 137 size_t dmasize; 138 bus_dmamap_t dmamap; 139 bus_dma_segment_t dmaseg; 140 salloc_t dmapool; 141 142 struct ac97_codec_if *codec_if; 143 struct ac97_host_if host_if; 144 struct audio_device *sc_audev; 145 146 void *powerhook; 147 int suspend; 148 149 struct maestro_channel play; 150 struct maestro_channel record; 151 }; 152 153 154 typedef u_int16_t wpreg_t; 155 typedef u_int16_t wcreg_t; 156 157 salloc_t salloc_new(caddr_t, size_t, int); 158 void salloc_destroy(salloc_t); 159 caddr_t salloc_alloc(salloc_t, size_t); 160 void salloc_free(salloc_t, caddr_t); 161 void salloc_insert(salloc_t, struct salloc_head *, 162 struct salloc_zone *, int); 163 164 int maestro_match(struct device *, void *, void *); 165 void maestro_attach(struct device *, struct device *, void *); 166 int maestro_intr(void *); 167 168 int maestro_open(void *, int); 169 void maestro_close(void *); 170 int maestro_query_encoding(void *, struct audio_encoding *); 171 int maestro_set_params(void *, int, int, struct audio_params *, 172 struct audio_params *); 173 int maestro_round_blocksize(void *, int); 174 int maestro_halt_output(void *); 175 int maestro_halt_input(void *); 176 int maestro_getdev(void *, struct audio_device *); 177 int maestro_set_port(void *, mixer_ctrl_t *); 178 int maestro_get_port(void *, mixer_ctrl_t *); 179 int maestro_query_devinfo(void *, mixer_devinfo_t *); 180 void *maestro_malloc(void *, int, size_t, int, int); 181 void maestro_free(void *, void *, int); 182 size_t maestro_round_buffersize(void *, int, size_t); 183 paddr_t maestro_mappage(void *, void *, off_t, int); 184 int maestro_get_props(void *); 185 int maestro_trigger_output(void *, void *, void *, int, void (*)(void *), 186 void *, struct audio_params *); 187 int maestro_trigger_input(void *, void *, void *, int, void (*)(void *), 188 void *, struct audio_params *); 189 190 int maestro_attach_codec(void *, struct ac97_codec_if *); 191 int maestro_read_codec(void *, u_int8_t, u_int16_t *); 192 int maestro_write_codec(void *, u_int8_t, u_int16_t); 193 void maestro_reset_codec(void *); 194 195 void maestro_initcodec(void *); 196 197 void maestro_set_speed(struct maestro_channel *, u_long *); 198 void maestro_init(struct maestro_softc *); 199 void maestro_power(struct maestro_softc *, int); 200 void maestro_powerhook(int, void *); 201 202 void maestro_channel_start(struct maestro_channel *); 203 void maestro_channel_stop(struct maestro_channel *); 204 void maestro_channel_advance_dma(struct maestro_channel *); 205 void maestro_channel_suppress_jitter(struct maestro_channel *); 206 207 int maestro_get_flags(struct pci_attach_args *); 208 209 void ringbus_setdest(struct maestro_softc *, int, int); 210 211 wpreg_t wp_reg_read(struct maestro_softc *, int); 212 void wp_reg_write(struct maestro_softc *, int, wpreg_t); 213 wpreg_t wp_apu_read(struct maestro_softc *, int, int); 214 void wp_apu_write(struct maestro_softc *, int, int, wpreg_t); 215 void wp_settimer(struct maestro_softc *, u_int); 216 void wp_starttimer(struct maestro_softc *); 217 void wp_stoptimer(struct maestro_softc *); 218 219 wcreg_t wc_reg_read(struct maestro_softc *, int); 220 void wc_reg_write(struct maestro_softc *, int, wcreg_t); 221 wcreg_t wc_ctrl_read(struct maestro_softc *, int); 222 void wc_ctrl_write(struct maestro_softc *, int, wcreg_t); 223 224 u_int maestro_calc_timer_freq(struct maestro_channel *); 225 void maestro_update_timer(struct maestro_softc *); 226 227 struct cfdriver maestro_cd = { 228 NULL, "maestro", DV_DULL 229 }; 230 231 struct cfattach maestro_ca = { 232 sizeof (struct maestro_softc), maestro_match, maestro_attach 233 }; 234 235 struct audio_hw_if maestro_hw_if = { 236 maestro_open, 237 maestro_close, 238 NULL, 239 maestro_query_encoding, 240 maestro_set_params, 241 maestro_round_blocksize, 242 NULL, 243 NULL, 244 NULL, 245 NULL, 246 NULL, 247 maestro_halt_output, 248 maestro_halt_input, 249 NULL, 250 maestro_getdev, 251 NULL, 252 maestro_set_port, 253 maestro_get_port, 254 maestro_query_devinfo, 255 maestro_malloc, 256 maestro_free, 257 maestro_round_buffersize, 258 maestro_mappage, 259 maestro_get_props, 260 maestro_trigger_output, 261 maestro_trigger_input 262 }; 263 264 struct audio_device maestro_audev = { 265 "ESS Maestro", "", "maestro" 266 }; 267 268 struct { 269 u_short vendor, product; 270 int flags; 271 } maestro_pcitab[] = { 272 { PCI_VENDOR_ESSTECH, PCI_PRODUCT_ESSTECH_MAESTROII, 0 }, 273 { PCI_VENDOR_ESSTECH, PCI_PRODUCT_ESSTECH_MAESTRO2E, 0 }, 274 { PCI_VENDOR_PLATFORM, PCI_PRODUCT_PLATFORM_ES1849, 0 }, 275 { PCI_VENDOR_NEC, PCI_PRODUCT_NEC_VERSAMAESTRO, MAESTRO_FLAG_SETUPGPIO }, 276 { PCI_VENDOR_NEC, PCI_PRODUCT_NEC_VERSAPRONXVA26D, MAESTRO_FLAG_SETUPGPIO } 277 }; 278 #define NMAESTRO_PCITAB lengthof(maestro_pcitab) 279 280 int 281 maestro_get_flags(pa) 282 struct pci_attach_args *pa; 283 { 284 int i; 285 286 /* Distinguish audio devices from modems with the same manfid */ 287 if (PCI_CLASS(pa->pa_class) != PCI_CLASS_MULTIMEDIA) 288 return (-1); 289 if (PCI_SUBCLASS(pa->pa_class) != PCI_SUBCLASS_MULTIMEDIA_AUDIO) 290 return (-1); 291 for (i = 0; i < NMAESTRO_PCITAB; i++) 292 if (PCI_VENDOR(pa->pa_id) == maestro_pcitab[i].vendor && 293 PCI_PRODUCT(pa->pa_id) == maestro_pcitab[i].product) 294 return (maestro_pcitab[i].flags); 295 return (-1); 296 } 297 298 /* ----------------------------- 299 * Driver interface. 300 */ 301 302 int 303 maestro_match(parent, match, aux) 304 struct device *parent; 305 void *match; 306 void *aux; 307 { 308 struct pci_attach_args *pa = (struct pci_attach_args *)aux; 309 310 if (maestro_get_flags(pa) == -1) 311 return (0); 312 else 313 return (1); 314 } 315 316 void 317 maestro_attach(parent, self, aux) 318 struct device *parent; 319 struct device *self; 320 void *aux; 321 { 322 struct maestro_softc *sc = (struct maestro_softc *)self; 323 struct pci_attach_args *pa = (struct pci_attach_args *)aux; 324 pci_chipset_tag_t pc = pa->pa_pc; 325 char const *intrstr; 326 pci_intr_handle_t ih; 327 int error; 328 pcireg_t data; 329 u_int16_t cdata; 330 int dmastage = 0; 331 int rseg; 332 333 sc->sc_audev = &maestro_audev; 334 sc->flags = maestro_get_flags(pa); 335 336 sc->pc = pa->pa_pc; 337 sc->pt = pa->pa_tag; 338 sc->dmat = pa->pa_dmat; 339 340 /* Map interrupt */ 341 if (pci_intr_map(pa, &ih)) { 342 printf(": couldn't map interrupt\n"); 343 return; 344 } 345 intrstr = pci_intr_string(pc, ih); 346 sc->ih = pci_intr_establish(pc, ih, IPL_AUDIO, maestro_intr, sc, 347 sc->dev.dv_xname); 348 if (sc->ih == NULL) { 349 printf(": couldn't establish interrupt"); 350 if (intrstr != NULL) 351 printf(" at %s\n", intrstr); 352 return; 353 } 354 printf(": %s", intrstr); 355 356 /* Rangers, power up */ 357 maestro_power(sc, PPMI_D0); 358 DELAY(100000); 359 360 /* Map i/o */ 361 if ((error = pci_mapreg_map(pa, PCI_MAPS, PCI_MAPREG_TYPE_IO, 362 0, &sc->iot, &sc->ioh, NULL, NULL, 0)) != 0) { 363 printf(", couldn't map i/o space\n"); 364 goto bad; 365 }; 366 367 /* Enable bus mastering */ 368 data = pci_conf_read(sc->pc, sc->pt, PCI_COMMAND_STATUS_REG); 369 if ((data & PCI_COMMAND_MASTER_ENABLE) == 0) 370 pci_conf_write(sc->pc, sc->pt, PCI_COMMAND_STATUS_REG, 371 data | PCI_COMMAND_MASTER_ENABLE); 372 373 /* Allocate fixed DMA segment :-( */ 374 sc->dmasize = MAESTRO_BUFSIZ * 16; 375 if ((error = bus_dmamem_alloc(sc->dmat, sc->dmasize, NBPG, 0, 376 &sc->dmaseg, 1, &rseg, BUS_DMA_NOWAIT)) != 0) { 377 printf(", unable to alloc dma, error %d\n", error); 378 goto bad; 379 } 380 dmastage = 1; 381 if ((error = bus_dmamem_map(sc->dmat, &sc->dmaseg, 1, 382 sc->dmasize, &sc->dmabase, BUS_DMA_NOWAIT | 383 BUS_DMA_COHERENT)) != 0) { 384 printf(", unable to map dma, error %d\n", error); 385 goto bad; 386 } 387 dmastage = 2; 388 if ((error = bus_dmamap_create(sc->dmat, sc->dmasize, 1, 389 sc->dmasize, 0, BUS_DMA_NOWAIT, &sc->dmamap)) != 0) { 390 printf(", unable to create dma map, error %d\n", error); 391 goto bad; 392 } 393 dmastage = 3; 394 if ((error = bus_dmamap_load(sc->dmat, sc->dmamap, 395 sc->dmabase, sc->dmasize, NULL, BUS_DMA_NOWAIT)) != 0) { 396 printf(", unable to load dma map, error %d\n", error); 397 goto bad; 398 } 399 400 /* XXX 401 * The first byte of the allocated memory is not usable, 402 * the WP sometimes uses it to store status. 403 */ 404 /* Make DMA memory pool */ 405 if ((sc->dmapool = salloc_new(sc->dmabase+16, sc->dmasize-16, 406 128/*overkill?*/)) == NULL) { 407 printf(", unable to make dma pool\n"); 408 goto bad; 409 } 410 411 sc->physaddr = sc->dmamap->dm_segs[0].ds_addr; 412 413 printf("\n"); 414 415 /* Kick device */ 416 maestro_init(sc); 417 maestro_read_codec(sc, 0, &cdata); 418 if (cdata == 0x80) { 419 printf("%s: PT101 codec unsupported, no mixer\n", 420 sc->dev.dv_xname); 421 /* Init values from Linux, no idea what this does. */ 422 maestro_write_codec(sc, 0x2a, 0x0001); 423 maestro_write_codec(sc, 0x2C, 0x0000); 424 maestro_write_codec(sc, 0x2C, 0xFFFF); 425 maestro_write_codec(sc, 0x10, 0x9F1F); 426 maestro_write_codec(sc, 0x12, 0x0808); 427 maestro_write_codec(sc, 0x14, 0x9F1F); 428 maestro_write_codec(sc, 0x16, 0x9F1F); 429 maestro_write_codec(sc, 0x18, 0x0404); 430 maestro_write_codec(sc, 0x1A, 0x0000); 431 maestro_write_codec(sc, 0x1C, 0x0000); 432 maestro_write_codec(sc, 0x02, 0x0404); 433 maestro_write_codec(sc, 0x04, 0x0808); 434 maestro_write_codec(sc, 0x0C, 0x801F); 435 maestro_write_codec(sc, 0x0E, 0x801F); 436 /* no control over the mixer, sorry */ 437 sc->codec_if = NULL; 438 } else { 439 /* Attach the AC'97 */ 440 sc->host_if.arg = sc; 441 sc->host_if.attach = maestro_attach_codec; 442 sc->host_if.read = maestro_read_codec; 443 sc->host_if.write = maestro_write_codec; 444 sc->host_if.reset = maestro_reset_codec; 445 if (ac97_attach(&sc->host_if) != 0) { 446 printf("%s: couldn't attach codec\n", sc->dev.dv_xname); 447 goto bad; 448 } 449 } 450 451 sc->play.mode = MAESTRO_PLAY; 452 sc->play.sc = sc; 453 sc->play.num = 0; 454 sc->record.sc = sc; 455 sc->record.num = 2; 456 sc->record.mode = 0; 457 458 /* Attach audio */ 459 audio_attach_mi(&maestro_hw_if, sc, &sc->dev); 460 461 /* Hook power changes */ 462 sc->suspend = PWR_RESUME; 463 sc->powerhook = powerhook_establish(maestro_powerhook, sc); 464 465 return; 466 467 bad: 468 /* Power down. */ 469 maestro_power(sc, PPMI_D3); 470 if (sc->ih) 471 pci_intr_disestablish(pc, sc->ih); 472 printf("%s: disabled\n", sc->dev.dv_xname); 473 if (sc->dmapool) 474 salloc_destroy(sc->dmapool); 475 if (dmastage >= 3) 476 bus_dmamap_destroy(sc->dmat, sc->dmamap); 477 if (dmastage >= 2) 478 bus_dmamem_unmap(sc->dmat, sc->dmabase, sc->dmasize); 479 if (dmastage >= 1) 480 bus_dmamem_free(sc->dmat, &sc->dmaseg, 1); 481 } 482 483 void 484 maestro_init(sc) 485 struct maestro_softc *sc; 486 { 487 int reg; 488 pcireg_t data; 489 490 /* Disable all legacy emulations. */ 491 data = pci_conf_read(sc->pc, sc->pt, CONF_LEGACY); 492 data |= LEGACY_DISABLED; 493 pci_conf_write(sc->pc, sc->pt, CONF_LEGACY, data); 494 495 /* Disconnect from CHI. (Makes Dell inspiron 7500 work?) 496 * Enable posted write. 497 * Prefer PCI timing rather than that of ISA. 498 * Don't swap L/R. */ 499 data = pci_conf_read(sc->pc, sc->pt, CONF_MAESTRO); 500 data |= MAESTRO_CHIBUS | MAESTRO_POSTEDWRITE | MAESTRO_DMA_PCITIMING; 501 data &= ~MAESTRO_SWAP_LR; 502 pci_conf_write(sc->pc, sc->pt, CONF_MAESTRO, data); 503 /* Reset direct sound. */ 504 bus_space_write_2(sc->iot, sc->ioh, PORT_HOSTINT_CTRL, 505 HOSTINT_CTRL_DSOUND_RESET); 506 DELAY(10000); /* XXX - too long? */ 507 bus_space_write_2(sc->iot, sc->ioh, PORT_HOSTINT_CTRL, 0); 508 DELAY(10000); 509 510 /* Enable direct sound and hardware volume control interruptions. */ 511 bus_space_write_2(sc->iot, sc->ioh, PORT_HOSTINT_CTRL, 512 HOSTINT_CTRL_DSOUND_INT_ENABLED | HOSTINT_CTRL_HWVOL_ENABLED); 513 514 /* Setup Wave Processor. */ 515 516 /* Enable WaveCache, set DMA base address. */ 517 wp_reg_write(sc, WPREG_WAVE_ROMRAM, 518 WP_WAVE_VIRTUAL_ENABLED | WP_WAVE_DRAM_ENABLED); 519 bus_space_write_2(sc->iot, sc->ioh, PORT_WAVCACHE_CTRL, 520 WAVCACHE_ENABLED | WAVCACHE_WTSIZE_4MB); 521 522 for (reg = WAVCACHE_PCMBAR; reg < WAVCACHE_PCMBAR + 4; reg++) 523 wc_reg_write(sc, reg, 524 sc->physaddr >> WAVCACHE_BASEADDR_SHIFT); 525 526 /* Setup Codec/Ringbus. */ 527 maestro_initcodec(sc); 528 bus_space_write_4(sc->iot, sc->ioh, PORT_RINGBUS_CTRL, 529 RINGBUS_CTRL_RINGBUS_ENABLED | RINGBUS_CTRL_ACLINK_ENABLED); 530 531 wp_reg_write(sc, WPREG_BASE, 0x8500); /* Parallel I/O */ 532 ringbus_setdest(sc, RINGBUS_SRC_ADC, 533 RINGBUS_DEST_STEREO | RINGBUS_DEST_DSOUND_IN); 534 ringbus_setdest(sc, RINGBUS_SRC_DSOUND, 535 RINGBUS_DEST_STEREO | RINGBUS_DEST_DAC); 536 537 /* Setup ASSP. Needed for Dell Inspiron 7500? */ 538 bus_space_write_1(sc->iot, sc->ioh, PORT_ASSP_CTRL_B, 0x00); 539 bus_space_write_1(sc->iot, sc->ioh, PORT_ASSP_CTRL_A, 0x03); 540 bus_space_write_1(sc->iot, sc->ioh, PORT_ASSP_CTRL_C, 0x00); 541 542 /* 543 * Reset hw volume to a known value so that we may handle diffs 544 * off to AC'97. 545 */ 546 547 bus_space_write_1(sc->iot, sc->ioh, PORT_HWVOL_MASTER, MIDDLE_VOLUME); 548 /* Setup GPIO if needed (NEC systems) */ 549 if (sc->flags & MAESTRO_FLAG_SETUPGPIO) { 550 /* Matthew Braithwaite <matt@braithwaite.net> reported that 551 * NEC Versa LX doesn't need GPIO operation. */ 552 bus_space_write_2(sc->iot, sc->ioh, 553 PORT_GPIO_MASK, 0x9ff); 554 bus_space_write_2(sc->iot, sc->ioh, PORT_GPIO_DIR, 555 bus_space_read_2(sc->iot, sc->ioh, PORT_GPIO_DIR) | 0x600); 556 bus_space_write_2(sc->iot, sc->ioh, 557 PORT_GPIO_DATA, 0x200); 558 } 559 } 560 561 /* ----------------------------- 562 * Audio interface 563 */ 564 565 int 566 maestro_round_blocksize(self, blk) 567 void *self; 568 int blk; 569 { 570 return (blk & ~0xf); 571 } 572 573 size_t 574 maestro_round_buffersize(self, direction, size) 575 void *self; 576 int direction; 577 size_t size; 578 { 579 return (size); 580 } 581 582 void * 583 maestro_malloc(arg, dir, size, pool, flags) 584 void *arg; 585 int dir; 586 size_t size; 587 int pool, flags; 588 { 589 struct maestro_softc *sc = (struct maestro_softc *)arg; 590 591 return (salloc_alloc(sc->dmapool, size)); 592 } 593 594 void 595 maestro_free(self, ptr, pool) 596 void *self, *ptr; 597 int pool; 598 { 599 struct maestro_softc *sc = (struct maestro_softc *)self; 600 601 salloc_free(sc->dmapool, ptr); 602 } 603 604 paddr_t 605 maestro_mappage(self, mem, off, prot) 606 void *self, *mem; 607 off_t off; 608 int prot; 609 { 610 struct maestro_softc *sc = (struct maestro_softc *)self; 611 612 if (off < 0) 613 return -1; 614 return bus_dmamem_mmap(sc->dmat, &sc->dmaseg, 1, 615 off, prot, BUS_DMA_WAITOK); 616 } 617 618 int 619 maestro_get_props(self) 620 void *self; 621 { 622 /* struct maestro_softc *sc = (struct maestro_softc *)self; */ 623 624 return (AUDIO_PROP_MMAP | AUDIO_PROP_INDEPENDENT); /* XXX */ 625 } 626 627 int 628 maestro_getdev(self, retp) 629 void *self; 630 struct audio_device *retp; 631 { 632 struct maestro_softc *sc = (struct maestro_softc *)self; 633 634 *retp = *sc->sc_audev; 635 return 0; 636 } 637 638 int 639 maestro_set_port(self, cp) 640 void *self; 641 mixer_ctrl_t *cp; 642 { 643 struct ac97_codec_if *c = ((struct maestro_softc *)self)->codec_if; 644 645 if (c) 646 return (c->vtbl->mixer_set_port(c, cp)); 647 else 648 return (ENXIO); 649 } 650 651 int 652 maestro_get_port(self, cp) 653 void *self; 654 mixer_ctrl_t *cp; 655 { 656 struct ac97_codec_if *c = ((struct maestro_softc *)self)->codec_if; 657 658 if (c) 659 return (c->vtbl->mixer_get_port(c, cp)); 660 else 661 return (ENXIO); 662 } 663 664 int 665 maestro_query_devinfo(self, cp) 666 void *self; 667 mixer_devinfo_t *cp; 668 { 669 struct ac97_codec_if *c = ((struct maestro_softc *)self)->codec_if; 670 671 if (c) 672 return (c->vtbl->query_devinfo(c, cp)); 673 else 674 return (ENXIO); 675 } 676 677 struct audio_encoding maestro_tab[] = { 678 {0, AudioEslinear_le, AUDIO_ENCODING_SLINEAR_LE, 16, 0}, 679 {1, AudioEslinear, AUDIO_ENCODING_SLINEAR, 8, 0}, 680 {2, AudioEulinear, AUDIO_ENCODING_ULINEAR, 8, 0}, 681 {3, AudioEslinear_be, AUDIO_ENCODING_SLINEAR_BE, 16, 682 AUDIO_ENCODINGFLAG_EMULATED}, 683 {4, AudioEulinear_le, AUDIO_ENCODING_ULINEAR_LE, 16, 684 AUDIO_ENCODINGFLAG_EMULATED}, 685 {5, AudioEulinear_be, AUDIO_ENCODING_ULINEAR_BE, 16, 686 AUDIO_ENCODINGFLAG_EMULATED}, 687 {6, AudioEmulaw, AUDIO_ENCODING_ULAW, 8, 688 AUDIO_ENCODINGFLAG_EMULATED}, 689 {7, AudioEalaw, AUDIO_ENCODING_ALAW, 8, 690 AUDIO_ENCODINGFLAG_EMULATED} 691 }; 692 693 int 694 maestro_query_encoding(hdl, fp) 695 void *hdl; 696 struct audio_encoding *fp; 697 { 698 if (fp->index < 0 || fp->index >= lengthof(maestro_tab)) 699 return (EINVAL); 700 *fp = maestro_tab[fp->index]; 701 return (0); 702 } 703 704 #define UNUSED __attribute__((unused)) 705 706 void 707 maestro_set_speed(ch, prate) 708 struct maestro_channel *ch; 709 u_long *prate; 710 { 711 ch->speed = *prate; 712 if ((ch->mode & (MAESTRO_8BIT | MAESTRO_STEREO)) == MAESTRO_8BIT) 713 ch->speed /= 2; 714 715 /* special common case */ 716 if (ch->speed == 48000) { 717 ch->dv = 0x10000; 718 } else { 719 /* compute 16 bits fixed point value of speed/48000, 720 * being careful not to overflow */ 721 ch->dv = (((ch->speed % 48000) << 16U) + 24000) / 48000 722 + ((ch->speed / 48000) << 16U); 723 /* And this is the real rate obtained */ 724 ch->speed = (ch->dv >> 16U) * 48000 + 725 (((ch->dv & 0xffff)*48000)>>16U); 726 } 727 *prate = ch->speed; 728 if ((ch->mode & (MAESTRO_8BIT | MAESTRO_STEREO)) == MAESTRO_8BIT) 729 *prate *= 2; 730 } 731 732 u_int 733 maestro_calc_timer_freq(ch) 734 struct maestro_channel *ch; 735 { 736 u_int ss = 2; 737 738 if (ch->mode & MAESTRO_8BIT) 739 ss = 1; 740 return (ch->speed * ss) / ch->blocksize; 741 } 742 743 void 744 maestro_update_timer(sc) 745 struct maestro_softc *sc; 746 { 747 u_int freq = 0; 748 u_int n; 749 750 if (sc->play.mode & MAESTRO_RUNNING) 751 freq = maestro_calc_timer_freq(&sc->play); 752 if (sc->record.mode & MAESTRO_RUNNING) { 753 n = maestro_calc_timer_freq(&sc->record); 754 if (freq < n) 755 freq = n; 756 } 757 if (freq) { 758 wp_settimer(sc, freq); 759 wp_starttimer(sc); 760 } else 761 wp_stoptimer(sc); 762 } 763 764 765 int 766 maestro_set_params(hdl, setmode, usemode, play, rec) 767 void *hdl; 768 int setmode, usemode; 769 struct audio_params *play, *rec; 770 { 771 struct maestro_softc *sc = (struct maestro_softc *)hdl; 772 773 if ((setmode & AUMODE_PLAY) == 0) 774 return (0); 775 776 /* Disallow parameter change on a running audio for now */ 777 if (sc->play.mode & MAESTRO_RUNNING) 778 return (EINVAL); 779 780 if (play->sample_rate < 4000) 781 play->sample_rate = 4000; 782 else if (play->sample_rate > 48000) 783 play->sample_rate = 48000; 784 785 play->factor = 1; 786 play->sw_code = NULL; 787 if (play->channels != 1 && play->channels != 2) 788 return (EINVAL); 789 790 791 sc->play.mode = MAESTRO_PLAY; 792 if (play->channels == 2) 793 sc->play.mode |= MAESTRO_STEREO; 794 795 if (play->encoding == AUDIO_ENCODING_ULAW) { 796 play->factor = 2; 797 play->sw_code = mulaw_to_slinear16_le; 798 } else if (play->encoding == AUDIO_ENCODING_ALAW) { 799 play->factor = 2; 800 play->sw_code = alaw_to_slinear16_le; 801 } else if (play->precision == 8) { 802 sc->play.mode |= MAESTRO_8BIT; 803 if (play->encoding == AUDIO_ENCODING_ULINEAR_LE || 804 play->encoding == AUDIO_ENCODING_ULINEAR_BE) 805 sc->play.mode |= MAESTRO_UNSIGNED; 806 } 807 else if (play->encoding == AUDIO_ENCODING_ULINEAR_LE) 808 play->sw_code = change_sign16_le; 809 else if (play->encoding == AUDIO_ENCODING_SLINEAR_BE) 810 play->sw_code = swap_bytes; 811 else if (play->encoding == AUDIO_ENCODING_ULINEAR_BE) 812 play->sw_code = change_sign16_swap_bytes_le; 813 else if (play->encoding != AUDIO_ENCODING_SLINEAR_LE) 814 return (EINVAL); 815 816 maestro_set_speed(&sc->play, &play->sample_rate); 817 return (0); 818 } 819 820 int 821 maestro_open(hdl, flags) 822 void *hdl; 823 int flags; 824 { 825 struct maestro_softc *sc = (struct maestro_softc *)hdl; 826 DPRINTF(("%s: open(%d)\n", sc->dev.dv_xname, flags)); 827 828 /* XXX work around VM brokeness */ 829 #if 0 830 if ((OFLAGS(flags) & O_ACCMODE) != O_WRONLY) 831 return (EINVAL); 832 #endif 833 sc->play.mode = MAESTRO_PLAY; 834 sc->record.mode = 0; 835 #ifdef AUDIO_DEBUG 836 maestrointr_called = 0; 837 maestrodma_effective = 0; 838 #endif 839 return (0); 840 } 841 842 void 843 maestro_close(hdl) 844 void *hdl; 845 { 846 struct maestro_softc *sc UNUSED = (struct maestro_softc *)hdl; 847 /* nothing to do */ 848 } 849 850 851 void 852 maestro_channel_stop(ch) 853 struct maestro_channel *ch; 854 { 855 wp_apu_write(ch->sc, ch->num, APUREG_APUTYPE, 856 APUTYPE_INACTIVE << APU_APUTYPE_SHIFT); 857 if (ch->mode & MAESTRO_STEREO) 858 wp_apu_write(ch->sc, ch->num+1, APUREG_APUTYPE, 859 APUTYPE_INACTIVE << APU_APUTYPE_SHIFT); 860 /* four channels for record... */ 861 if (ch->mode & MAESTRO_PLAY) 862 return; 863 wp_apu_write(ch->sc, ch->num+2, APUREG_APUTYPE, 864 APUTYPE_INACTIVE << APU_APUTYPE_SHIFT); 865 if (ch->mode & MAESTRO_STEREO) 866 wp_apu_write(ch->sc, ch->num+3, APUREG_APUTYPE, 867 APUTYPE_INACTIVE << APU_APUTYPE_SHIFT); 868 869 } 870 871 int 872 maestro_halt_input(hdl) 873 void *hdl; 874 { 875 struct maestro_softc *sc = (struct maestro_softc *)hdl; 876 maestro_channel_stop(&sc->record); 877 sc->record.mode &= ~MAESTRO_RUNNING; 878 maestro_update_timer(sc); 879 return 0; 880 } 881 882 int 883 maestro_halt_output(hdl) 884 void *hdl; 885 { 886 struct maestro_softc *sc = (struct maestro_softc *)hdl; 887 888 maestro_channel_stop(&sc->play); 889 sc->play.mode &= ~MAESTRO_RUNNING; 890 maestro_update_timer(sc); 891 return 0; 892 } 893 894 int 895 maestro_trigger_input(hdl, start, end, blksize, intr, arg, param) 896 void *hdl; 897 void *start, *end; 898 int blksize; 899 void (*intr)(void *); 900 void *arg; 901 struct audio_params *param; 902 { 903 struct maestro_softc *sc = (struct maestro_softc *)hdl; 904 905 sc->record.mode |= MAESTRO_RUNNING; 906 sc->record.blocksize = blksize; 907 908 maestro_channel_start(&sc->record); 909 910 sc->record.threshold = sc->record.start; 911 maestro_update_timer(sc); 912 return 0; 913 } 914 915 void 916 maestro_channel_start(ch) 917 struct maestro_channel *ch; 918 { 919 struct maestro_softc *sc = ch->sc; 920 int n = ch->num; 921 int aputype; 922 wcreg_t wcreg = (sc->physaddr - 16) & WAVCACHE_CHCTL_ADDRTAG_MASK; 923 924 switch(ch->mode & (MAESTRO_STEREO | MAESTRO_8BIT)) { 925 case 0: 926 aputype = APUTYPE_16BITLINEAR; 927 break; 928 case MAESTRO_STEREO: 929 aputype = APUTYPE_16BITSTEREO; 930 break; 931 case MAESTRO_8BIT: 932 aputype = APUTYPE_8BITLINEAR; 933 break; 934 case MAESTRO_8BIT|MAESTRO_STEREO: 935 aputype = APUTYPE_8BITSTEREO; 936 break; 937 } 938 if (ch->mode & MAESTRO_UNSIGNED) 939 wcreg |= WAVCACHE_CHCTL_U8; 940 if ((ch->mode & MAESTRO_STEREO) == 0) { 941 DPRINTF(("Setting mono parameters\n")); 942 wp_apu_write(sc, n, APUREG_WAVESPACE, ch->wpwa & 0xff00); 943 wp_apu_write(sc, n, APUREG_CURPTR, ch->current); 944 wp_apu_write(sc, n, APUREG_ENDPTR, ch->end); 945 wp_apu_write(sc, n, APUREG_LOOPLEN, ch->end - ch->start); 946 wp_apu_write(sc, n, APUREG_AMPLITUDE, 0xe800); 947 wp_apu_write(sc, n, APUREG_POSITION, 0x8f00 948 | (RADIUS_CENTERCIRCLE << APU_RADIUS_SHIFT) 949 | (PAN_FRONT << APU_PAN_SHIFT)); 950 wp_apu_write(sc, n, APUREG_FREQ_LOBYTE, APU_plus6dB 951 | ((ch->dv & 0xff) << APU_FREQ_LOBYTE_SHIFT)); 952 wp_apu_write(sc, n, APUREG_FREQ_HIWORD, ch->dv >> 8); 953 wc_ctrl_write(sc, n, wcreg); 954 wp_apu_write(sc, n, APUREG_APUTYPE, 955 (aputype << APU_APUTYPE_SHIFT) | APU_DMA_ENABLED | 0xf); 956 } else { 957 wcreg |= WAVCACHE_CHCTL_STEREO; 958 DPRINTF(("Setting stereo parameters\n")); 959 wp_apu_write(sc, n+1, APUREG_WAVESPACE, ch->wpwa & 0xff00); 960 wp_apu_write(sc, n+1, APUREG_CURPTR, ch->current); 961 wp_apu_write(sc, n+1, APUREG_ENDPTR, ch->end); 962 wp_apu_write(sc, n+1, APUREG_LOOPLEN, ch->end - ch->start); 963 wp_apu_write(sc, n+1, APUREG_AMPLITUDE, 0xe800); 964 wp_apu_write(sc, n+1, APUREG_POSITION, 0x8f00 965 | (RADIUS_CENTERCIRCLE << APU_RADIUS_SHIFT) 966 | (PAN_LEFT << APU_PAN_SHIFT)); 967 wp_apu_write(sc, n+1, APUREG_FREQ_LOBYTE, APU_plus6dB 968 | ((ch->dv & 0xff) << APU_FREQ_LOBYTE_SHIFT)); 969 wp_apu_write(sc, n+1, APUREG_FREQ_HIWORD, ch->dv >> 8); 970 if (ch->mode & MAESTRO_8BIT) 971 wp_apu_write(sc, n, APUREG_WAVESPACE, 972 ch->wpwa & 0xff00); 973 else 974 wp_apu_write(sc, n, APUREG_WAVESPACE, 975 (ch->wpwa|(APU_STEREO >> 1)) & 0xff00); 976 wp_apu_write(sc, n, APUREG_CURPTR, ch->current); 977 wp_apu_write(sc, n, APUREG_ENDPTR, ch->end); 978 wp_apu_write(sc, n, APUREG_LOOPLEN, ch->end - ch->start); 979 wp_apu_write(sc, n, APUREG_AMPLITUDE, 0xe800); 980 wp_apu_write(sc, n, APUREG_POSITION, 0x8f00 981 | (RADIUS_CENTERCIRCLE << APU_RADIUS_SHIFT) 982 | (PAN_RIGHT << APU_PAN_SHIFT)); 983 wp_apu_write(sc, n, APUREG_FREQ_LOBYTE, APU_plus6dB 984 | ((ch->dv & 0xff) << APU_FREQ_LOBYTE_SHIFT)); 985 wp_apu_write(sc, n, APUREG_FREQ_HIWORD, ch->dv >> 8); 986 wc_ctrl_write(sc, n, wcreg); 987 wc_ctrl_write(sc, n+1, wcreg); 988 wp_apu_write(sc, n, APUREG_APUTYPE, 989 (aputype << APU_APUTYPE_SHIFT) | APU_DMA_ENABLED | 0xf); 990 wp_apu_write(sc, n+1, APUREG_APUTYPE, 991 (aputype << APU_APUTYPE_SHIFT) | APU_DMA_ENABLED | 0xf); 992 } 993 } 994 995 int 996 maestro_trigger_output(hdl, start, end, blksize, intr, arg, param) 997 void *hdl; 998 void *start, *end; 999 int blksize; 1000 void (*intr)(void *); 1001 void *arg; 1002 struct audio_params *param; 1003 { 1004 struct maestro_softc *sc = (struct maestro_softc *)hdl; 1005 1006 u_int offset = ((caddr_t)start - sc->dmabase) >> 1; 1007 u_int size = (end - start) >> 1; 1008 sc->play.mode |= MAESTRO_RUNNING; 1009 sc->play.wpwa = APU_USE_SYSMEM | (offset >> 8); 1010 DPRINTF(("maestro_trigger_output: start=%x, end=%x, blksize=%x ", 1011 start, end, blksize)); 1012 DPRINTF(("offset = %x, size=%x\n", offset, size)); 1013 1014 sc->play.intr = intr; 1015 sc->play.intr_arg = arg; 1016 sc->play.blocksize = blksize; 1017 sc->play.end = offset+size; 1018 sc->play.start = offset; 1019 sc->play.current = sc->play.start; 1020 if ((sc->play.mode & (MAESTRO_STEREO | MAESTRO_8BIT)) == MAESTRO_STEREO) { 1021 sc->play.wpwa >>= 1; 1022 sc->play.start >>= 1; 1023 sc->play.end >>= 1; 1024 sc->play.blocksize >>= 1; 1025 } 1026 maestro_channel_start(&sc->play); 1027 1028 sc->play.threshold = sc->play.start; 1029 maestro_update_timer(sc); 1030 1031 return 0; 1032 } 1033 1034 /* ----------------------------- 1035 * Codec interface 1036 */ 1037 1038 int 1039 maestro_read_codec(self, regno, datap) 1040 void *self; 1041 u_int8_t regno; 1042 u_int16_t *datap; 1043 { 1044 struct maestro_softc *sc = (struct maestro_softc *)self; 1045 int t; 1046 1047 /* We have to wait for a SAFE time to write addr/data */ 1048 for (t = 0; t < 20; t++) { 1049 if ((bus_space_read_1(sc->iot, sc->ioh, PORT_CODEC_STAT) 1050 & CODEC_STAT_MASK) != CODEC_STAT_PROGLESS) 1051 break; 1052 DELAY(2); /* 20.8us / 13 */ 1053 } 1054 if (t == 20) 1055 printf("%s: maestro_read_codec() PROGLESS timed out.\n", 1056 sc->dev.dv_xname); 1057 /* XXX return 1 */ 1058 1059 bus_space_write_1(sc->iot, sc->ioh, PORT_CODEC_CMD, 1060 CODEC_CMD_READ | regno); 1061 DELAY(21); /* AC97 cycle = 20.8usec */ 1062 1063 /* Wait for data retrieve */ 1064 for (t = 0; t < 20; t++) { 1065 if ((bus_space_read_1(sc->iot, sc->ioh, PORT_CODEC_STAT) 1066 & CODEC_STAT_MASK) == CODEC_STAT_RW_DONE) 1067 break; 1068 DELAY(2); /* 20.8us / 13 */ 1069 } 1070 if (t == 20) 1071 /* Timed out, but perform dummy read. */ 1072 printf("%s: maestro_read_codec() RW_DONE timed out.\n", 1073 sc->dev.dv_xname); 1074 1075 *datap = bus_space_read_2(sc->iot, sc->ioh, PORT_CODEC_REG); 1076 return 0; 1077 } 1078 1079 int 1080 maestro_write_codec(self, regno, data) 1081 void *self; 1082 u_int8_t regno; 1083 u_int16_t data; 1084 { 1085 struct maestro_softc *sc = (struct maestro_softc *)self; 1086 int t; 1087 1088 /* We have to wait for a SAFE time to write addr/data */ 1089 for (t = 0; t < 20; t++) { 1090 if ((bus_space_read_1(sc->iot, sc->ioh, PORT_CODEC_STAT) 1091 & CODEC_STAT_MASK) != CODEC_STAT_PROGLESS) 1092 break; 1093 DELAY(2); /* 20.8us / 13 */ 1094 } 1095 if (t == 20) { 1096 /* Timed out. Abort writing. */ 1097 printf("%s: maestro_write_codec() PROGLESS timed out.\n", 1098 sc->dev.dv_xname); 1099 return 1; 1100 } 1101 1102 bus_space_write_2(sc->iot, sc->ioh, PORT_CODEC_REG, data); 1103 bus_space_write_1(sc->iot, sc->ioh, PORT_CODEC_CMD, 1104 CODEC_CMD_WRITE | regno); 1105 1106 return 0; 1107 } 1108 1109 int 1110 maestro_attach_codec(self, cif) 1111 void *self; 1112 struct ac97_codec_if *cif; 1113 { 1114 struct maestro_softc *sc = (struct maestro_softc *)self; 1115 1116 sc->codec_if = cif; 1117 return 0; 1118 } 1119 1120 void 1121 maestro_reset_codec(self) 1122 void *self UNUSED; 1123 { 1124 } 1125 1126 void 1127 maestro_initcodec(self) 1128 void *self; 1129 { 1130 struct maestro_softc *sc = (struct maestro_softc *)self; 1131 u_int16_t data; 1132 1133 if (bus_space_read_4(sc->iot, sc->ioh, PORT_RINGBUS_CTRL) 1134 & RINGBUS_CTRL_ACLINK_ENABLED) { 1135 bus_space_write_4(sc->iot, sc->ioh, PORT_RINGBUS_CTRL, 0); 1136 DELAY(104); /* 20.8us * (4 + 1) */ 1137 } 1138 /* XXX - 2nd codec should be looked at. */ 1139 bus_space_write_4(sc->iot, sc->ioh, 1140 PORT_RINGBUS_CTRL, RINGBUS_CTRL_AC97_SWRESET); 1141 DELAY(2); 1142 bus_space_write_4(sc->iot, sc->ioh, 1143 PORT_RINGBUS_CTRL, RINGBUS_CTRL_ACLINK_ENABLED); 1144 DELAY(21); 1145 1146 maestro_read_codec(sc, 0, &data); 1147 if ((bus_space_read_1(sc->iot, sc->ioh, PORT_CODEC_STAT) 1148 & CODEC_STAT_MASK) != 0) { 1149 bus_space_write_4(sc->iot, sc->ioh, 1150 PORT_RINGBUS_CTRL, 0); 1151 DELAY(21); 1152 1153 /* Try cold reset. */ 1154 printf("%s: resetting codec\n", sc->dev.dv_xname); 1155 1156 data = bus_space_read_2(sc->iot, sc->ioh, PORT_GPIO_DIR); 1157 if (pci_conf_read(sc->pc, sc->pt, 0x58) & 1) 1158 data |= 0x10; 1159 data |= 0x009 & 1160 ~bus_space_read_2(sc->iot, sc->ioh, PORT_GPIO_DATA); 1161 bus_space_write_2(sc->iot, sc->ioh, 1162 PORT_GPIO_MASK, 0xff6); 1163 bus_space_write_2(sc->iot, sc->ioh, 1164 PORT_GPIO_DIR, data | 0x009); 1165 bus_space_write_2(sc->iot, sc->ioh, 1166 PORT_GPIO_DATA, 0x000); 1167 DELAY(2); 1168 bus_space_write_2(sc->iot, sc->ioh, 1169 PORT_GPIO_DATA, 0x001); 1170 DELAY(1); 1171 bus_space_write_2(sc->iot, sc->ioh, 1172 PORT_GPIO_DATA, 0x009); 1173 DELAY(500000); 1174 bus_space_write_2(sc->iot, sc->ioh, 1175 PORT_GPIO_DIR, data); 1176 DELAY(84); /* 20.8us * 4 */ 1177 bus_space_write_4(sc->iot, sc->ioh, 1178 PORT_RINGBUS_CTRL, RINGBUS_CTRL_ACLINK_ENABLED); 1179 DELAY(21); 1180 } 1181 1182 /* Check the codec to see is still busy */ 1183 if ((bus_space_read_1(sc->iot, sc->ioh, PORT_CODEC_STAT) & 1184 CODEC_STAT_MASK) != 0) { 1185 printf("%s: codec failure\n", sc->dev.dv_xname); 1186 } 1187 } 1188 1189 /* ----------------------------- 1190 * Power management interface 1191 */ 1192 1193 void 1194 maestro_powerhook(why, self) 1195 int why; 1196 void *self; 1197 { 1198 struct maestro_softc *sc = (struct maestro_softc *)self; 1199 1200 if (why != PWR_RESUME) { 1201 /* Power down device on shutdown. */ 1202 DPRINTF(("maestro: power down\n")); 1203 sc->suspend = why; 1204 if (sc->record.mode & MAESTRO_RUNNING) { 1205 sc->record.current = wp_apu_read(sc, sc->record.num, APUREG_CURPTR); 1206 maestro_channel_stop(&sc->record); 1207 } 1208 if (sc->play.mode & MAESTRO_RUNNING) { 1209 sc->play.current = wp_apu_read(sc, sc->play.num, APUREG_CURPTR); 1210 maestro_channel_stop(&sc->play); 1211 } 1212 1213 wp_stoptimer(sc); 1214 1215 /* Power down everything except clock. */ 1216 bus_space_write_2(sc->iot, sc->ioh, PORT_HOSTINT_CTRL, 0); 1217 maestro_write_codec(sc, AC97_REG_POWER, 0xdf00); 1218 DELAY(20); 1219 bus_space_write_4(sc->iot, sc->ioh, PORT_RINGBUS_CTRL, 0); 1220 DELAY(1); 1221 maestro_power(sc, PPMI_D3); 1222 } else { 1223 /* Power up device on resume. */ 1224 DPRINTF(("maestro: power resume\n")); 1225 if (sc->suspend == PWR_RESUME) { 1226 printf("%s: resume without suspend?\n", 1227 sc->dev.dv_xname); 1228 sc->suspend = why; 1229 return; 1230 } 1231 sc->suspend = why; 1232 maestro_power(sc, PPMI_D0); 1233 DELAY(100000); 1234 maestro_init(sc); 1235 /* Restore codec settings */ 1236 if (sc->codec_if) 1237 sc->codec_if->vtbl->restore_ports(sc->codec_if); 1238 if (sc->play.mode & MAESTRO_RUNNING) 1239 maestro_channel_start(&sc->play); 1240 if (sc->record.mode & MAESTRO_RUNNING) 1241 maestro_channel_start(&sc->record); 1242 maestro_update_timer(sc); 1243 } 1244 } 1245 1246 void 1247 maestro_power(sc, status) 1248 struct maestro_softc *sc; 1249 int status; 1250 { 1251 int data; 1252 1253 /* Set the power state of the device. */ 1254 data = pci_conf_read(sc->pc, sc->pt, CONF_PM_PTR); 1255 data = pci_conf_read(sc->pc, sc->pt, data); 1256 if (data == PPMI_CID) 1257 pci_conf_write(sc->pc, sc->pt, data + PM_CTRL, status); 1258 } 1259 1260 void 1261 maestro_channel_advance_dma(ch) 1262 struct maestro_channel *ch; 1263 { 1264 wpreg_t pos; 1265 #ifdef AUDIO_DEBUG 1266 maestrointr_called++; 1267 #endif 1268 for (;;) { 1269 pos = wp_apu_read(ch->sc, ch->num, APUREG_CURPTR); 1270 /* Are we still processing the current dma block ? */ 1271 if (pos >= ch->threshold && 1272 pos < ch->threshold + ch->blocksize/2) 1273 break; 1274 ch->threshold += ch->blocksize/2; 1275 if (ch->threshold >= ch->end) 1276 ch->threshold = ch->start; 1277 (*ch->intr)(ch->intr_arg); 1278 #ifdef AUDIO_DEBUG 1279 maestrodma_effective++; 1280 #endif 1281 } 1282 1283 #ifdef AUDIO_DEBUG 1284 if (maestrodebug && maestrointr_called % 64 == 0) 1285 printf("maestro: dma advanced %lu for %lu calls\n", 1286 maestrodma_effective, maestrointr_called); 1287 #endif 1288 } 1289 1290 /* Some maestro makes sometimes get desynchronized in stereo mode. */ 1291 void 1292 maestro_channel_suppress_jitter(ch) 1293 struct maestro_channel *ch; 1294 { 1295 int cp, diff; 1296 1297 /* Verify that both channels are not too far off. */ 1298 cp = wp_apu_read(ch->sc, ch->num, APUREG_CURPTR); 1299 diff = wp_apu_read(ch->sc, ch->num+1, APUREG_CURPTR) - cp; 1300 if (diff > 4 || diff < -4) 1301 /* Otherwise, directly resynch the 2nd channel. */ 1302 bus_space_write_2(ch->sc->iot, ch->sc->ioh, 1303 PORT_DSP_DATA, cp); 1304 } 1305 1306 /* ----------------------------- 1307 * Interrupt handler interface 1308 */ 1309 int 1310 maestro_intr(arg) 1311 void *arg; 1312 { 1313 struct maestro_softc *sc = (struct maestro_softc *)arg; 1314 u_int16_t status; 1315 1316 status = bus_space_read_1(sc->iot, sc->ioh, PORT_HOSTINT_STAT); 1317 if (status == 0) 1318 return 0; /* Not for us? */ 1319 1320 /* Acknowledge all. */ 1321 bus_space_write_2(sc->iot, sc->ioh, PORT_INT_STAT, 1); 1322 bus_space_write_1(sc->iot, sc->ioh, PORT_HOSTINT_STAT, status); 1323 1324 /* Hardware volume support */ 1325 if (status & HOSTINT_STAT_HWVOL && sc->codec_if != NULL) { 1326 int n, i, delta, v; 1327 mixer_ctrl_t hwvol; 1328 1329 n = bus_space_read_1(sc->iot, sc->ioh, PORT_HWVOL_MASTER); 1330 /* Special case: Mute key */ 1331 if (n & 0x11) { 1332 hwvol.type = AUDIO_MIXER_ENUM; 1333 hwvol.dev = 1334 sc->codec_if->vtbl->get_portnum_by_name(sc->codec_if, 1335 AudioCoutputs, AudioNmaster, AudioNmute); 1336 sc->codec_if->vtbl->mixer_get_port(sc->codec_if, &hwvol); 1337 hwvol.un.ord = !hwvol.un.ord; 1338 } else { 1339 hwvol.type = AUDIO_MIXER_VALUE; 1340 hwvol.un.value.num_channels = 2; 1341 hwvol.dev = 1342 sc->codec_if->vtbl->get_portnum_by_name( 1343 sc->codec_if, AudioCoutputs, AudioNmaster, 1344 NULL); 1345 sc->codec_if->vtbl->mixer_get_port(sc->codec_if, &hwvol); 1346 /* XXX AC'97 yields five bits for master volume. */ 1347 delta = (n - MIDDLE_VOLUME)/STEP_VOLUME * 8; 1348 for (i = 0; i < hwvol.un.value.num_channels; i++) { 1349 v = ((int)hwvol.un.value.level[i]) + delta; 1350 if (v < 0) 1351 v = 0; 1352 else if (v > 255) 1353 v = 255; 1354 hwvol.un.value.level[i] = v; 1355 } 1356 } 1357 sc->codec_if->vtbl->mixer_set_port(sc->codec_if, &hwvol); 1358 /* Reset to compute next diffs */ 1359 bus_space_write_1(sc->iot, sc->ioh, PORT_HWVOL_MASTER, 1360 MIDDLE_VOLUME); 1361 } 1362 1363 if (sc->play.mode & MAESTRO_RUNNING) { 1364 maestro_channel_advance_dma(&sc->play); 1365 if (sc->play.mode & MAESTRO_STEREO) 1366 maestro_channel_suppress_jitter(&sc->play); 1367 } 1368 1369 if (sc->record.mode & MAESTRO_RUNNING) 1370 maestro_channel_advance_dma(&sc->record); 1371 1372 return 1; 1373 } 1374 1375 /* ----------------------------- 1376 * Hardware interface 1377 */ 1378 1379 /* Codec/Ringbus */ 1380 1381 void 1382 ringbus_setdest(struct maestro_softc *sc, int src, int dest) 1383 { 1384 u_int32_t data; 1385 1386 data = bus_space_read_4(sc->iot, sc->ioh, PORT_RINGBUS_CTRL); 1387 data &= ~(0xfU << src); 1388 data |= (0xfU & dest) << src; 1389 bus_space_write_4(sc->iot, sc->ioh, PORT_RINGBUS_CTRL, data); 1390 } 1391 1392 /* Wave Processor */ 1393 1394 wpreg_t 1395 wp_reg_read(struct maestro_softc *sc, int reg) 1396 { 1397 bus_space_write_2(sc->iot, sc->ioh, PORT_DSP_INDEX, reg); 1398 return bus_space_read_2(sc->iot, sc->ioh, PORT_DSP_DATA); 1399 } 1400 1401 void 1402 wp_reg_write(struct maestro_softc *sc, int reg, wpreg_t data) 1403 { 1404 bus_space_write_2(sc->iot, sc->ioh, PORT_DSP_INDEX, reg); 1405 bus_space_write_2(sc->iot, sc->ioh, PORT_DSP_DATA, data); 1406 } 1407 1408 static void 1409 apu_setindex(struct maestro_softc *sc, int reg) 1410 { 1411 int t; 1412 1413 wp_reg_write(sc, WPREG_CRAM_PTR, reg); 1414 /* Sometimes WP fails to set apu register index. */ 1415 for (t = 0; t < 1000; t++) { 1416 if (bus_space_read_2(sc->iot, sc->ioh, 1417 PORT_DSP_DATA) == reg) 1418 break; 1419 bus_space_write_2(sc->iot, sc->ioh, PORT_DSP_DATA, reg); 1420 } 1421 if (t == 1000) 1422 printf("%s: apu_setindex() timeout\n", sc->dev.dv_xname); 1423 } 1424 1425 wpreg_t 1426 wp_apu_read(struct maestro_softc *sc, int ch, int reg) 1427 { 1428 wpreg_t ret; 1429 1430 apu_setindex(sc, ((unsigned)ch << 4) + reg); 1431 ret = wp_reg_read(sc, WPREG_DATA_PORT); 1432 return ret; 1433 } 1434 1435 void 1436 wp_apu_write(struct maestro_softc *sc, int ch, int reg, wpreg_t data) 1437 { 1438 int t; 1439 1440 apu_setindex(sc, ((unsigned)ch << 4) + reg); 1441 wp_reg_write(sc, WPREG_DATA_PORT, data); 1442 for (t = 0; t < 1000; t++) { 1443 if (bus_space_read_2(sc->iot, sc->ioh, PORT_DSP_DATA) == data) 1444 break; 1445 bus_space_write_2(sc->iot, sc->ioh, PORT_DSP_DATA, data); 1446 } 1447 if (t == 1000) 1448 printf("%s: wp_apu_write() timeout\n", sc->dev.dv_xname); 1449 } 1450 1451 void 1452 wp_settimer(struct maestro_softc *sc, u_int freq) 1453 { 1454 u_int clock = 48000 << 2; 1455 u_int prescale = 0, divide = (freq != 0) ? (clock / freq) : ~0; 1456 1457 if (divide < 4) 1458 divide = 4; 1459 else if (divide > 32 << 8) 1460 divide = 32 << 8; 1461 1462 for (; divide > 32 << 1; divide >>= 1) 1463 prescale++; 1464 divide = (divide + 1) >> 1; 1465 1466 for (; prescale < 7 && divide > 2 && !(divide & 1); divide >>= 1) 1467 prescale++; 1468 1469 wp_reg_write(sc, WPREG_TIMER_ENABLE, 0); 1470 wp_reg_write(sc, WPREG_TIMER_FREQ, 1471 (prescale << WP_TIMER_FREQ_PRESCALE_SHIFT) | (divide - 1)); 1472 wp_reg_write(sc, WPREG_TIMER_ENABLE, 1); 1473 } 1474 1475 void 1476 wp_starttimer(struct maestro_softc *sc) 1477 { 1478 wp_reg_write(sc, WPREG_TIMER_START, 1); 1479 } 1480 1481 void 1482 wp_stoptimer(struct maestro_softc *sc) 1483 { 1484 wp_reg_write(sc, WPREG_TIMER_START, 0); 1485 bus_space_write_2(sc->iot, sc->ioh, PORT_INT_STAT, 1); 1486 } 1487 1488 /* WaveCache */ 1489 1490 wcreg_t 1491 wc_reg_read(struct maestro_softc *sc, int reg) 1492 { 1493 bus_space_write_2(sc->iot, sc->ioh, PORT_WAVCACHE_INDEX, reg); 1494 return bus_space_read_2(sc->iot, sc->ioh, PORT_WAVCACHE_DATA); 1495 } 1496 1497 void 1498 wc_reg_write(struct maestro_softc *sc, int reg, wcreg_t data) 1499 { 1500 bus_space_write_2(sc->iot, sc->ioh, PORT_WAVCACHE_INDEX, reg); 1501 bus_space_write_2(sc->iot, sc->ioh, PORT_WAVCACHE_DATA, data); 1502 } 1503 1504 u_int16_t 1505 wc_ctrl_read(struct maestro_softc *sc, int ch) 1506 { 1507 return wc_reg_read(sc, ch << 3); 1508 } 1509 1510 void 1511 wc_ctrl_write(struct maestro_softc *sc, int ch, wcreg_t data) 1512 { 1513 wc_reg_write(sc, ch << 3, data); 1514 } 1515 1516 /* ----------------------------- 1517 * Simple zone allocator. 1518 * (All memory allocated in advance) 1519 */ 1520 1521 salloc_t 1522 salloc_new(addr, size, nzones) 1523 caddr_t addr; 1524 size_t size; 1525 int nzones; 1526 { 1527 struct salloc_pool *pool; 1528 struct salloc_zone *space; 1529 int i; 1530 1531 MALLOC(pool, salloc_t, sizeof *pool + nzones * sizeof pool->zones[0], 1532 M_TEMP, M_NOWAIT); 1533 if (pool == NULL) 1534 return NULL; 1535 SLIST_INIT(&pool->free); 1536 SLIST_INIT(&pool->used); 1537 SLIST_INIT(&pool->spare); 1538 /* Espie says the following line is obvious */ 1539 pool->zones = (struct salloc_zone *)(pool + 1); 1540 for (i = 1; i < nzones; i++) 1541 SLIST_INSERT_HEAD(&pool->spare, &pool->zones[i], link); 1542 space = &pool->zones[0]; 1543 space->addr = addr; 1544 space->size = size; 1545 SLIST_INSERT_HEAD(&pool->free, space, link); 1546 return pool; 1547 } 1548 1549 void 1550 salloc_destroy(pool) 1551 salloc_t pool; 1552 { 1553 FREE(pool, M_TEMP); 1554 } 1555 1556 void 1557 salloc_insert(pool, head, zone, merge) 1558 salloc_t pool; 1559 struct salloc_head *head; 1560 struct salloc_zone *zone; 1561 int merge; 1562 { 1563 struct salloc_zone *prev, *next; 1564 1565 /* 1566 * Insert a zone into an ordered list of zones, possibly 1567 * merging adjacent zones. 1568 */ 1569 prev = NULL; 1570 SLIST_FOREACH(next, head, link) { 1571 if (next->addr > zone->addr) 1572 break; 1573 prev = next; 1574 } 1575 1576 if (merge && prev && prev->addr + prev->size == zone->addr) { 1577 prev->size += zone->size; 1578 SLIST_INSERT_HEAD(&pool->spare, zone, link); 1579 zone = prev; 1580 } else if (prev) 1581 SLIST_INSERT_AFTER(prev, zone, link); 1582 else 1583 SLIST_INSERT_HEAD(head, zone, link); 1584 if (merge && next && zone->addr + zone->size == next->addr) { 1585 zone->size += next->size; 1586 SLIST_REMOVE(head, next, salloc_zone, link); 1587 SLIST_INSERT_HEAD(&pool->spare, next, link); 1588 } 1589 } 1590 1591 caddr_t 1592 salloc_alloc(pool, size) 1593 salloc_t pool; 1594 size_t size; 1595 { 1596 struct salloc_zone *zone, *uzone; 1597 1598 SLIST_FOREACH(zone, &pool->free, link) 1599 if (zone->size >= size) 1600 break; 1601 if (zone == SLIST_END(&pool->free)) 1602 return NULL; 1603 if (zone->size == size) { 1604 SLIST_REMOVE(&pool->free, zone, salloc_zone, link); 1605 uzone = zone; 1606 } else { 1607 uzone = SLIST_FIRST(&pool->spare); 1608 if (uzone == NULL) 1609 return NULL; /* XXX */ 1610 SLIST_REMOVE_HEAD(&pool->spare, link); 1611 uzone->size = size; 1612 uzone->addr = zone->addr; 1613 zone->size -= size; 1614 zone->addr += size; 1615 } 1616 salloc_insert(pool, &pool->used, uzone, 0); 1617 return uzone->addr; 1618 } 1619 1620 void 1621 salloc_free(pool, addr) 1622 salloc_t pool; 1623 caddr_t addr; 1624 { 1625 struct salloc_zone *zone; 1626 1627 SLIST_FOREACH(zone, &pool->used, link) 1628 if (zone->addr == addr) 1629 break; 1630 #ifdef DIAGNOSTIC 1631 if (zone == SLIST_END(&pool->used)) 1632 panic("salloc_free: freeing unallocated memory"); 1633 #endif 1634 SLIST_REMOVE(&pool->used, zone, salloc_zone, link); 1635 salloc_insert(pool, &pool->free, zone, 1); 1636 } 1637