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