1 /* $OpenBSD: autri.c,v 1.24 2010/04/08 00:23:53 tedu Exp $ */ 2 3 /* 4 * Copyright (c) 2001 SOMEYA Yoshihiko and KUROSAWA Takahiro. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 21 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 */ 27 28 /* 29 * Trident 4DWAVE-DX/NX, SiS 7018, ALi M5451 Sound Driver 30 * 31 * The register information is taken from the ALSA driver. 32 * 33 * Documentation links: 34 * - ftp://ftp.alsa-project.org/pub/manuals/trident/ 35 */ 36 37 #include "midi.h" 38 39 #include <sys/param.h> 40 #include <sys/systm.h> 41 #include <sys/kernel.h> 42 #include <sys/fcntl.h> 43 #include <sys/malloc.h> 44 #include <sys/device.h> 45 46 #include <dev/pci/pcidevs.h> 47 #include <dev/pci/pcireg.h> 48 #include <dev/pci/pcivar.h> 49 50 #include <sys/audioio.h> 51 #include <dev/audio_if.h> 52 #include <dev/midi_if.h> 53 #include <dev/mulaw.h> 54 #include <dev/auconv.h> 55 #include <dev/ic/ac97.h> 56 #include <dev/ic/mpuvar.h> 57 58 #include <machine/bus.h> 59 #include <machine/intr.h> 60 61 #include <dev/pci/autrireg.h> 62 #include <dev/pci/autrivar.h> 63 64 #ifdef AUDIO_DEBUG 65 # define DPRINTF(x) if (autridebug) printf x 66 # define DPRINTFN(n,x) if (autridebug > (n)) printf x 67 int autridebug = 0; 68 #else 69 # define DPRINTF(x) 70 # define DPRINTFN(n,x) 71 #endif 72 73 int autri_match(struct device *, void *, void *); 74 void autri_attach(struct device *, struct device *, void *); 75 int autri_intr(void *); 76 77 #define DMAADDR(p) ((p)->map->dm_segs[0].ds_addr) 78 #define KERNADDR(p) ((void *)((p)->addr)) 79 80 int autri_allocmem(struct autri_softc *, size_t, size_t, struct autri_dma *); 81 int autri_freemem(struct autri_softc *, struct autri_dma *); 82 83 #define TWRITE1(sc, r, x) bus_space_write_1((sc)->memt, (sc)->memh, (r), (x)) 84 #define TWRITE2(sc, r, x) bus_space_write_2((sc)->memt, (sc)->memh, (r), (x)) 85 #define TWRITE4(sc, r, x) bus_space_write_4((sc)->memt, (sc)->memh, (r), (x)) 86 #define TREAD1(sc, r) bus_space_read_1((sc)->memt, (sc)->memh, (r)) 87 #define TREAD2(sc, r) bus_space_read_2((sc)->memt, (sc)->memh, (r)) 88 #define TREAD4(sc, r) bus_space_read_4((sc)->memt, (sc)->memh, (r)) 89 90 static __inline void autri_reg_set_1(struct autri_softc *, int, uint8_t); 91 static __inline void autri_reg_clear_1(struct autri_softc *, int, uint8_t); 92 static __inline void autri_reg_set_4(struct autri_softc *, int, uint32_t); 93 static __inline void autri_reg_clear_4(struct autri_softc *, int, uint32_t); 94 95 int autri_attach_codec(void *sc, struct ac97_codec_if *); 96 int autri_read_codec(void *sc, u_int8_t a, u_int16_t *d); 97 int autri_write_codec(void *sc, u_int8_t a, u_int16_t d); 98 void autri_reset_codec(void *sc); 99 enum ac97_host_flags autri_flags_codec(void *); 100 101 void autri_powerhook(int why,void *addr); 102 int autri_init(void *sc); 103 struct autri_dma *autri_find_dma(struct autri_softc *, void *); 104 void autri_setup_channel(struct autri_softc *sc,int mode, 105 struct audio_params *param); 106 void autri_enable_interrupt(struct autri_softc *sc, int ch); 107 void autri_disable_interrupt(struct autri_softc *sc, int ch); 108 void autri_startch(struct autri_softc *sc, int ch, int ch_intr); 109 void autri_stopch(struct autri_softc *sc, int ch, int ch_intr); 110 void autri_enable_loop_interrupt(void *sc); 111 #if 0 112 void autri_disable_loop_interrupt(void *sc); 113 #endif 114 115 struct cfdriver autri_cd = { 116 NULL, "autri", DV_DULL 117 }; 118 119 struct cfattach autri_ca = { 120 sizeof(struct autri_softc), autri_match, autri_attach 121 }; 122 123 int autri_open(void *, int); 124 void autri_close(void *); 125 int autri_query_encoding(void *, struct audio_encoding *); 126 int autri_set_params(void *, int, int, struct audio_params *, 127 struct audio_params *); 128 int autri_round_blocksize(void *, int); 129 int autri_trigger_output(void *, void *, void *, int, void (*)(void *), 130 void *, struct audio_params *); 131 int autri_trigger_input(void *, void *, void *, int, void (*)(void *), 132 void *, struct audio_params *); 133 int autri_halt_output(void *); 134 int autri_halt_input(void *); 135 int autri_getdev(void *, struct audio_device *); 136 int autri_mixer_set_port(void *, mixer_ctrl_t *); 137 int autri_mixer_get_port(void *, mixer_ctrl_t *); 138 void *autri_malloc(void *, int, size_t, int, int); 139 void autri_free(void *, void *, int); 140 paddr_t autri_mappage(void *, void *, off_t, int); 141 int autri_get_props(void *); 142 int autri_query_devinfo(void *addr, mixer_devinfo_t *dip); 143 144 int autri_get_portnum_by_name(struct autri_softc *, char *, char *, char *); 145 146 struct audio_hw_if autri_hw_if = { 147 autri_open, 148 autri_close, 149 NULL, /* drain */ 150 autri_query_encoding, 151 autri_set_params, 152 autri_round_blocksize, 153 NULL, /* commit_settings */ 154 NULL, /* init_output */ 155 NULL, /* init_input */ 156 NULL, /* start_output */ 157 NULL, /* start_input */ 158 autri_halt_output, 159 autri_halt_input, 160 NULL, /* speaker_ctl */ 161 autri_getdev, 162 NULL, /* setfd */ 163 autri_mixer_set_port, 164 autri_mixer_get_port, 165 autri_query_devinfo, 166 autri_malloc, 167 autri_free, 168 NULL, 169 autri_mappage, 170 autri_get_props, 171 autri_trigger_output, 172 autri_trigger_input, 173 NULL 174 }; 175 176 #if NMIDI > 0 177 void autri_midi_close(void *); 178 void autri_midi_getinfo(void *, struct midi_info *); 179 int autri_midi_open(void *, int, void (*)(void *, int), 180 void (*)(void *), void *); 181 int autri_midi_output(void *, int); 182 183 struct midi_hw_if autri_midi_hw_if = { 184 autri_midi_open, 185 autri_midi_close, 186 autri_midi_output, 187 NULL, /* flush */ 188 autri_midi_getinfo, 189 NULL, /* ioctl */ 190 }; 191 #endif 192 193 /* 194 * register set/clear bit 195 */ 196 static __inline void 197 autri_reg_set_1(sc, no, mask) 198 struct autri_softc *sc; 199 int no; 200 uint8_t mask; 201 { 202 bus_space_write_1(sc->memt, sc->memh, no, 203 (bus_space_read_1(sc->memt, sc->memh, no) | mask)); 204 } 205 206 static __inline void 207 autri_reg_clear_1(sc, no, mask) 208 struct autri_softc *sc; 209 int no; 210 uint8_t mask; 211 { 212 bus_space_write_1(sc->memt, sc->memh, no, 213 (bus_space_read_1(sc->memt, sc->memh, no) & ~mask)); 214 } 215 216 static __inline void 217 autri_reg_set_4(sc, no, mask) 218 struct autri_softc *sc; 219 int no; 220 uint32_t mask; 221 { 222 bus_space_write_4(sc->memt, sc->memh, no, 223 (bus_space_read_4(sc->memt, sc->memh, no) | mask)); 224 } 225 226 static __inline void 227 autri_reg_clear_4(sc, no, mask) 228 struct autri_softc *sc; 229 int no; 230 uint32_t mask; 231 { 232 bus_space_write_4(sc->memt, sc->memh, no, 233 (bus_space_read_4(sc->memt, sc->memh, no) & ~mask)); 234 } 235 236 /* 237 * AC97 codec 238 */ 239 int 240 autri_attach_codec(sc_, codec_if) 241 void *sc_; 242 struct ac97_codec_if *codec_if; 243 { 244 struct autri_codec_softc *sc = sc_; 245 246 DPRINTF(("autri_attach_codec()\n")); 247 248 sc->codec_if = codec_if; 249 return 0; 250 } 251 252 int 253 autri_read_codec(sc_, index, data) 254 void *sc_; 255 u_int8_t index; 256 u_int16_t *data; 257 { 258 struct autri_codec_softc *codec = sc_; 259 struct autri_softc *sc = codec->sc; 260 u_int32_t status, addr, cmd, busy; 261 u_int16_t count; 262 263 /*DPRINTF(("sc->sc->type : 0x%X",sc->sc->type));*/ 264 265 switch (sc->sc_devid) { 266 case AUTRI_DEVICE_ID_4DWAVE_DX: 267 addr = AUTRI_DX_ACR1; 268 cmd = AUTRI_DX_ACR1_CMD_READ; 269 busy = AUTRI_DX_ACR1_BUSY_READ; 270 break; 271 case AUTRI_DEVICE_ID_4DWAVE_NX: 272 addr = AUTRI_NX_ACR2; 273 cmd = AUTRI_NX_ACR2_CMD_READ; 274 busy = AUTRI_NX_ACR2_BUSY_READ | AUTRI_NX_ACR2_RECV_WAIT; 275 break; 276 case AUTRI_DEVICE_ID_SIS_7018: 277 addr = AUTRI_SIS_ACRD; 278 cmd = AUTRI_SIS_ACRD_CMD_READ; 279 busy = AUTRI_SIS_ACRD_BUSY_READ | AUTRI_SIS_ACRD_AUDIO_BUSY; 280 break; 281 case AUTRI_DEVICE_ID_ALI_M5451: 282 if (sc->sc_revision > 0x01) 283 addr = AUTRI_ALI_ACWR; 284 else 285 addr = AUTRI_ALI_ACRD; 286 cmd = AUTRI_ALI_ACRD_CMD_READ; 287 busy = AUTRI_ALI_ACRD_BUSY_READ; 288 break; 289 default: 290 printf("%s: autri_read_codec : unknown device\n", 291 sc->sc_dev.dv_xname); 292 return -1; 293 } 294 295 /* wait for 'Ready to Read' */ 296 for (count=0; count < 0xffff; count++) { 297 if ((TREAD4(sc, addr) & busy) == 0) 298 break; 299 DELAY(1); 300 } 301 302 if (count == 0xffff) { 303 printf("%s: Codec timeout. Busy reading AC97 codec.\n", 304 sc->sc_dev.dv_xname); 305 return -1; 306 } 307 308 /* send Read Command to AC97 */ 309 TWRITE4(sc, addr, (index & 0x7f) | cmd); 310 311 /* wait for 'Returned data is available' */ 312 for (count=0; count < 0xffff; count++) { 313 status = TREAD4(sc, addr); 314 if ((status & busy) == 0) 315 break; 316 DELAY(1); 317 } 318 319 if (count == 0xffff) { 320 printf("%s: Codec timeout. Busy reading AC97 codec.\n", 321 sc->sc_dev.dv_xname); 322 return -1; 323 } 324 325 *data = (status >> 16) & 0x0000ffff; 326 /*DPRINTF(("autri_read_codec(0x%X) return 0x%X\n",reg,*data));*/ 327 return 0; 328 } 329 330 int 331 autri_write_codec(sc_, index, data) 332 void *sc_; 333 u_int8_t index; 334 u_int16_t data; 335 { 336 struct autri_codec_softc *codec = sc_; 337 struct autri_softc *sc = codec->sc; 338 u_int32_t addr, cmd, busy; 339 u_int16_t count; 340 341 /*DPRINTF(("autri_write_codec(0x%X,0x%X)\n",index,data));*/ 342 343 switch (sc->sc_devid) { 344 case AUTRI_DEVICE_ID_4DWAVE_DX: 345 addr = AUTRI_DX_ACR0; 346 cmd = AUTRI_DX_ACR0_CMD_WRITE; 347 busy = AUTRI_DX_ACR0_BUSY_WRITE; 348 break; 349 case AUTRI_DEVICE_ID_4DWAVE_NX: 350 addr = AUTRI_NX_ACR1; 351 cmd = AUTRI_NX_ACR1_CMD_WRITE; 352 busy = AUTRI_NX_ACR1_BUSY_WRITE; 353 break; 354 case AUTRI_DEVICE_ID_SIS_7018: 355 addr = AUTRI_SIS_ACWR; 356 cmd = AUTRI_SIS_ACWR_CMD_WRITE; 357 busy = AUTRI_SIS_ACWR_BUSY_WRITE | AUTRI_SIS_ACWR_AUDIO_BUSY; 358 break; 359 case AUTRI_DEVICE_ID_ALI_M5451: 360 addr = AUTRI_ALI_ACWR; 361 cmd = AUTRI_ALI_ACWR_CMD_WRITE; 362 if (sc->sc_revision > 0x01) 363 cmd |= 0x0100; 364 busy = AUTRI_ALI_ACWR_BUSY_WRITE; 365 break; 366 default: 367 printf("%s: autri_write_codec : unknown device.\n", 368 sc->sc_dev.dv_xname); 369 return -1; 370 } 371 372 /* wait for 'Ready to Write' */ 373 for (count=0; count < 0xffff; count++) { 374 if ((TREAD4(sc, addr) & busy) == 0) 375 break; 376 DELAY(1); 377 } 378 379 if (count == 0xffff) { 380 printf("%s: Codec timeout. Busy writing AC97 codec\n", 381 sc->sc_dev.dv_xname); 382 return -1; 383 } 384 385 /* send Write Command to AC97 */ 386 TWRITE4(sc, addr, (data << 16) | (index & 0x7f) | cmd); 387 388 return 0; 389 } 390 391 void 392 autri_reset_codec(sc_) 393 void *sc_; 394 { 395 struct autri_codec_softc *codec = sc_; 396 struct autri_softc *sc = codec->sc; 397 u_int32_t reg, ready; 398 int addr, count = 200; 399 400 DPRINTF(("autri_reset_codec(codec=%p,sc=%p)\n",codec,sc)); 401 DPRINTF(("sc->sc_devid=%X\n",sc->sc_devid)); 402 403 switch (sc->sc_devid) { 404 case AUTRI_DEVICE_ID_4DWAVE_DX: 405 /* warm reset AC97 codec */ 406 autri_reg_set_4(sc, AUTRI_DX_ACR2, 1); 407 delay(100); 408 /* release reset */ 409 autri_reg_clear_4(sc, AUTRI_DX_ACR2, 1); 410 delay(100); 411 412 addr = AUTRI_DX_ACR2; 413 ready = AUTRI_DX_ACR2_CODEC_READY; 414 break; 415 case AUTRI_DEVICE_ID_4DWAVE_NX: 416 /* warm reset AC97 codec */ 417 autri_reg_set_4(sc, AUTRI_NX_ACR0, 1); 418 delay(100); 419 /* release reset */ 420 autri_reg_clear_4(sc, AUTRI_NX_ACR0, 1); 421 delay(100); 422 423 addr = AUTRI_NX_ACR0; 424 ready = AUTRI_NX_ACR0_CODEC_READY; 425 break; 426 case AUTRI_DEVICE_ID_SIS_7018: 427 /* warm reset AC97 codec */ 428 autri_reg_set_4(sc, AUTRI_SIS_SCTRL, 2); 429 delay(1000); 430 /* release reset (warm & cold) */ 431 autri_reg_clear_4(sc, AUTRI_SIS_SCTRL, 3); 432 delay(2000); 433 434 addr = AUTRI_SIS_SCTRL; 435 ready = AUTRI_SIS_SCTRL_CODEC_READY; 436 break; 437 case AUTRI_DEVICE_ID_ALI_M5451: 438 /* warm reset AC97 codec */ 439 autri_reg_set_4(sc, AUTRI_ALI_SCTRL, 1); 440 delay(100); 441 /* release reset (warm & cold) */ 442 autri_reg_clear_4(sc, AUTRI_ALI_SCTRL, 3); 443 delay(100); 444 445 addr = AUTRI_ALI_SCTRL; 446 ready = AUTRI_ALI_SCTRL_CODEC_READY; 447 break; 448 } 449 450 /* wait for 'Codec Ready' */ 451 while (count--) { 452 reg = TREAD4(sc, addr); 453 if (reg & ready) 454 break; 455 delay(1000); 456 } 457 458 if (count == 0) 459 printf("%s: Codec timeout. AC97 is not ready for operation.\n", 460 sc->sc_dev.dv_xname); 461 } 462 463 enum ac97_host_flags 464 autri_flags_codec(void *v) 465 { 466 struct autri_codec_softc *sc = v; 467 468 return (sc->flags); 469 } 470 471 /* 472 * 473 */ 474 const struct pci_matchid autri_devices[] = { 475 { PCI_VENDOR_TRIDENT, PCI_PRODUCT_TRIDENT_4DWAVE_NX }, 476 { PCI_VENDOR_SIS, PCI_PRODUCT_SIS_7018 }, 477 { PCI_VENDOR_ALI, PCI_PRODUCT_ALI_M5451 } 478 }; 479 480 int 481 autri_match(parent, match, aux) 482 struct device *parent; 483 void *match; 484 void *aux; 485 { 486 struct pci_attach_args *pa = aux; 487 488 if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_TRIDENT && 489 PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_TRIDENT_4DWAVE_DX) { 490 /* 491 * IBM makes a pcn network card and improperly 492 * sets the vendor and product ID's. Avoid matching. 493 */ 494 if (PCI_CLASS(pa->pa_class) == PCI_CLASS_NETWORK) 495 return (0); 496 else 497 return (1); 498 } 499 500 return (pci_matchbyid((struct pci_attach_args *)aux, autri_devices, 501 sizeof(autri_devices)/sizeof(autri_devices[0]))); 502 } 503 504 void 505 autri_attach(parent, self, aux) 506 struct device *parent; 507 struct device *self; 508 void *aux; 509 { 510 struct autri_softc *sc = (struct autri_softc *)self; 511 struct pci_attach_args *pa = (struct pci_attach_args *)aux; 512 pci_chipset_tag_t pc = pa->pa_pc; 513 struct autri_codec_softc *codec; 514 bus_size_t iosize; 515 pci_intr_handle_t ih; 516 char const *intrstr; 517 mixer_ctrl_t ctl; 518 int i, r; 519 520 sc->sc_devid = pa->pa_id; 521 sc->sc_class = pa->pa_class; 522 sc->sc_revision = PCI_REVISION(pa->pa_class); 523 524 /* map register to memory */ 525 if (pci_mapreg_map(pa, AUTRI_PCI_MEMORY_BASE, 526 PCI_MAPREG_TYPE_MEM, 0, &sc->memt, &sc->memh, NULL, &iosize, 0)) { 527 printf("%s: can't map mem space\n", sc->sc_dev.dv_xname); 528 return; 529 } 530 531 /* map and establish the interrupt */ 532 if (pci_intr_map(pa, &ih)) { 533 printf("%s: couldn't map interrupt\n", sc->sc_dev.dv_xname); 534 bus_space_unmap(sc->memt, sc->memh, iosize); 535 return; 536 } 537 intrstr = pci_intr_string(pc, ih); 538 sc->sc_ih = pci_intr_establish(pc, ih, IPL_AUDIO, autri_intr, sc, 539 sc->sc_dev.dv_xname); 540 if (sc->sc_ih == NULL) { 541 printf("%s: couldn't establish interrupt", 542 sc->sc_dev.dv_xname); 543 if (intrstr != NULL) 544 printf(" at %s", intrstr); 545 printf("\n"); 546 bus_space_unmap(sc->memt, sc->memh, iosize); 547 return; 548 } 549 printf(": %s\n", intrstr); 550 551 sc->sc_dmatag = pa->pa_dmat; 552 sc->sc_pc = pc; 553 sc->sc_pt = pa->pa_tag; 554 555 /* initialize the device */ 556 autri_init(sc); 557 558 /* attach AC97 codec */ 559 codec = &sc->sc_codec; 560 memcpy(&codec->sc_dev, &sc->sc_dev, sizeof(codec->sc_dev)); 561 codec->sc = sc; 562 563 codec->host_if.arg = codec; 564 codec->host_if.attach = autri_attach_codec; 565 codec->host_if.reset = autri_reset_codec; 566 codec->host_if.read = autri_read_codec; 567 codec->host_if.write = autri_write_codec; 568 codec->host_if.flags = autri_flags_codec; 569 codec->flags = AC97_HOST_DONT_READ | AC97_HOST_SWAPPED_CHANNELS; 570 if (sc->sc_dev.dv_cfdata->cf_flags & 0x0001) 571 codec->flags &= ~AC97_HOST_SWAPPED_CHANNELS; 572 573 if ((r = ac97_attach(&codec->host_if)) != 0) { 574 printf("%s: can't attach codec (error 0x%X)\n", 575 sc->sc_dev.dv_xname, r); 576 pci_intr_disestablish(pc, sc->sc_ih); 577 bus_space_unmap(sc->memt, sc->memh, iosize); 578 return; 579 } 580 581 /* disable mutes */ 582 for (i = 0; i < 4; i++) { 583 static struct { 584 char *class, *device; 585 } d[] = { 586 { AudioCoutputs, AudioNmaster}, 587 { AudioCinputs, AudioNdac}, 588 { AudioCinputs, AudioNcd}, 589 { AudioCrecord, AudioNvolume}, 590 }; 591 592 ctl.type = AUDIO_MIXER_ENUM; 593 ctl.un.ord = 0; 594 595 #if 0 596 ctl.dev = sc->sc_codec.codec_if->vtbl->get_portnum_by_name(sc->sc_codec.codec_if, 597 d[i].class, d[i].device, AudioNmute); 598 #endif 599 ctl.dev = autri_get_portnum_by_name(sc,d[i].class, 600 d[i].device, AudioNmute); 601 autri_mixer_set_port(sc, &ctl); 602 } 603 604 /* set a reasonable default volume */ 605 ctl.type = AUDIO_MIXER_VALUE; 606 ctl.un.value.num_channels = 2; 607 ctl.un.value.level[AUDIO_MIXER_LEVEL_LEFT] = 608 ctl.un.value.level[AUDIO_MIXER_LEVEL_RIGHT] = 127; 609 610 ctl.dev = autri_get_portnum_by_name(sc,AudioCoutputs,AudioNmaster,NULL); 611 autri_mixer_set_port(sc, &ctl); 612 613 audio_attach_mi(&autri_hw_if, sc, &sc->sc_dev); 614 615 #if NMIDI > 0 616 midi_attach_mi(&autri_midi_hw_if, sc, &sc->sc_dev); 617 #endif 618 619 sc->sc_old_power = PWR_RESUME; 620 powerhook_establish(autri_powerhook, sc); 621 } 622 623 void 624 autri_powerhook(int why,void *addr) 625 { 626 struct autri_softc *sc = addr; 627 628 if (why == PWR_RESUME && sc->sc_old_power == PWR_SUSPEND) { 629 DPRINTF(("PWR_RESUME\n")); 630 autri_init(sc); 631 /*autri_reset_codec(&sc->sc_codec);*/ 632 (sc->sc_codec.codec_if->vtbl->restore_ports)(sc->sc_codec.codec_if); 633 } 634 sc->sc_old_power = why; 635 } 636 637 int 638 autri_init(sc_) 639 void *sc_; 640 { 641 struct autri_softc *sc = sc_; 642 pcireg_t reg; 643 644 pci_chipset_tag_t pc = sc->sc_pc; 645 pcitag_t pt = sc->sc_pt; 646 647 DPRINTF(("in autri_init()\n")); 648 DPRINTFN(5,("pci_conf_read(0x40) : 0x%X\n",pci_conf_read(pc,pt,0x40))); 649 DPRINTFN(5,("pci_conf_read(0x44) : 0x%X\n",pci_conf_read(pc,pt,0x44))); 650 651 switch (sc->sc_devid) { 652 case AUTRI_DEVICE_ID_4DWAVE_DX: 653 /* disable Legacy Control */ 654 pci_conf_write(pc, pt, AUTRI_PCI_DDMA_CFG,0); 655 reg = pci_conf_read(pc, pt, AUTRI_PCI_LEGACY_IOBASE); 656 pci_conf_write(pc, pt, AUTRI_PCI_LEGACY_IOBASE, reg & 0xffff0000); 657 delay(100); 658 /* audio engine reset */ 659 reg = pci_conf_read(pc, pt, AUTRI_PCI_LEGACY_IOBASE); 660 pci_conf_write(pc, pt, AUTRI_PCI_LEGACY_IOBASE, reg | 0x00040000); 661 delay(100); 662 /* release reset */ 663 reg = pci_conf_read(pc, pt, AUTRI_PCI_LEGACY_IOBASE); 664 pci_conf_write(pc, pt, AUTRI_PCI_LEGACY_IOBASE, reg & ~0x00040000); 665 delay(100); 666 /* DAC on */ 667 autri_reg_set_4(sc,AUTRI_DX_ACR2,0x02); 668 break; 669 case AUTRI_DEVICE_ID_4DWAVE_NX: 670 /* disable Legacy Control */ 671 pci_conf_write(pc, pt, AUTRI_PCI_DDMA_CFG,0); 672 reg = pci_conf_read(pc, pt, AUTRI_PCI_LEGACY_IOBASE); 673 pci_conf_write(pc, pt, AUTRI_PCI_LEGACY_IOBASE, reg & 0xffff0000); 674 delay(100); 675 /* audio engine reset */ 676 reg = pci_conf_read(pc, pt, AUTRI_PCI_LEGACY_IOBASE); 677 pci_conf_write(pc, pt, AUTRI_PCI_LEGACY_IOBASE, reg | 0x00010000); 678 delay(100); 679 /* release reset */ 680 reg = pci_conf_read(pc, pt, AUTRI_PCI_LEGACY_IOBASE); 681 pci_conf_write(pc, pt, AUTRI_PCI_LEGACY_IOBASE, reg & ~0x00010000); 682 delay(100); 683 /* DAC on */ 684 autri_reg_set_4(sc,AUTRI_NX_ACR0,0x02); 685 break; 686 case AUTRI_DEVICE_ID_SIS_7018: 687 /* disable Legacy Control */ 688 pci_conf_write(pc, pt, AUTRI_PCI_DDMA_CFG,0); 689 reg = pci_conf_read(pc, pt, AUTRI_PCI_LEGACY_IOBASE); 690 pci_conf_write(pc, pt, AUTRI_PCI_LEGACY_IOBASE, reg & 0xffff0000); 691 delay(100); 692 /* reset Digital Controller */ 693 reg = pci_conf_read(pc, pt, AUTRI_PCI_LEGACY_IOBASE); 694 pci_conf_write(pc, pt, AUTRI_PCI_LEGACY_IOBASE, reg | 0x000c0000); 695 delay(100); 696 /* release reset */ 697 reg = pci_conf_read(pc, pt, AUTRI_PCI_LEGACY_IOBASE); 698 pci_conf_write(pc, pt, AUTRI_PCI_LEGACY_IOBASE, reg & ~0x00040000); 699 delay(100); 700 /* disable AC97 GPIO interrupt */ 701 TWRITE1(sc, AUTRI_SIS_ACGPIO, 0); 702 /* enable 64 channel mode */ 703 autri_reg_set_4(sc, AUTRI_LFO_GC_CIR, BANK_B_EN); 704 break; 705 case AUTRI_DEVICE_ID_ALI_M5451: 706 /* disable Legacy Control */ 707 pci_conf_write(pc, pt, AUTRI_PCI_DDMA_CFG,0); 708 reg = pci_conf_read(pc, pt, AUTRI_PCI_LEGACY_IOBASE); 709 pci_conf_write(pc, pt, AUTRI_PCI_LEGACY_IOBASE, reg & 0xffff0000); 710 delay(100); 711 /* reset Digital Controller */ 712 reg = pci_conf_read(pc, pt, AUTRI_PCI_LEGACY_IOBASE); 713 pci_conf_write(pc, pt, AUTRI_PCI_LEGACY_IOBASE, reg | 0x000c0000); 714 delay(100); 715 /* release reset */ 716 reg = pci_conf_read(pc, pt, AUTRI_PCI_LEGACY_IOBASE); 717 pci_conf_write(pc, pt, AUTRI_PCI_LEGACY_IOBASE, reg & ~0x00040000); 718 delay(100); 719 /* enable PCM input */ 720 autri_reg_set_4(sc, AUTRI_ALI_GCONTROL, AUTRI_ALI_GCONTROL_PCM_IN); 721 break; 722 } 723 724 if (sc->sc_devid == AUTRI_DEVICE_ID_ALI_M5451) { 725 sc->sc_play.ch = 0; 726 sc->sc_play.ch_intr = 1; 727 sc->sc_rec.ch = 31; 728 sc->sc_rec.ch_intr = 2; 729 } else { 730 sc->sc_play.ch = 0x20; 731 sc->sc_play.ch_intr = 0x21; 732 sc->sc_rec.ch = 0x22; 733 sc->sc_rec.ch_intr = 0x23; 734 } 735 736 /* clear channel status */ 737 TWRITE4(sc, AUTRI_STOP_A, 0xffffffff); 738 TWRITE4(sc, AUTRI_STOP_B, 0xffffffff); 739 740 /* disable channel interrupt */ 741 TWRITE4(sc, AUTRI_AINTEN_A, 0); 742 TWRITE4(sc, AUTRI_AINTEN_B, 0); 743 744 #if 0 745 /* TLB */ 746 if (sc->sc_devid == AUTRI_DEVICE_ID_4DWAVE_NX) { 747 TWRITE4(sc,AUTRI_NX_TLBC,0); 748 } 749 #endif 750 751 autri_enable_loop_interrupt(sc); 752 753 DPRINTF(("out autri_init()\n")); 754 return 0; 755 } 756 757 void 758 autri_enable_loop_interrupt(sc_) 759 void *sc_; 760 { 761 struct autri_softc *sc = sc_; 762 u_int32_t reg; 763 764 /*reg = (ENDLP_IE | MIDLP_IE);*/ 765 reg = ENDLP_IE; 766 #if 0 767 if (sc->sc_devid == AUTRI_DEVICE_ID_SIS_7018) 768 reg |= BANK_B_EN; 769 #endif 770 autri_reg_set_4(sc,AUTRI_LFO_GC_CIR,reg); 771 } 772 773 #if 0 774 void 775 autri_disable_loop_interrupt(sc_) 776 void *sc_; 777 { 778 struct autri_softc *sc = sc_; 779 u_int32_t reg; 780 781 reg = (ENDLP_IE | MIDLP_IE); 782 autri_reg_clear_4(sc,AUTRI_LFO_GC_CIR,reg); 783 } 784 #endif 785 786 int 787 autri_intr(p) 788 void *p; 789 { 790 struct autri_softc *sc = p; 791 u_int32_t intsrc; 792 u_int32_t mask, active[2]; 793 int ch, endch; 794 /* 795 u_int32_t reg; 796 u_int32_t cso,eso; 797 */ 798 799 intsrc = TREAD4(sc,AUTRI_MISCINT); 800 if ((intsrc & (ADDRESS_IRQ|MPU401_IRQ)) == 0) 801 return 0; 802 803 if (intsrc & ADDRESS_IRQ) { 804 805 active[0] = TREAD4(sc,AUTRI_AIN_A); 806 active[1] = TREAD4(sc,AUTRI_AIN_B); 807 808 if (sc->sc_devid == AUTRI_DEVICE_ID_ALI_M5451) { 809 endch = 32; 810 } else { 811 endch = 64; 812 } 813 814 for (ch=0; ch<endch; ch++) { 815 mask = 1 << (ch & 0x1f); 816 if (active[(ch & 0x20) ? 1 : 0] & mask) { 817 818 /* clear interrupt */ 819 TWRITE4(sc, (ch & 0x20) ? AUTRI_AIN_B : AUTRI_AIN_A, mask); 820 /* disable interrupt */ 821 autri_reg_clear_4(sc,(ch & 0x20) ? AUTRI_AINTEN_B : AUTRI_AINTEN_A, mask); 822 #if 0 823 reg = TREAD4(sc,AUTRI_LFO_GC_CIR) & ~0x0000003f; 824 TWRITE4(sc,AUTRI_LFO_GC_CIR, reg | ch); 825 826 if (sc->sc_devid == AUTRI_DEVICE_ID_4DWAVE_NX) { 827 cso = TREAD4(sc, 0xe0) & 0x00ffffff; 828 eso = TREAD4(sc, 0xe8) & 0x00ffffff; 829 } else { 830 cso = (TREAD4(sc, 0xe0) >> 16) & 0x0000ffff; 831 eso = (TREAD4(sc, 0xe8) >> 16) & 0x0000ffff; 832 } 833 /*printf("cso=%d, eso=%d\n",cso,eso);*/ 834 #endif 835 if (ch == sc->sc_play.ch_intr) { 836 if (sc->sc_play.intr) 837 sc->sc_play.intr(sc->sc_play.intr_arg); 838 } 839 840 if (ch == sc->sc_rec.ch_intr) { 841 if (sc->sc_rec.intr) 842 sc->sc_rec.intr(sc->sc_rec.intr_arg); 843 } 844 845 /* enable interrupt */ 846 autri_reg_set_4(sc, (ch & 0x20) ? AUTRI_AINTEN_B : AUTRI_AINTEN_A, mask); 847 } 848 } 849 } 850 851 if (intsrc & MPU401_IRQ) { 852 /* XXX */ 853 } 854 855 autri_reg_set_4(sc,AUTRI_MISCINT, 856 ST_TARGET_REACHED | MIXER_OVERFLOW | MIXER_UNDERFLOW); 857 858 return 1; 859 } 860 861 /* 862 * 863 */ 864 865 int 866 autri_allocmem(sc, size, align, p) 867 struct autri_softc *sc; 868 size_t size; 869 size_t align; 870 struct autri_dma *p; 871 { 872 int error; 873 874 p->size = size; 875 error = bus_dmamem_alloc(sc->sc_dmatag, p->size, align, 0, 876 p->segs, sizeof(p->segs)/sizeof(p->segs[0]), 877 &p->nsegs, BUS_DMA_NOWAIT); 878 if (error) 879 return (error); 880 881 error = bus_dmamem_map(sc->sc_dmatag, p->segs, p->nsegs, p->size, 882 &p->addr, BUS_DMA_NOWAIT|BUS_DMA_COHERENT); 883 if (error) 884 goto free; 885 886 error = bus_dmamap_create(sc->sc_dmatag, p->size, 1, p->size, 887 0, BUS_DMA_NOWAIT, &p->map); 888 if (error) 889 goto unmap; 890 891 error = bus_dmamap_load(sc->sc_dmatag, p->map, p->addr, p->size, NULL, 892 BUS_DMA_NOWAIT); 893 if (error) 894 goto destroy; 895 return (0); 896 897 destroy: 898 bus_dmamap_destroy(sc->sc_dmatag, p->map); 899 unmap: 900 bus_dmamem_unmap(sc->sc_dmatag, p->addr, p->size); 901 free: 902 bus_dmamem_free(sc->sc_dmatag, p->segs, p->nsegs); 903 return (error); 904 } 905 906 int 907 autri_freemem(sc, p) 908 struct autri_softc *sc; 909 struct autri_dma *p; 910 { 911 bus_dmamap_unload(sc->sc_dmatag, p->map); 912 bus_dmamap_destroy(sc->sc_dmatag, p->map); 913 bus_dmamem_unmap(sc->sc_dmatag, p->addr, p->size); 914 bus_dmamem_free(sc->sc_dmatag, p->segs, p->nsegs); 915 return 0; 916 } 917 918 int 919 autri_open(addr, flags) 920 void *addr; 921 int flags; 922 { 923 DPRINTF(("autri_open()\n")); 924 DPRINTFN(5,("MISCINT : 0x%08X\n", 925 TREAD4((struct autri_softc *)addr, AUTRI_MISCINT))); 926 DPRINTFN(5,("LFO_GC_CIR : 0x%08X\n", 927 TREAD4((struct autri_softc *)addr, AUTRI_LFO_GC_CIR))); 928 return 0; 929 } 930 931 void 932 autri_close(addr) 933 void *addr; 934 { 935 DPRINTF(("autri_close()\n")); 936 } 937 938 int 939 autri_query_encoding(addr, fp) 940 void *addr; 941 struct audio_encoding *fp; 942 { 943 switch (fp->index) { 944 case 0: 945 strlcpy(fp->name, AudioEulinear, sizeof fp->name); 946 fp->encoding = AUDIO_ENCODING_ULINEAR; 947 fp->precision = 8; 948 fp->flags = 0; 949 break; 950 case 1: 951 strlcpy(fp->name, AudioEmulaw, sizeof fp->name); 952 fp->encoding = AUDIO_ENCODING_ULAW; 953 fp->precision = 8; 954 fp->flags = AUDIO_ENCODINGFLAG_EMULATED; 955 break; 956 case 2: 957 strlcpy(fp->name, AudioEalaw, sizeof fp->name); 958 fp->encoding = AUDIO_ENCODING_ALAW; 959 fp->precision = 8; 960 fp->flags = AUDIO_ENCODINGFLAG_EMULATED; 961 break; 962 case 3: 963 strlcpy(fp->name, AudioEslinear, sizeof fp->name); 964 fp->encoding = AUDIO_ENCODING_SLINEAR; 965 fp->precision = 8; 966 fp->flags = 0; 967 break; 968 case 4: 969 strlcpy(fp->name, AudioEslinear_le, sizeof fp->name); 970 fp->encoding = AUDIO_ENCODING_SLINEAR_LE; 971 fp->precision = 16; 972 fp->flags = 0; 973 break; 974 case 5: 975 strlcpy(fp->name, AudioEulinear_le, sizeof fp->name); 976 fp->encoding = AUDIO_ENCODING_ULINEAR_LE; 977 fp->precision = 16; 978 fp->flags = 0; 979 break; 980 case 6: 981 strlcpy(fp->name, AudioEslinear_be, sizeof fp->name); 982 fp->encoding = AUDIO_ENCODING_SLINEAR_BE; 983 fp->precision = 16; 984 fp->flags = AUDIO_ENCODINGFLAG_EMULATED; 985 break; 986 case 7: 987 strlcpy(fp->name, AudioEulinear_be, sizeof fp->name); 988 fp->encoding = AUDIO_ENCODING_ULINEAR_BE; 989 fp->precision = 16; 990 fp->flags = AUDIO_ENCODINGFLAG_EMULATED; 991 break; 992 default: 993 return (EINVAL); 994 } 995 996 return 0; 997 } 998 999 int 1000 autri_set_params(addr, setmode, usemode, play, rec) 1001 void *addr; 1002 int setmode, usemode; 1003 struct audio_params *play, *rec; 1004 { 1005 struct audio_params *p; 1006 int mode; 1007 1008 for (mode = AUMODE_RECORD; mode != -1; 1009 mode = mode == AUMODE_RECORD ? AUMODE_PLAY : -1) { 1010 if ((setmode & mode) == 0) 1011 continue; 1012 1013 p = mode == AUMODE_PLAY ? play : rec; 1014 if (p->sample_rate < 4000) 1015 p->sample_rate = 4000; 1016 if (p->sample_rate > 48000) 1017 p->sample_rate = 48000; 1018 if (p->precision > 16) 1019 p->precision = 16; 1020 if (p->channels > 2) 1021 p->channels = 2; 1022 p->factor = 1; 1023 p->sw_code = 0; 1024 switch (p->encoding) { 1025 case AUDIO_ENCODING_SLINEAR_BE: 1026 case AUDIO_ENCODING_ULINEAR_BE: 1027 if (p->precision == 16) 1028 p->sw_code = swap_bytes; 1029 break; 1030 case AUDIO_ENCODING_SLINEAR_LE: 1031 case AUDIO_ENCODING_ULINEAR_LE: 1032 break; 1033 case AUDIO_ENCODING_ULAW: 1034 if (mode == AUMODE_PLAY) 1035 p->sw_code = mulaw_to_ulinear8; 1036 else 1037 p->sw_code = ulinear8_to_mulaw; 1038 1039 break; 1040 case AUDIO_ENCODING_ALAW: 1041 if (mode == AUMODE_PLAY) 1042 p->sw_code = alaw_to_ulinear8; 1043 else 1044 p->sw_code = ulinear8_to_alaw; 1045 1046 break; 1047 default: 1048 return (EINVAL); 1049 } 1050 } 1051 1052 return 0; 1053 } 1054 1055 int 1056 autri_round_blocksize(addr, block) 1057 void *addr; 1058 int block; 1059 { 1060 return ((block + 3) & -4); 1061 } 1062 1063 int 1064 autri_halt_output(addr) 1065 void *addr; 1066 { 1067 struct autri_softc *sc = addr; 1068 1069 DPRINTF(("autri_halt_output()\n")); 1070 1071 sc->sc_play.intr = NULL; 1072 autri_stopch(sc, sc->sc_play.ch, sc->sc_play.ch_intr); 1073 autri_disable_interrupt(sc, sc->sc_play.ch_intr); 1074 1075 return 0; 1076 } 1077 1078 int 1079 autri_halt_input(addr) 1080 void *addr; 1081 { 1082 struct autri_softc *sc = addr; 1083 1084 DPRINTF(("autri_halt_input()\n")); 1085 1086 sc->sc_rec.intr = NULL; 1087 autri_stopch(sc, sc->sc_rec.ch, sc->sc_rec.ch_intr); 1088 autri_disable_interrupt(sc, sc->sc_rec.ch_intr); 1089 1090 return 0; 1091 } 1092 1093 int 1094 autri_getdev(addr, retp) 1095 void *addr; 1096 struct audio_device *retp; 1097 { 1098 struct autri_softc *sc = addr; 1099 1100 DPRINTF(("autri_getdev().\n")); 1101 1102 strncpy(retp->name, "Trident 4DWAVE", sizeof(retp->name)); 1103 snprintf(retp->version, sizeof(retp->version), "0x%02x", 1104 PCI_REVISION(sc->sc_class)); 1105 1106 switch (sc->sc_devid) { 1107 case AUTRI_DEVICE_ID_4DWAVE_DX: 1108 strncpy(retp->config, "4DWAVE-DX", sizeof(retp->config)); 1109 break; 1110 case AUTRI_DEVICE_ID_4DWAVE_NX: 1111 strncpy(retp->config, "4DWAVE-NX", sizeof(retp->config)); 1112 break; 1113 case AUTRI_DEVICE_ID_SIS_7018: 1114 strncpy(retp->config, "SiS 7018", sizeof(retp->config)); 1115 break; 1116 case AUTRI_DEVICE_ID_ALI_M5451: 1117 strncpy(retp->config, "ALi M5451", sizeof(retp->config)); 1118 break; 1119 default: 1120 strncpy(retp->config, "unknown", sizeof(retp->config)); 1121 } 1122 1123 return 0; 1124 } 1125 1126 int 1127 autri_mixer_set_port(addr, cp) 1128 void *addr; 1129 mixer_ctrl_t *cp; 1130 { 1131 struct autri_softc *sc = addr; 1132 1133 return (sc->sc_codec.codec_if->vtbl->mixer_set_port( 1134 sc->sc_codec.codec_if, cp)); 1135 } 1136 1137 int 1138 autri_mixer_get_port(addr, cp) 1139 void *addr; 1140 mixer_ctrl_t *cp; 1141 { 1142 struct autri_softc *sc = addr; 1143 1144 return (sc->sc_codec.codec_if->vtbl->mixer_get_port( 1145 sc->sc_codec.codec_if, cp)); 1146 } 1147 1148 int 1149 autri_query_devinfo(addr, dip) 1150 void *addr; 1151 mixer_devinfo_t *dip; 1152 { 1153 struct autri_softc *sc = addr; 1154 1155 return (sc->sc_codec.codec_if->vtbl->query_devinfo( 1156 sc->sc_codec.codec_if, dip)); 1157 } 1158 1159 int 1160 autri_get_portnum_by_name(sc, class, device, qualifier) 1161 struct autri_softc *sc; 1162 char *class, *device, *qualifier; 1163 { 1164 return (sc->sc_codec.codec_if->vtbl->get_portnum_by_name( 1165 sc->sc_codec.codec_if, class, device, qualifier)); 1166 } 1167 1168 void * 1169 autri_malloc(addr, direction, size, pool, flags) 1170 void *addr; 1171 int direction; 1172 size_t size; 1173 int pool, flags; 1174 { 1175 struct autri_softc *sc = addr; 1176 struct autri_dma *p; 1177 int error; 1178 1179 p = malloc(sizeof(*p), pool, flags); 1180 if (!p) 1181 return NULL; 1182 1183 #if 0 1184 error = autri_allocmem(sc, size, 16, p); 1185 #endif 1186 error = autri_allocmem(sc, size, 0x10000, p); 1187 if (error) { 1188 free(p, pool); 1189 return NULL; 1190 } 1191 1192 p->next = sc->sc_dmas; 1193 sc->sc_dmas = p; 1194 return KERNADDR(p); 1195 } 1196 1197 void 1198 autri_free(addr, ptr, pool) 1199 void *addr; 1200 void *ptr; 1201 int pool; 1202 { 1203 struct autri_softc *sc = addr; 1204 struct autri_dma **pp, *p; 1205 1206 for (pp = &sc->sc_dmas; (p = *pp) != NULL; pp = &p->next) { 1207 if (KERNADDR(p) == ptr) { 1208 autri_freemem(sc, p); 1209 *pp = p->next; 1210 free(p, pool); 1211 return; 1212 } 1213 } 1214 } 1215 1216 struct autri_dma * 1217 autri_find_dma(sc, addr) 1218 struct autri_softc *sc; 1219 void *addr; 1220 { 1221 struct autri_dma *p; 1222 1223 for (p = sc->sc_dmas; p && KERNADDR(p) != addr; p = p->next) 1224 ; 1225 1226 return p; 1227 } 1228 1229 paddr_t 1230 autri_mappage(addr, mem, off, prot) 1231 void *addr; 1232 void *mem; 1233 off_t off; 1234 int prot; 1235 { 1236 struct autri_softc *sc = addr; 1237 struct autri_dma *p; 1238 1239 if (off < 0) 1240 return (-1); 1241 1242 p = autri_find_dma(sc, mem); 1243 if (!p) 1244 return (-1); 1245 1246 return (bus_dmamem_mmap(sc->sc_dmatag, p->segs, p->nsegs, 1247 off, prot, BUS_DMA_WAITOK)); 1248 } 1249 1250 int 1251 autri_get_props(addr) 1252 void *addr; 1253 { 1254 return (AUDIO_PROP_MMAP | AUDIO_PROP_INDEPENDENT | 1255 AUDIO_PROP_FULLDUPLEX); 1256 } 1257 1258 void 1259 autri_setup_channel(sc, mode, param) 1260 struct autri_softc *sc; 1261 int mode; 1262 struct audio_params *param; 1263 { 1264 int i, ch, channel; 1265 u_int32_t reg, cr[5]; 1266 u_int32_t cso, eso; 1267 u_int32_t delta, dch[2], ctrl; 1268 u_int32_t alpha_fms, fm_vol, attribute; 1269 1270 u_int32_t dmaaddr, dmalen; 1271 int factor, rvol, cvol; 1272 struct autri_chstatus *chst; 1273 1274 ctrl = AUTRI_CTRL_LOOPMODE; 1275 switch (param->encoding) { 1276 case AUDIO_ENCODING_SLINEAR_BE: 1277 case AUDIO_ENCODING_SLINEAR_LE: 1278 ctrl |= AUTRI_CTRL_SIGNED; 1279 break; 1280 } 1281 1282 factor = 0; 1283 if (param->precision == 16) { 1284 ctrl |= AUTRI_CTRL_16BIT; 1285 factor++; 1286 } 1287 1288 if (param->channels == 2) { 1289 ctrl |= AUTRI_CTRL_STEREO; 1290 factor++; 1291 } 1292 1293 delta = (u_int32_t)param->sample_rate; 1294 if (delta < 4000) 1295 delta = 4000; 1296 if (delta > 48000) 1297 delta = 48000; 1298 1299 attribute = 0; 1300 1301 dch[1] = ((delta << 12) / 48000) & 0x0000ffff; 1302 if (mode == AUMODE_PLAY) { 1303 chst = &sc->sc_play; 1304 dch[0] = ((delta << 12) / 48000) & 0x0000ffff; 1305 ctrl |= AUTRI_CTRL_WAVEVOL; 1306 /* 1307 if (sc->sc_devid == AUTRI_DEVICE_ID_ALI_M5451) 1308 ctrl |= 0x80000000; 1309 */ 1310 } else { 1311 chst = &sc->sc_rec; 1312 dch[0] = ((48000 << 12) / delta) & 0x0000ffff; 1313 if (sc->sc_devid == AUTRI_DEVICE_ID_SIS_7018) { 1314 ctrl |= AUTRI_CTRL_MUTE_SIS; 1315 attribute = AUTRI_ATTR_PCMREC_SIS; 1316 if (delta != 48000) 1317 attribute |= AUTRI_ATTR_ENASRC_SIS; 1318 } 1319 ctrl |= AUTRI_CTRL_MUTE; 1320 } 1321 1322 dmaaddr = DMAADDR(chst->dma); 1323 cso = alpha_fms = 0; 1324 rvol = cvol = 0x7f; 1325 fm_vol = 0x0 | ((rvol & 0x7f) << 7) | (cvol & 0x7f); 1326 1327 for (ch=0; ch<2; ch++) { 1328 1329 if (ch == 0) 1330 dmalen = (chst->length >> factor); 1331 else { 1332 /* channel for interrupt */ 1333 dmalen = (chst->blksize >> factor); 1334 if (sc->sc_devid == AUTRI_DEVICE_ID_SIS_7018) 1335 ctrl |= AUTRI_CTRL_MUTE_SIS; 1336 else 1337 ctrl |= AUTRI_CTRL_MUTE; 1338 attribute = 0; 1339 } 1340 1341 eso = dmalen - 1; 1342 1343 switch (sc->sc_devid) { 1344 case AUTRI_DEVICE_ID_4DWAVE_DX: 1345 cr[0] = (cso << 16) | (alpha_fms & 0x0000ffff); 1346 cr[1] = dmaaddr; 1347 cr[2] = (eso << 16) | (dch[ch] & 0x0000ffff); 1348 cr[3] = fm_vol; 1349 cr[4] = ctrl; 1350 break; 1351 case AUTRI_DEVICE_ID_4DWAVE_NX: 1352 cr[0] = (dch[ch] << 24) | (cso & 0x00ffffff); 1353 cr[1] = dmaaddr; 1354 cr[2] = ((dch[ch] << 16) & 0xff000000) | (eso & 0x00ffffff); 1355 cr[3] = (alpha_fms << 16) | (fm_vol & 0x0000ffff); 1356 cr[4] = ctrl; 1357 break; 1358 case AUTRI_DEVICE_ID_SIS_7018: 1359 cr[0] = (cso << 16) | (alpha_fms & 0x0000ffff); 1360 cr[1] = dmaaddr; 1361 cr[2] = (eso << 16) | (dch[ch] & 0x0000ffff); 1362 cr[3] = attribute; 1363 cr[4] = ctrl; 1364 break; 1365 case AUTRI_DEVICE_ID_ALI_M5451: 1366 cr[0] = (cso << 16) | (alpha_fms & 0x0000ffff); 1367 cr[1] = dmaaddr; 1368 cr[2] = (eso << 16) | (dch[ch] & 0x0000ffff); 1369 cr[3] = 0; 1370 cr[4] = ctrl; 1371 break; 1372 } 1373 1374 /* write channel data */ 1375 channel = (ch == 0) ? chst->ch : chst->ch_intr; 1376 1377 reg = TREAD4(sc,AUTRI_LFO_GC_CIR) & ~0x0000003f; 1378 TWRITE4(sc,AUTRI_LFO_GC_CIR, reg | channel); 1379 1380 for (i=0; i<5; i++) { 1381 TWRITE4(sc, AUTRI_ARAM_CR + i*sizeof(cr[0]), cr[i]); 1382 DPRINTFN(5,("cr[%d] : 0x%08X\n", i, cr[i])); 1383 } 1384 1385 /* Bank A only */ 1386 if (channel < 0x20) { 1387 TWRITE4(sc, AUTRI_EBUF1, AUTRI_EMOD_STILL); 1388 TWRITE4(sc, AUTRI_EBUF2, AUTRI_EMOD_STILL); 1389 } 1390 } 1391 1392 } 1393 1394 int 1395 autri_trigger_output(addr, start, end, blksize, intr, arg, param) 1396 void *addr; 1397 void *start, *end; 1398 int blksize; 1399 void (*intr)(void *); 1400 void *arg; 1401 struct audio_params *param; 1402 { 1403 struct autri_softc *sc = addr; 1404 struct autri_dma *p; 1405 1406 DPRINTFN(5,("autri_trigger_output: sc=%p start=%p end=%p " 1407 "blksize=%d intr=%p(%p)\n", addr, start, end, blksize, intr, arg)); 1408 1409 sc->sc_play.intr = intr; 1410 sc->sc_play.intr_arg = arg; 1411 sc->sc_play.offset = 0; 1412 sc->sc_play.blksize = blksize; 1413 sc->sc_play.length = (char *)end - (char *)start; 1414 1415 p = autri_find_dma(sc, start); 1416 if (!p) { 1417 printf("autri_trigger_output: bad addr %p\n", start); 1418 return (EINVAL); 1419 } 1420 1421 sc->sc_play.dma = p; 1422 1423 /* */ 1424 autri_setup_channel(sc, AUMODE_PLAY, param); 1425 1426 /* volume set to no attenuation */ 1427 TWRITE4(sc, AUTRI_MUSICVOL_WAVEVOL, 0); 1428 1429 /* enable interrupt */ 1430 autri_enable_interrupt(sc, sc->sc_play.ch_intr); 1431 1432 /* start channel */ 1433 autri_startch(sc, sc->sc_play.ch, sc->sc_play.ch_intr); 1434 1435 return 0; 1436 } 1437 1438 int 1439 autri_trigger_input(addr, start, end, blksize, intr, arg, param) 1440 void *addr; 1441 void *start, *end; 1442 int blksize; 1443 void (*intr)(void *); 1444 void *arg; 1445 struct audio_params *param; 1446 { 1447 struct autri_softc *sc = addr; 1448 struct autri_dma *p; 1449 1450 DPRINTFN(5,("autri_trigger_input: sc=%p start=%p end=%p " 1451 "blksize=%d intr=%p(%p)\n", addr, start, end, blksize, intr, arg)); 1452 1453 sc->sc_rec.intr = intr; 1454 sc->sc_rec.intr_arg = arg; 1455 sc->sc_rec.offset = 0; 1456 sc->sc_rec.blksize = blksize; 1457 sc->sc_rec.length = (char *)end - (char *)start; 1458 1459 /* */ 1460 p = autri_find_dma(sc, start); 1461 if (!p) { 1462 printf("autri_trigger_input: bad addr %p\n", start); 1463 return (EINVAL); 1464 } 1465 1466 sc->sc_rec.dma = p; 1467 1468 /* */ 1469 if (sc->sc_devid == AUTRI_DEVICE_ID_4DWAVE_NX) { 1470 autri_reg_set_4(sc, AUTRI_NX_ACR0, AUTRI_NX_ACR0_PSB_CAPTURE); 1471 TWRITE1(sc, AUTRI_NX_RCI3, AUTRI_NX_RCI3_ENABLE | sc->sc_rec.ch); 1472 } 1473 1474 #if 0 1475 /* 4DWAVE only allows capturing at a 48KHz rate */ 1476 if (sc->sc_devid == AUTRI_DEVICE_ID_4DWAVE_DX || 1477 sc->sc_devid == AUTRI_DEVICE_ID_4DWAVE_NX) 1478 param->sample_rate = 48000; 1479 #endif 1480 1481 autri_setup_channel(sc, AUMODE_RECORD, param); 1482 1483 /* enable interrupt */ 1484 autri_enable_interrupt(sc, sc->sc_rec.ch_intr); 1485 1486 /* start channel */ 1487 autri_startch(sc, sc->sc_rec.ch, sc->sc_rec.ch_intr); 1488 1489 return 0; 1490 } 1491 1492 #if 0 1493 int 1494 autri_halt(sc) 1495 struct autri_softc *sc; 1496 { 1497 DPRINTF(("autri_halt().\n")); 1498 /*autri_stopch(sc);*/ 1499 autri_disable_interrupt(sc, sc->sc_play.channel); 1500 autri_disable_interrupt(sc, sc->sc_rec.channel); 1501 return 0; 1502 } 1503 #endif 1504 1505 void 1506 autri_enable_interrupt(sc, ch) 1507 struct autri_softc *sc; 1508 int ch; 1509 { 1510 int reg; 1511 1512 reg = (ch & 0x20) ? AUTRI_AINTEN_B : AUTRI_AINTEN_A; 1513 ch &= 0x1f; 1514 1515 autri_reg_set_4(sc, reg, 1 << ch); 1516 } 1517 1518 void 1519 autri_disable_interrupt(sc, ch) 1520 struct autri_softc *sc; 1521 int ch; 1522 { 1523 int reg; 1524 1525 reg = (ch & 0x20) ? AUTRI_AINTEN_B : AUTRI_AINTEN_A; 1526 ch &= 0x1f; 1527 1528 autri_reg_clear_4(sc, reg, 1 << ch); 1529 } 1530 1531 void 1532 autri_startch(sc, ch, ch_intr) 1533 struct autri_softc *sc; 1534 int ch, ch_intr; 1535 { 1536 int reg; 1537 u_int32_t chmask; 1538 1539 reg = (ch & 0x20) ? AUTRI_START_B : AUTRI_START_A; 1540 ch &= 0x1f; 1541 chmask = (1 << ch) | (1 << ch_intr); 1542 1543 autri_reg_set_4(sc, reg, chmask); 1544 } 1545 1546 void 1547 autri_stopch(sc, ch, ch_intr) 1548 struct autri_softc *sc; 1549 int ch, ch_intr; 1550 { 1551 int reg; 1552 u_int32_t chmask; 1553 1554 reg = (ch & 0x20) ? AUTRI_STOP_B : AUTRI_STOP_A; 1555 ch &= 0x1f; 1556 chmask = (1 << ch) | (1 << ch_intr); 1557 1558 autri_reg_set_4(sc, reg, chmask); 1559 } 1560 1561 #if NMIDI > 0 1562 int 1563 autri_midi_open(void *addr, int flags, 1564 void (*iintr)(void *, int), 1565 void (*ointr)(void *), 1566 void *arg) 1567 { 1568 struct autri_softc *sc = addr; 1569 1570 DPRINTF(("autri_midi_open()\n")); 1571 1572 DPRINTFN(5,("MPUR1 : 0x%02X\n",TREAD1(sc,AUTRI_MPUR1))); 1573 DPRINTFN(5,("MPUR2 : 0x%02X\n",TREAD1(sc,AUTRI_MPUR2))); 1574 1575 sc->sc_iintr = iintr; 1576 sc->sc_ointr = ointr; 1577 sc->sc_arg = arg; 1578 1579 if (flags & FREAD) 1580 autri_reg_clear_1(sc, AUTRI_MPUR2, AUTRI_MIDIIN_ENABLE_INTR); 1581 1582 if (flags & FWRITE) 1583 autri_reg_set_1(sc, AUTRI_MPUR2, AUTRI_MIDIOUT_CONNECT); 1584 1585 return (0); 1586 } 1587 1588 void 1589 autri_midi_close(void *addr) 1590 { 1591 struct autri_softc *sc = addr; 1592 1593 DPRINTF(("autri_midi_close()\n")); 1594 1595 tsleep(sc, PWAIT, "autri", hz/10); /* give uart a chance to drain */ 1596 1597 sc->sc_iintr = NULL; 1598 sc->sc_ointr = NULL; 1599 } 1600 1601 int 1602 autri_midi_output(void *addr, int d) 1603 { 1604 struct autri_softc *sc = addr; 1605 int x; 1606 1607 for (x = 0; x != MIDI_BUSY_WAIT; x++) { 1608 if ((TREAD1(sc, AUTRI_MPUR1) & AUTRI_MIDIOUT_READY) == 0) { 1609 TWRITE1(sc, AUTRI_MPUR0, d); 1610 return (0); 1611 } 1612 delay(MIDI_BUSY_DELAY); 1613 } 1614 return (EIO); 1615 } 1616 1617 void 1618 autri_midi_getinfo(void *addr, struct midi_info *mi) 1619 { 1620 mi->name = "4DWAVE MIDI UART"; 1621 mi->props = MIDI_PROP_CAN_INPUT; 1622 } 1623 1624 #endif 1625