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