1 /* $OpenBSD: autri.c,v 1.4 2001/12/05 10:00:18 deraadt 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 #include <sys/proc.h> 46 47 #include <dev/pci/pcidevs.h> 48 #include <dev/pci/pcireg.h> 49 #include <dev/pci/pcivar.h> 50 51 #include <sys/audioio.h> 52 #include <dev/audio_if.h> 53 #include <dev/midi_if.h> 54 #include <dev/mulaw.h> 55 #include <dev/auconv.h> 56 #include <dev/ic/ac97.h> 57 #include <dev/ic/mpuvar.h> 58 59 #include <machine/bus.h> 60 #include <machine/intr.h> 61 62 #include <dev/pci/autrireg.h> 63 #include <dev/pci/autrivar.h> 64 65 #ifdef AUDIO_DEBUG 66 # define DPRINTF(x) if (autridebug) printf x 67 # define DPRINTFN(n,x) if (autridebug > (n)) printf x 68 int autridebug = 0; 69 #else 70 # define DPRINTF(x) 71 # define DPRINTFN(n,x) 72 #endif 73 74 int autri_match __P((struct device *, void *, void *)); 75 void autri_attach __P((struct device *, struct device *, void *)); 76 int autri_intr __P((void *)); 77 78 #define DMAADDR(p) ((p)->map->dm_segs[0].ds_addr) 79 #define KERNADDR(p) ((void *)((p)->addr)) 80 81 int autri_allocmem 82 __P((struct autri_softc *, size_t, size_t, struct autri_dma *)); 83 int autri_freemem __P((struct autri_softc *, struct autri_dma *)); 84 85 #define TWRITE1(sc, r, x) bus_space_write_1((sc)->memt, (sc)->memh, (r), (x)) 86 #define TWRITE2(sc, r, x) bus_space_write_2((sc)->memt, (sc)->memh, (r), (x)) 87 #define TWRITE4(sc, r, x) bus_space_write_4((sc)->memt, (sc)->memh, (r), (x)) 88 #define TREAD1(sc, r) bus_space_read_1((sc)->memt, (sc)->memh, (r)) 89 #define TREAD2(sc, r) bus_space_read_2((sc)->memt, (sc)->memh, (r)) 90 #define TREAD4(sc, r) bus_space_read_4((sc)->memt, (sc)->memh, (r)) 91 92 static __inline void autri_reg_set_1 __P((struct autri_softc *, int, uint8_t)); 93 static __inline void autri_reg_clear_1 94 __P((struct autri_softc *, int, uint8_t)); 95 static __inline void autri_reg_set_4 96 __P((struct autri_softc *, int, uint32_t)); 97 static __inline void autri_reg_clear_4 98 __P((struct autri_softc *, int, uint32_t)); 99 100 int autri_attach_codec __P((void *sc, struct ac97_codec_if *)); 101 int autri_read_codec __P((void *sc, u_int8_t a, u_int16_t *d)); 102 int autri_write_codec __P((void *sc, u_int8_t a, u_int16_t d)); 103 void autri_reset_codec __P((void *sc)); 104 105 void autri_powerhook(int why,void *addr); 106 int autri_init __P((void *sc)); 107 struct autri_dma *autri_find_dma __P((struct autri_softc *, void *)); 108 void autri_setup_channel __P((struct autri_softc *sc,int mode, 109 struct audio_params *param)); 110 void autri_enable_interrupt __P((struct autri_softc *sc, int ch)); 111 void autri_disable_interrupt __P((struct autri_softc *sc, int ch)); 112 void autri_startch __P((struct autri_softc *sc, int ch, int ch_intr)); 113 void autri_stopch __P((struct autri_softc *sc, int ch, int ch_intr)); 114 void autri_enable_loop_interrupt __P((void *sc)); 115 #if 0 116 void autri_disable_loop_interrupt __P((void *sc)); 117 #endif 118 119 struct cfdriver autri_cd = { 120 NULL, "autri", DV_DULL 121 }; 122 123 struct cfattach autri_ca = { 124 sizeof(struct autri_softc), autri_match, autri_attach 125 }; 126 127 int autri_open __P((void *, int)); 128 void autri_close __P((void *)); 129 int autri_query_encoding __P((void *, struct audio_encoding *)); 130 int autri_set_params 131 __P((void *, int, int, struct audio_params *, struct audio_params *)); 132 int autri_round_blocksize __P((void *, int)); 133 int autri_trigger_output 134 __P((void *, void *, void *, int, void (*)(void *), void *, 135 struct audio_params *)); 136 int autri_trigger_input 137 __P((void *, void *, void *, int, void (*)(void *), void *, 138 struct audio_params *)); 139 int autri_halt_output __P((void *)); 140 int autri_halt_input __P((void *)); 141 int autri_getdev __P((void *, struct audio_device *)); 142 int autri_mixer_set_port __P((void *, mixer_ctrl_t *)); 143 int autri_mixer_get_port __P((void *, mixer_ctrl_t *)); 144 void* autri_malloc __P((void *, int, size_t, int, int)); 145 void autri_free __P((void *, void *, int)); 146 size_t autri_round_buffersize __P((void *, int, size_t)); 147 paddr_t autri_mappage __P((void *, void *, off_t, int)); 148 int autri_get_props __P((void *)); 149 int autri_query_devinfo __P((void *addr, mixer_devinfo_t *dip)); 150 151 int autri_get_portnum_by_name 152 __P((struct autri_softc *, char *, char *, char *)); 153 154 struct audio_hw_if autri_hw_if = { 155 autri_open, 156 autri_close, 157 NULL, /* drain */ 158 autri_query_encoding, 159 autri_set_params, 160 autri_round_blocksize, 161 NULL, /* commit_settings */ 162 NULL, /* init_output */ 163 NULL, /* init_input */ 164 NULL, /* start_output */ 165 NULL, /* start_input */ 166 autri_halt_output, 167 autri_halt_input, 168 NULL, /* speaker_ctl */ 169 autri_getdev, 170 NULL, /* setfd */ 171 autri_mixer_set_port, 172 autri_mixer_get_port, 173 autri_query_devinfo, 174 NULL, 175 autri_free, 176 NULL, 177 autri_mappage, 178 autri_get_props, 179 autri_trigger_output, 180 autri_trigger_input, 181 autri_malloc, 182 autri_round_buffersize, 183 }; 184 185 #if NMIDI > 0 186 void autri_midi_close(void *); 187 void autri_midi_getinfo(void *, struct midi_info *); 188 int autri_midi_open(void *, int, void (*)(void *, int), 189 void (*)(void *), void *); 190 int autri_midi_output(void *, int); 191 192 struct midi_hw_if autri_midi_hw_if = { 193 autri_midi_open, 194 autri_midi_close, 195 autri_midi_output, 196 autri_midi_getinfo, 197 NULL, /* ioctl */ 198 }; 199 #endif 200 201 /* 202 * register set/clear bit 203 */ 204 static __inline void 205 autri_reg_set_1(sc, no, mask) 206 struct autri_softc *sc; 207 int no; 208 uint8_t mask; 209 { 210 bus_space_write_1(sc->memt, sc->memh, no, 211 (bus_space_read_1(sc->memt, sc->memh, no) | mask)); 212 } 213 214 static __inline void 215 autri_reg_clear_1(sc, no, mask) 216 struct autri_softc *sc; 217 int no; 218 uint8_t mask; 219 { 220 bus_space_write_1(sc->memt, sc->memh, no, 221 (bus_space_read_1(sc->memt, sc->memh, no) & ~mask)); 222 } 223 224 static __inline void 225 autri_reg_set_4(sc, no, mask) 226 struct autri_softc *sc; 227 int no; 228 uint32_t mask; 229 { 230 bus_space_write_4(sc->memt, sc->memh, no, 231 (bus_space_read_4(sc->memt, sc->memh, no) | mask)); 232 } 233 234 static __inline void 235 autri_reg_clear_4(sc, no, mask) 236 struct autri_softc *sc; 237 int no; 238 uint32_t mask; 239 { 240 bus_space_write_4(sc->memt, sc->memh, no, 241 (bus_space_read_4(sc->memt, sc->memh, no) & ~mask)); 242 } 243 244 /* 245 * AC97 codec 246 */ 247 int 248 autri_attach_codec(sc_, codec_if) 249 void *sc_; 250 struct ac97_codec_if *codec_if; 251 { 252 struct autri_codec_softc *sc = sc_; 253 254 DPRINTF(("autri_attach_codec()\n")); 255 256 sc->codec_if = codec_if; 257 return 0; 258 } 259 260 int 261 autri_read_codec(sc_, index, data) 262 void *sc_; 263 u_int8_t index; 264 u_int16_t *data; 265 { 266 struct autri_codec_softc *codec = sc_; 267 struct autri_softc *sc = codec->sc; 268 u_int32_t status, addr, cmd, busy; 269 u_int16_t count; 270 271 /*DPRINTF(("sc->sc->type : 0x%X",sc->sc->type));*/ 272 273 switch (sc->sc_devid) { 274 case AUTRI_DEVICE_ID_4DWAVE_DX: 275 addr = AUTRI_DX_ACR1; 276 cmd = AUTRI_DX_ACR1_CMD_READ; 277 busy = AUTRI_DX_ACR1_BUSY_READ; 278 break; 279 case AUTRI_DEVICE_ID_4DWAVE_NX: 280 addr = AUTRI_NX_ACR2; 281 cmd = AUTRI_NX_ACR2_CMD_READ; 282 busy = AUTRI_NX_ACR2_BUSY_READ | AUTRI_NX_ACR2_RECV_WAIT; 283 break; 284 case AUTRI_DEVICE_ID_SIS_7018: 285 addr = AUTRI_SIS_ACRD; 286 cmd = AUTRI_SIS_ACRD_CMD_READ; 287 busy = AUTRI_SIS_ACRD_BUSY_READ | AUTRI_SIS_ACRD_AUDIO_BUSY; 288 break; 289 case AUTRI_DEVICE_ID_ALI_M5451: 290 if (sc->sc_revision > 0x01) 291 addr = AUTRI_ALI_ACWR; 292 else 293 addr = AUTRI_ALI_ACRD; 294 cmd = AUTRI_ALI_ACRD_CMD_READ; 295 busy = AUTRI_ALI_ACRD_BUSY_READ; 296 break; 297 default: 298 printf("%s: autri_read_codec : unknown device\n", 299 sc->sc_dev.dv_xname); 300 return -1; 301 } 302 303 /* wait for 'Ready to Read' */ 304 for (count=0; count<0xffff; count++) { 305 if ((TREAD4(sc, addr) & busy) == 0) 306 break; 307 } 308 309 if (count == 0xffff) { 310 printf("%s: Codec timeout. Busy reading AC97 codec.\n", 311 sc->sc_dev.dv_xname); 312 return -1; 313 } 314 315 /* send Read Command to AC97 */ 316 TWRITE4(sc, addr, (index & 0x7f) | cmd); 317 318 /* wait for 'Returned data is avalable' */ 319 for (count=0; count<0xffff; count++) { 320 status = TREAD4(sc, addr); 321 if ((status & busy) == 0) 322 break; 323 } 324 325 if (count == 0xffff) { 326 printf("%s: Codec timeout. Busy reading AC97 codec.\n", 327 sc->sc_dev.dv_xname); 328 return -1; 329 } 330 331 *data = (status >> 16) & 0x0000ffff; 332 /*DPRINTF(("autri_read_codec(0x%X) return 0x%X\n",reg,*data));*/ 333 return 0; 334 } 335 336 int 337 autri_write_codec(sc_, index, data) 338 void *sc_; 339 u_int8_t index; 340 u_int16_t data; 341 { 342 struct autri_codec_softc *codec = sc_; 343 struct autri_softc *sc = codec->sc; 344 u_int32_t addr, cmd, busy; 345 u_int16_t count; 346 347 /*DPRINTF(("autri_write_codec(0x%X,0x%X)\n",index,data));*/ 348 349 switch (sc->sc_devid) { 350 case AUTRI_DEVICE_ID_4DWAVE_DX: 351 addr = AUTRI_DX_ACR0; 352 cmd = AUTRI_DX_ACR0_CMD_WRITE; 353 busy = AUTRI_DX_ACR0_BUSY_WRITE; 354 break; 355 case AUTRI_DEVICE_ID_4DWAVE_NX: 356 addr = AUTRI_NX_ACR1; 357 cmd = AUTRI_NX_ACR1_CMD_WRITE; 358 busy = AUTRI_NX_ACR1_BUSY_WRITE; 359 break; 360 case AUTRI_DEVICE_ID_SIS_7018: 361 addr = AUTRI_SIS_ACWR; 362 cmd = AUTRI_SIS_ACWR_CMD_WRITE; 363 busy = AUTRI_SIS_ACWR_BUSY_WRITE | AUTRI_SIS_ACWR_AUDIO_BUSY; 364 break; 365 case AUTRI_DEVICE_ID_ALI_M5451: 366 addr = AUTRI_ALI_ACWR; 367 cmd = AUTRI_ALI_ACWR_CMD_WRITE; 368 if (sc->sc_revision > 0x01) 369 cmd |= 0x0100; 370 busy = AUTRI_ALI_ACWR_BUSY_WRITE; 371 break; 372 default: 373 printf("%s: autri_write_codec : unknown device.\n", 374 sc->sc_dev.dv_xname); 375 return -1; 376 } 377 378 /* wait for 'Ready to Write' */ 379 for (count=0; count<0xffff; count++) { 380 if ((TREAD4(sc, addr) & busy) == 0) 381 break; 382 } 383 384 if (count == 0xffff) { 385 printf("%s: Codec timeout. Busy writing AC97 codec\n", 386 sc->sc_dev.dv_xname); 387 return -1; 388 } 389 390 /* send Write Command to AC97 */ 391 TWRITE4(sc, addr, (data << 16) | (index & 0x7f) | cmd); 392 393 return 0; 394 } 395 396 void 397 autri_reset_codec(sc_) 398 void *sc_; 399 { 400 struct autri_codec_softc *codec = sc_; 401 struct autri_softc *sc = codec->sc; 402 u_int32_t reg, ready; 403 int addr, count = 200; 404 405 DPRINTF(("autri_reset_codec(codec=%p,sc=%p)\n",codec,sc)); 406 DPRINTF(("sc->sc_devid=%X\n",sc->sc_devid)); 407 408 switch (sc->sc_devid) { 409 case AUTRI_DEVICE_ID_4DWAVE_DX: 410 /* warm reset AC97 codec */ 411 autri_reg_set_4(sc, AUTRI_DX_ACR2, 1); 412 delay(100); 413 /* release reset */ 414 autri_reg_clear_4(sc, AUTRI_DX_ACR2, 1); 415 delay(100); 416 417 addr = AUTRI_DX_ACR2; 418 ready = AUTRI_DX_ACR2_CODEC_READY; 419 break; 420 case AUTRI_DEVICE_ID_4DWAVE_NX: 421 /* warm reset AC97 codec */ 422 autri_reg_set_4(sc, AUTRI_NX_ACR0, 1); 423 delay(100); 424 /* release reset */ 425 autri_reg_clear_4(sc, AUTRI_NX_ACR0, 1); 426 delay(100); 427 428 addr = AUTRI_NX_ACR0; 429 ready = AUTRI_NX_ACR0_CODEC_READY; 430 break; 431 case AUTRI_DEVICE_ID_SIS_7018: 432 /* warm reset AC97 codec */ 433 autri_reg_set_4(sc, AUTRI_SIS_SCTRL, 1); 434 delay(100); 435 /* release reset (warm & cold) */ 436 autri_reg_clear_4(sc, AUTRI_SIS_SCTRL, 3); 437 delay(100); 438 439 addr = AUTRI_SIS_SCTRL; 440 ready = AUTRI_SIS_SCTRL_CODEC_READY; 441 break; 442 case AUTRI_DEVICE_ID_ALI_M5451: 443 /* warm reset AC97 codec */ 444 autri_reg_set_4(sc, AUTRI_ALI_SCTRL, 1); 445 delay(100); 446 /* release reset (warm & cold) */ 447 autri_reg_clear_4(sc, AUTRI_ALI_SCTRL, 3); 448 delay(100); 449 450 addr = AUTRI_ALI_SCTRL; 451 ready = AUTRI_ALI_SCTRL_CODEC_READY; 452 break; 453 } 454 455 /* wait for 'Codec Ready' */ 456 while (count--) { 457 reg = TREAD4(sc, addr); 458 if (reg & ready) 459 break; 460 delay(1000); 461 } 462 463 if (count == 0) 464 printf("%s: Codec timeout. AC97 is not ready for operation.\n", 465 sc->sc_dev.dv_xname); 466 } 467 468 /* 469 * 470 */ 471 472 int 473 autri_match(parent, match, aux) 474 struct device *parent; 475 void *match; 476 void *aux; 477 { 478 struct pci_attach_args *pa = (struct pci_attach_args *) aux; 479 480 switch (PCI_VENDOR(pa->pa_id)) { 481 case PCI_VENDOR_TRIDENT: 482 switch (PCI_PRODUCT(pa->pa_id)) { 483 case PCI_PRODUCT_TRIDENT_4DWAVE_DX: 484 case PCI_PRODUCT_TRIDENT_4DWAVE_NX: 485 return 1; 486 } 487 break; 488 case PCI_VENDOR_SIS: 489 switch (PCI_PRODUCT(pa->pa_id)) { 490 case PCI_PRODUCT_SIS_7018: 491 return 1; 492 } 493 break; 494 case PCI_VENDOR_ALI: 495 switch (PCI_PRODUCT(pa->pa_id)) { 496 case PCI_PRODUCT_ALI_M5451: 497 return 1; 498 } 499 break; 500 } 501 502 return 0; 503 } 504 505 void 506 autri_attach(parent, self, aux) 507 struct device *parent; 508 struct device *self; 509 void *aux; 510 { 511 struct autri_softc *sc = (struct autri_softc *)self; 512 struct pci_attach_args *pa = (struct pci_attach_args *)aux; 513 pci_chipset_tag_t pc = pa->pa_pc; 514 struct autri_codec_softc *codec; 515 bus_size_t iosize; 516 pci_intr_handle_t ih; 517 char const *intrstr; 518 mixer_ctrl_t ctl; 519 int i, r; 520 u_int32_t reg; 521 522 sc->sc_devid = pa->pa_id; 523 sc->sc_class = pa->pa_class; 524 sc->sc_revision = PCI_REVISION(pa->pa_class); 525 526 /* map register to memory */ 527 if (pci_mapreg_map(pa, AUTRI_PCI_MEMORY_BASE, 528 PCI_MAPREG_TYPE_MEM, 0, &sc->memt, &sc->memh, NULL, &iosize, 0)) { 529 printf("%s: can't map memory space\n", sc->sc_dev.dv_xname); 530 return; 531 } 532 533 /* map and establish the interrupt */ 534 if (pci_intr_map(pa, &ih)) { 535 printf("%s: couldn't map interrupt\n", sc->sc_dev.dv_xname); 536 bus_space_unmap(sc->memt, sc->memh, iosize); 537 return; 538 } 539 intrstr = pci_intr_string(pc, ih); 540 sc->sc_ih = pci_intr_establish(pc, ih, IPL_AUDIO, autri_intr, sc, 541 sc->sc_dev.dv_xname); 542 if (sc->sc_ih == NULL) { 543 printf("%s: couldn't establish interrupt", 544 sc->sc_dev.dv_xname); 545 if (intrstr != NULL) 546 printf(" at %s", intrstr); 547 printf("\n"); 548 bus_space_unmap(sc->memt, sc->memh, iosize); 549 return; 550 } 551 printf(": %s\n", intrstr); 552 553 sc->sc_dmatag = pa->pa_dmat; 554 sc->sc_pc = pc; 555 sc->sc_pt = pa->pa_tag; 556 557 /* enable the device */ 558 reg = pci_conf_read(pc, pa->pa_tag, PCI_COMMAND_STATUS_REG); 559 reg |= (PCI_COMMAND_MEM_ENABLE | PCI_COMMAND_MASTER_ENABLE); 560 pci_conf_write(pc, pa->pa_tag, PCI_COMMAND_STATUS_REG, reg); 561 562 /* initialize the device */ 563 autri_init(sc); 564 565 /* attach AC97 codec */ 566 codec = &sc->sc_codec; 567 memcpy(&codec->sc_dev, &sc->sc_dev, sizeof(codec->sc_dev)); 568 codec->sc = sc; 569 570 codec->host_if.arg = codec; 571 codec->host_if.attach = autri_attach_codec; 572 codec->host_if.reset = autri_reset_codec; 573 codec->host_if.read = autri_read_codec; 574 codec->host_if.write = autri_write_codec; 575 576 if ((r = ac97_attach(&codec->host_if)) != 0) { 577 printf("%s: can't attach codec (error 0x%X)\n", 578 sc->sc_dev.dv_xname, r); 579 pci_intr_disestablish(pc, sc->sc_ih); 580 bus_space_unmap(sc->memt, sc->memh, iosize); 581 return; 582 } 583 584 /* disable mutes */ 585 for (i = 0; i < 4; i++) { 586 static struct { 587 char *class, *device; 588 } d[] = { 589 { AudioCoutputs, AudioNmaster}, 590 { AudioCinputs, AudioNdac}, 591 { AudioCinputs, AudioNcd}, 592 { AudioCrecord, AudioNvolume}, 593 }; 594 595 ctl.type = AUDIO_MIXER_ENUM; 596 ctl.un.ord = 0; 597 598 #if 0 599 ctl.dev = sc->sc_codec.codec_if->vtbl->get_portnum_by_name(sc->sc_codec.codec_if, 600 d[i].class, d[i].device, AudioNmute); 601 #endif 602 ctl.dev = autri_get_portnum_by_name(sc,d[i].class, 603 d[i].device, AudioNmute); 604 autri_mixer_set_port(sc, &ctl); 605 } 606 607 /* set a reasonable default volume */ 608 ctl.type = AUDIO_MIXER_VALUE; 609 ctl.un.value.num_channels = 2; 610 ctl.un.value.level[AUDIO_MIXER_LEVEL_LEFT] = 611 ctl.un.value.level[AUDIO_MIXER_LEVEL_RIGHT] = 127; 612 613 ctl.dev = autri_get_portnum_by_name(sc,AudioCoutputs,AudioNmaster,NULL); 614 autri_mixer_set_port(sc, &ctl); 615 616 audio_attach_mi(&autri_hw_if, sc, &sc->sc_dev); 617 618 #if NMIDI > 0 619 midi_attach_mi(&autri_midi_hw_if, sc, &sc->sc_dev); 620 #endif 621 622 sc->sc_old_power = PWR_RESUME; 623 powerhook_establish(autri_powerhook, sc); 624 } 625 626 void 627 autri_powerhook(int why,void *addr) 628 { 629 struct autri_softc *sc = addr; 630 631 if (why == PWR_RESUME && sc->sc_old_power == PWR_SUSPEND) { 632 DPRINTF(("PWR_RESUME\n")); 633 autri_init(sc); 634 /*autri_reset_codec(&sc->sc_codec);*/ 635 (sc->sc_codec.codec_if->vtbl->restore_ports)(sc->sc_codec.codec_if); 636 } 637 sc->sc_old_power = why; 638 } 639 640 int 641 autri_init(sc_) 642 void *sc_; 643 { 644 struct autri_softc *sc = sc_; 645 u_int32_t reg; 646 647 pci_chipset_tag_t pc = sc->sc_pc; 648 pcitag_t pt = sc->sc_pt; 649 650 DPRINTF(("in autri_init()\n")); 651 DPRINTFN(5,("pci_conf_read(0x40) : 0x%X\n",pci_conf_read(pc,pt,0x40))); 652 DPRINTFN(5,("pci_conf_read(0x44) : 0x%X\n",pci_conf_read(pc,pt,0x44))); 653 654 switch (sc->sc_devid) { 655 case AUTRI_DEVICE_ID_4DWAVE_DX: 656 /* disable Legacy Control */ 657 pci_conf_write(pc, pt, AUTRI_PCI_DDMA_CFG,0); 658 reg = pci_conf_read(pc, pt, AUTRI_PCI_LEGACY_IOBASE); 659 pci_conf_write(pc, pt, AUTRI_PCI_LEGACY_IOBASE, reg & 0xffff0000); 660 delay(100); 661 /* audio engine reset */ 662 reg = pci_conf_read(pc, pt, AUTRI_PCI_LEGACY_IOBASE); 663 pci_conf_write(pc, pt, AUTRI_PCI_LEGACY_IOBASE, reg | 0x00040000); 664 delay(100); 665 /* release reset */ 666 reg = pci_conf_read(pc, pt, AUTRI_PCI_LEGACY_IOBASE); 667 pci_conf_write(pc, pt, AUTRI_PCI_LEGACY_IOBASE, reg & ~0x00040000); 668 delay(100); 669 /* DAC on */ 670 autri_reg_set_4(sc,AUTRI_DX_ACR2,0x02); 671 break; 672 case AUTRI_DEVICE_ID_4DWAVE_NX: 673 /* disable Legacy Control */ 674 pci_conf_write(pc, pt, AUTRI_PCI_DDMA_CFG,0); 675 reg = pci_conf_read(pc, pt, AUTRI_PCI_LEGACY_IOBASE); 676 pci_conf_write(pc, pt, AUTRI_PCI_LEGACY_IOBASE, reg & 0xffff0000); 677 delay(100); 678 /* audio engine reset */ 679 reg = pci_conf_read(pc, pt, AUTRI_PCI_LEGACY_IOBASE); 680 pci_conf_write(pc, pt, AUTRI_PCI_LEGACY_IOBASE, reg | 0x00010000); 681 delay(100); 682 /* release reset */ 683 reg = pci_conf_read(pc, pt, AUTRI_PCI_LEGACY_IOBASE); 684 pci_conf_write(pc, pt, AUTRI_PCI_LEGACY_IOBASE, reg & ~0x00010000); 685 delay(100); 686 /* DAC on */ 687 autri_reg_set_4(sc,AUTRI_NX_ACR0,0x02); 688 break; 689 case AUTRI_DEVICE_ID_SIS_7018: 690 /* disable Legacy Control */ 691 pci_conf_write(pc, pt, AUTRI_PCI_DDMA_CFG,0); 692 reg = pci_conf_read(pc, pt, AUTRI_PCI_LEGACY_IOBASE); 693 pci_conf_write(pc, pt, AUTRI_PCI_LEGACY_IOBASE, reg & 0xffff0000); 694 delay(100); 695 /* reset Digital Controller */ 696 reg = pci_conf_read(pc, pt, AUTRI_PCI_LEGACY_IOBASE); 697 pci_conf_write(pc, pt, AUTRI_PCI_LEGACY_IOBASE, reg | 0x000c0000); 698 delay(100); 699 /* release reset */ 700 reg = pci_conf_read(pc, pt, AUTRI_PCI_LEGACY_IOBASE); 701 pci_conf_write(pc, pt, AUTRI_PCI_LEGACY_IOBASE, reg & ~0x00040000); 702 delay(100); 703 /* disable AC97 GPIO interrupt */ 704 TWRITE1(sc, AUTRI_SIS_ACGPIO, 0); 705 /* enable 64 channel mode */ 706 autri_reg_set_4(sc, AUTRI_LFO_GC_CIR, BANK_B_EN); 707 break; 708 case AUTRI_DEVICE_ID_ALI_M5451: 709 /* disable Legacy Control */ 710 pci_conf_write(pc, pt, AUTRI_PCI_DDMA_CFG,0); 711 reg = pci_conf_read(pc, pt, AUTRI_PCI_LEGACY_IOBASE); 712 pci_conf_write(pc, pt, AUTRI_PCI_LEGACY_IOBASE, reg & 0xffff0000); 713 delay(100); 714 /* reset Digital Controller */ 715 reg = pci_conf_read(pc, pt, AUTRI_PCI_LEGACY_IOBASE); 716 pci_conf_write(pc, pt, AUTRI_PCI_LEGACY_IOBASE, reg | 0x000c0000); 717 delay(100); 718 /* release reset */ 719 reg = pci_conf_read(pc, pt, AUTRI_PCI_LEGACY_IOBASE); 720 pci_conf_write(pc, pt, AUTRI_PCI_LEGACY_IOBASE, reg & ~0x00040000); 721 delay(100); 722 /* enable PCM input */ 723 autri_reg_set_4(sc, AUTRI_ALI_GCONTROL, AUTRI_ALI_GCONTROL_PCM_IN); 724 break; 725 } 726 727 if (sc->sc_devid == AUTRI_DEVICE_ID_ALI_M5451) { 728 sc->sc_play.ch = 0; 729 sc->sc_play.ch_intr = 1; 730 sc->sc_rec.ch = 31; 731 sc->sc_rec.ch_intr = 2; 732 } else { 733 sc->sc_play.ch = 0x20; 734 sc->sc_play.ch_intr = 0x21; 735 sc->sc_rec.ch = 0x22; 736 sc->sc_rec.ch_intr = 0x23; 737 } 738 739 /* clear channel status */ 740 TWRITE4(sc, AUTRI_STOP_A, 0xffffffff); 741 TWRITE4(sc, AUTRI_STOP_B, 0xffffffff); 742 743 /* disable channel interrupt */ 744 TWRITE4(sc, AUTRI_AINTEN_A, 0); 745 TWRITE4(sc, AUTRI_AINTEN_B, 0); 746 747 #if 0 748 /* TLB */ 749 if (sc->sc_devid == AUTRI_DEVICE_ID_4DWAVE_NX) { 750 TWRITE4(sc,AUTRI_NX_TLBC,0); 751 } 752 #endif 753 754 autri_enable_loop_interrupt(sc); 755 756 DPRINTF(("out autri_init()\n")); 757 return 0; 758 } 759 760 void 761 autri_enable_loop_interrupt(sc_) 762 void *sc_; 763 { 764 struct autri_softc *sc = sc_; 765 u_int32_t reg; 766 767 /*reg = (ENDLP_IE | MIDLP_IE);*/ 768 reg = ENDLP_IE; 769 #if 0 770 if (sc->sc_devid == AUTRI_DEVICE_ID_SIS_7018) 771 reg |= BANK_B_EN; 772 #endif 773 autri_reg_set_4(sc,AUTRI_LFO_GC_CIR,reg); 774 } 775 776 #if 0 777 void 778 autri_disable_loop_interrupt(sc_) 779 void *sc_; 780 { 781 struct autri_softc *sc = sc_; 782 u_int32_t reg; 783 784 reg = (ENDLP_IE | MIDLP_IE); 785 autri_reg_clear_4(sc,AUTRI_LFO_GC_CIR,reg); 786 } 787 #endif 788 789 int 790 autri_intr(p) 791 void *p; 792 { 793 struct autri_softc *sc = p; 794 u_int32_t intsrc; 795 u_int32_t mask, active[2]; 796 int ch, endch; 797 /* 798 u_int32_t reg; 799 u_int32_t cso,eso; 800 */ 801 802 intsrc = TREAD4(sc,AUTRI_MISCINT); 803 if ((intsrc & (ADDRESS_IRQ|MPU401_IRQ)) == 0) 804 return 0; 805 806 if (intsrc & ADDRESS_IRQ) { 807 808 active[0] = TREAD4(sc,AUTRI_AIN_A); 809 active[1] = TREAD4(sc,AUTRI_AIN_B); 810 811 if (sc->sc_devid == AUTRI_DEVICE_ID_ALI_M5451) { 812 endch = 32; 813 } else { 814 endch = 64; 815 } 816 817 for (ch=0; ch<endch; ch++) { 818 mask = 1 << (ch & 0x1f); 819 if (active[(ch & 0x20) ? 1 : 0] & mask) { 820 821 /* clear interupt */ 822 TWRITE4(sc, (ch & 0x20) ? AUTRI_AIN_B : AUTRI_AIN_A, mask); 823 /* disable interupt */ 824 autri_reg_clear_4(sc,(ch & 0x20) ? AUTRI_AINTEN_B : AUTRI_AINTEN_A, mask); 825 #if 0 826 reg = TREAD4(sc,AUTRI_LFO_GC_CIR) & ~0x0000003f; 827 TWRITE4(sc,AUTRI_LFO_GC_CIR, reg | ch); 828 829 if (sc->sc_devid == AUTRI_DEVICE_ID_4DWAVE_NX) { 830 cso = TREAD4(sc, 0xe0) & 0x00ffffff; 831 eso = TREAD4(sc, 0xe8) & 0x00ffffff; 832 } else { 833 cso = (TREAD4(sc, 0xe0) >> 16) & 0x0000ffff; 834 eso = (TREAD4(sc, 0xe8) >> 16) & 0x0000ffff; 835 } 836 /*printf("cso=%d, eso=%d\n",cso,eso);*/ 837 #endif 838 if (ch == sc->sc_play.ch_intr) { 839 if (sc->sc_play.intr) 840 sc->sc_play.intr(sc->sc_play.intr_arg); 841 } 842 843 if (ch == sc->sc_rec.ch_intr) { 844 if (sc->sc_rec.intr) 845 sc->sc_rec.intr(sc->sc_rec.intr_arg); 846 } 847 848 /* enable interrupt */ 849 autri_reg_set_4(sc, (ch & 0x20) ? AUTRI_AINTEN_B : AUTRI_AINTEN_A, mask); 850 } 851 } 852 } 853 854 if (intsrc & MPU401_IRQ) { 855 /* XXX */ 856 } 857 858 autri_reg_set_4(sc,AUTRI_MISCINT, 859 ST_TARGET_REACHED | MIXER_OVERFLOW | MIXER_UNDERFLOW); 860 861 return 1; 862 } 863 864 /* 865 * 866 */ 867 868 int 869 autri_allocmem(sc, size, align, p) 870 struct autri_softc *sc; 871 size_t size; 872 size_t align; 873 struct autri_dma *p; 874 { 875 int error; 876 877 p->size = size; 878 error = bus_dmamem_alloc(sc->sc_dmatag, p->size, align, 0, 879 p->segs, sizeof(p->segs)/sizeof(p->segs[0]), 880 &p->nsegs, BUS_DMA_NOWAIT); 881 if (error) 882 return (error); 883 884 error = bus_dmamem_map(sc->sc_dmatag, p->segs, p->nsegs, p->size, 885 &p->addr, BUS_DMA_NOWAIT|BUS_DMA_COHERENT); 886 if (error) 887 goto free; 888 889 error = bus_dmamap_create(sc->sc_dmatag, p->size, 1, p->size, 890 0, BUS_DMA_NOWAIT, &p->map); 891 if (error) 892 goto unmap; 893 894 error = bus_dmamap_load(sc->sc_dmatag, p->map, p->addr, p->size, NULL, 895 BUS_DMA_NOWAIT); 896 if (error) 897 goto destroy; 898 return (0); 899 900 destroy: 901 bus_dmamap_destroy(sc->sc_dmatag, p->map); 902 unmap: 903 bus_dmamem_unmap(sc->sc_dmatag, p->addr, p->size); 904 free: 905 bus_dmamem_free(sc->sc_dmatag, p->segs, p->nsegs); 906 return (error); 907 } 908 909 int 910 autri_freemem(sc, p) 911 struct autri_softc *sc; 912 struct autri_dma *p; 913 { 914 bus_dmamap_unload(sc->sc_dmatag, p->map); 915 bus_dmamap_destroy(sc->sc_dmatag, p->map); 916 bus_dmamem_unmap(sc->sc_dmatag, p->addr, p->size); 917 bus_dmamem_free(sc->sc_dmatag, p->segs, p->nsegs); 918 return 0; 919 } 920 921 int 922 autri_open(addr, flags) 923 void *addr; 924 int flags; 925 { 926 DPRINTF(("autri_open()\n")); 927 DPRINTFN(5,("MISCINT : 0x%08X\n", 928 TREAD4((struct autri_softc *)addr, AUTRI_MISCINT))); 929 DPRINTFN(5,("LFO_GC_CIR : 0x%08X\n", 930 TREAD4((struct autri_softc *)addr, AUTRI_LFO_GC_CIR))); 931 return 0; 932 } 933 934 void 935 autri_close(addr) 936 void *addr; 937 { 938 DPRINTF(("autri_close()\n")); 939 } 940 941 int 942 autri_query_encoding(addr, fp) 943 void *addr; 944 struct audio_encoding *fp; 945 { 946 switch (fp->index) { 947 case 0: 948 strcpy(fp->name, AudioEulinear); 949 fp->encoding = AUDIO_ENCODING_ULINEAR; 950 fp->precision = 8; 951 fp->flags = 0; 952 break; 953 case 1: 954 strcpy(fp->name, AudioEmulaw); 955 fp->encoding = AUDIO_ENCODING_ULAW; 956 fp->precision = 8; 957 fp->flags = AUDIO_ENCODINGFLAG_EMULATED; 958 break; 959 case 2: 960 strcpy(fp->name, AudioEalaw); 961 fp->encoding = AUDIO_ENCODING_ALAW; 962 fp->precision = 8; 963 fp->flags = AUDIO_ENCODINGFLAG_EMULATED; 964 break; 965 case 3: 966 strcpy(fp->name, AudioEslinear); 967 fp->encoding = AUDIO_ENCODING_SLINEAR; 968 fp->precision = 8; 969 fp->flags = 0; 970 break; 971 case 4: 972 strcpy(fp->name, AudioEslinear_le); 973 fp->encoding = AUDIO_ENCODING_SLINEAR_LE; 974 fp->precision = 16; 975 fp->flags = 0; 976 break; 977 case 5: 978 strcpy(fp->name, AudioEulinear_le); 979 fp->encoding = AUDIO_ENCODING_ULINEAR_LE; 980 fp->precision = 16; 981 fp->flags = 0; 982 break; 983 case 6: 984 strcpy(fp->name, AudioEslinear_be); 985 fp->encoding = AUDIO_ENCODING_SLINEAR_BE; 986 fp->precision = 16; 987 fp->flags = AUDIO_ENCODINGFLAG_EMULATED; 988 break; 989 case 7: 990 strcpy(fp->name, AudioEulinear_be); 991 fp->encoding = AUDIO_ENCODING_ULINEAR_BE; 992 fp->precision = 16; 993 fp->flags = AUDIO_ENCODINGFLAG_EMULATED; 994 break; 995 default: 996 return (EINVAL); 997 } 998 999 return 0; 1000 } 1001 1002 int 1003 autri_set_params(addr, setmode, usemode, play, rec) 1004 void *addr; 1005 int setmode, usemode; 1006 struct audio_params *play, *rec; 1007 { 1008 struct audio_params *p; 1009 int mode; 1010 1011 for (mode = AUMODE_RECORD; mode != -1; 1012 mode = mode == AUMODE_RECORD ? AUMODE_PLAY : -1) { 1013 if ((setmode & mode) == 0) 1014 continue; 1015 1016 p = mode == AUMODE_PLAY ? play : rec; 1017 1018 if (p->sample_rate < 4000 || p->sample_rate > 48000 || 1019 (p->precision != 8 && p->precision != 16) || 1020 (p->channels != 1 && p->channels != 2)) 1021 return (EINVAL); 1022 1023 p->factor = 1; 1024 p->sw_code = 0; 1025 switch (p->encoding) { 1026 case AUDIO_ENCODING_SLINEAR_BE: 1027 case AUDIO_ENCODING_ULINEAR_BE: 1028 if (p->precision == 16) 1029 p->sw_code = swap_bytes; 1030 break; 1031 case AUDIO_ENCODING_SLINEAR_LE: 1032 case AUDIO_ENCODING_ULINEAR_LE: 1033 break; 1034 case AUDIO_ENCODING_ULAW: 1035 if (mode == AUMODE_PLAY) 1036 p->sw_code = mulaw_to_ulinear8; 1037 else 1038 p->sw_code = ulinear8_to_mulaw; 1039 1040 break; 1041 case AUDIO_ENCODING_ALAW: 1042 if (mode == AUMODE_PLAY) 1043 p->sw_code = alaw_to_ulinear8; 1044 else 1045 p->sw_code = ulinear8_to_alaw; 1046 1047 break; 1048 default: 1049 return (EINVAL); 1050 } 1051 } 1052 1053 return 0; 1054 } 1055 1056 int 1057 autri_round_blocksize(addr, block) 1058 void *addr; 1059 int block; 1060 { 1061 return (block & -4); 1062 } 1063 1064 int 1065 autri_halt_output(addr) 1066 void *addr; 1067 { 1068 struct autri_softc *sc = addr; 1069 1070 DPRINTF(("autri_halt_output()\n")); 1071 1072 sc->sc_play.intr = NULL; 1073 autri_stopch(sc, sc->sc_play.ch, sc->sc_play.ch_intr); 1074 autri_disable_interrupt(sc, sc->sc_play.ch_intr); 1075 1076 return 0; 1077 } 1078 1079 int 1080 autri_halt_input(addr) 1081 void *addr; 1082 { 1083 struct autri_softc *sc = addr; 1084 1085 DPRINTF(("autri_halt_input()\n")); 1086 1087 sc->sc_rec.intr = NULL; 1088 autri_stopch(sc, sc->sc_rec.ch, sc->sc_rec.ch_intr); 1089 autri_disable_interrupt(sc, sc->sc_rec.ch_intr); 1090 1091 return 0; 1092 } 1093 1094 int 1095 autri_getdev(addr, retp) 1096 void *addr; 1097 struct audio_device *retp; 1098 { 1099 struct autri_softc *sc = addr; 1100 1101 DPRINTF(("autri_getdev().\n")); 1102 1103 strncpy(retp->name, "Trident 4DWAVE", sizeof(retp->name)); 1104 snprintf(retp->version, sizeof(retp->version), "0x%02x", 1105 PCI_REVISION(sc->sc_class)); 1106 1107 switch (sc->sc_devid) { 1108 case AUTRI_DEVICE_ID_4DWAVE_DX: 1109 strncpy(retp->config, "4DWAVE-DX", sizeof(retp->config)); 1110 break; 1111 case AUTRI_DEVICE_ID_4DWAVE_NX: 1112 strncpy(retp->config, "4DWAVE-NX", sizeof(retp->config)); 1113 break; 1114 case AUTRI_DEVICE_ID_SIS_7018: 1115 strncpy(retp->config, "SiS 7018", sizeof(retp->config)); 1116 break; 1117 case AUTRI_DEVICE_ID_ALI_M5451: 1118 strncpy(retp->config, "ALi M5451", sizeof(retp->config)); 1119 break; 1120 default: 1121 strncpy(retp->config, "unknown", sizeof(retp->config)); 1122 } 1123 1124 return 0; 1125 } 1126 1127 int 1128 autri_mixer_set_port(addr, cp) 1129 void *addr; 1130 mixer_ctrl_t *cp; 1131 { 1132 struct autri_softc *sc = addr; 1133 1134 return (sc->sc_codec.codec_if->vtbl->mixer_set_port( 1135 sc->sc_codec.codec_if, cp)); 1136 } 1137 1138 int 1139 autri_mixer_get_port(addr, cp) 1140 void *addr; 1141 mixer_ctrl_t *cp; 1142 { 1143 struct autri_softc *sc = addr; 1144 1145 return (sc->sc_codec.codec_if->vtbl->mixer_get_port( 1146 sc->sc_codec.codec_if, cp)); 1147 } 1148 1149 int 1150 autri_query_devinfo(addr, dip) 1151 void *addr; 1152 mixer_devinfo_t *dip; 1153 { 1154 struct autri_softc *sc = addr; 1155 1156 return (sc->sc_codec.codec_if->vtbl->query_devinfo( 1157 sc->sc_codec.codec_if, dip)); 1158 } 1159 1160 int 1161 autri_get_portnum_by_name(sc, class, device, qualifier) 1162 struct autri_softc *sc; 1163 char *class, *device, *qualifier; 1164 { 1165 return (sc->sc_codec.codec_if->vtbl->get_portnum_by_name( 1166 sc->sc_codec.codec_if, class, device, qualifier)); 1167 } 1168 1169 void * 1170 autri_malloc(addr, direction, size, pool, flags) 1171 void *addr; 1172 int direction; 1173 size_t size; 1174 int pool, flags; 1175 { 1176 struct autri_softc *sc = addr; 1177 struct autri_dma *p; 1178 int error; 1179 1180 p = malloc(sizeof(*p), pool, flags); 1181 if (!p) 1182 return NULL; 1183 1184 #if 0 1185 error = autri_allocmem(sc, size, 16, p); 1186 #endif 1187 error = autri_allocmem(sc, size, 0x10000, p); 1188 if (error) { 1189 free(p, pool); 1190 return NULL; 1191 } 1192 1193 p->next = sc->sc_dmas; 1194 sc->sc_dmas = p; 1195 return KERNADDR(p); 1196 } 1197 1198 void 1199 autri_free(addr, ptr, pool) 1200 void *addr; 1201 void *ptr; 1202 int pool; 1203 { 1204 struct autri_softc *sc = addr; 1205 struct autri_dma **pp, *p; 1206 1207 for (pp = &sc->sc_dmas; (p = *pp) != NULL; pp = &p->next) { 1208 if (KERNADDR(p) == ptr) { 1209 autri_freemem(sc, p); 1210 *pp = p->next; 1211 free(p, pool); 1212 return; 1213 } 1214 } 1215 } 1216 1217 struct autri_dma * 1218 autri_find_dma(sc, addr) 1219 struct autri_softc *sc; 1220 void *addr; 1221 { 1222 struct autri_dma *p; 1223 1224 for (p = sc->sc_dmas; p && KERNADDR(p) != addr; p = p->next) 1225 ; 1226 1227 return p; 1228 } 1229 1230 size_t 1231 autri_round_buffersize(addr, direction, size) 1232 void *addr; 1233 int direction; 1234 size_t size; 1235 { 1236 return size; 1237 } 1238 1239 paddr_t 1240 autri_mappage(addr, mem, off, prot) 1241 void *addr; 1242 void *mem; 1243 off_t off; 1244 int prot; 1245 { 1246 struct autri_softc *sc = addr; 1247 struct autri_dma *p; 1248 1249 if (off < 0) 1250 return (-1); 1251 1252 p = autri_find_dma(sc, mem); 1253 if (!p) 1254 return (-1); 1255 1256 return (bus_dmamem_mmap(sc->sc_dmatag, p->segs, p->nsegs, 1257 off, prot, BUS_DMA_WAITOK)); 1258 } 1259 1260 int 1261 autri_get_props(addr) 1262 void *addr; 1263 { 1264 return (AUDIO_PROP_MMAP | AUDIO_PROP_INDEPENDENT | 1265 AUDIO_PROP_FULLDUPLEX); 1266 } 1267 1268 void 1269 autri_setup_channel(sc, mode, param) 1270 struct autri_softc *sc; 1271 int mode; 1272 struct audio_params *param; 1273 { 1274 int i, ch, channel; 1275 u_int32_t reg, cr[5]; 1276 u_int32_t cso, eso; 1277 u_int32_t delta, dch[2], ctrl; 1278 u_int32_t alpha_fms, fm_vol, attribute; 1279 1280 u_int32_t dmaaddr, dmalen; 1281 int factor, rvol, cvol; 1282 struct autri_chstatus *chst; 1283 1284 ctrl = AUTRI_CTRL_LOOPMODE; 1285 switch (param->encoding) { 1286 case AUDIO_ENCODING_SLINEAR_BE: 1287 case AUDIO_ENCODING_SLINEAR_LE: 1288 ctrl |= AUTRI_CTRL_SIGNED; 1289 break; 1290 } 1291 1292 factor = 0; 1293 if (param->precision == 16) { 1294 ctrl |= AUTRI_CTRL_16BIT; 1295 factor++; 1296 } 1297 1298 if (param->channels == 2) { 1299 ctrl |= AUTRI_CTRL_STEREO; 1300 factor++; 1301 } 1302 1303 delta = (u_int32_t)param->sample_rate; 1304 if (delta < 4000) 1305 delta = 4000; 1306 if (delta > 48000) 1307 delta = 48000; 1308 1309 dch[1] = ((delta << 12) / 48000) & 0x0000ffff; 1310 if (mode == AUMODE_PLAY) { 1311 chst = &sc->sc_play; 1312 dch[0] = ((delta << 12) / 48000) & 0x0000ffff; 1313 if (sc->sc_devid != AUTRI_DEVICE_ID_SIS_7018) 1314 ctrl |= AUTRI_CTRL_WAVEVOL; 1315 /* 1316 if (sc->sc_devid == AUTRI_DEVICE_ID_ALI_M5451) 1317 ctrl |= 0x80000000; 1318 */ 1319 } else { 1320 chst = &sc->sc_rec; 1321 dch[0] = ((48000 << 12) / delta) & 0x0000ffff; 1322 ctrl |= AUTRI_CTRL_MUTE; 1323 } 1324 1325 dmaaddr = DMAADDR(chst->dma); 1326 cso = alpha_fms = 0; 1327 rvol = cvol = 0x7f; 1328 fm_vol = 0x0 | ((rvol & 0x7f) << 7) | (cvol & 0x7f); 1329 attribute = 0; 1330 1331 for (ch=0; ch<2; ch++) { 1332 1333 if (ch == 0) 1334 dmalen = (chst->length >> factor); 1335 else { 1336 /* channel for interrupt */ 1337 dmalen = (chst->blksize >> factor); 1338 ctrl |= AUTRI_CTRL_MUTE; 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 << 16) | (fm_vol & 0x0000ffff); 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) __P((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) __P((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