1 /* $OpenBSD: auixp.c,v 1.33 2014/07/12 18:48:51 tedu Exp $ */ 2 /* $NetBSD: auixp.c,v 1.9 2005/06/27 21:13:09 thorpej Exp $ */ 3 4 /* 5 * Copyright (c) 2004, 2005 Reinoud Zandijk <reinoud@netbsd.org> 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. The name of the author may not be used to endorse or promote products 14 * derived from this software without specific prior written permission. 15 * 3. All advertising materials mentioning features or use of this software 16 * must display the following acknowledgement: 17 * This product includes software developed by the NetBSD 18 * Foundation, Inc. and its contributors. 19 * 4. Neither the name of The NetBSD Foundation nor the names of its 20 * contributors may be used to endorse or promote products derived 21 * from this software without specific prior written permission. 22 * 23 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 24 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 25 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 26 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 27 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 28 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 29 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 30 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 31 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 33 * SUCH DAMAGE. 34 */ 35 /* 36 * Audio driver for ATI IXP-{150,200,...} audio driver hardware. 37 * 38 * Recording and playback has been tested OK on various sample rates and 39 * encodings. 40 * 41 * Known problems and issues : 42 * - SPDIF is untested and needs some work still (LED stays off) 43 * - 32 bit audio playback failed last time i tried but that might an AC'97 44 * codec support problem. 45 * - 32 bit recording works but can't try out playing: see above. 46 * - no suspend/resume support yet. 47 * - multiple codecs are `supported' but not tested; the implemetation needs 48 * some cleaning up. 49 */ 50 51 /*#define DEBUG_AUIXP*/ 52 53 #include <sys/types.h> 54 #include <sys/errno.h> 55 #include <sys/param.h> 56 #include <sys/systm.h> 57 #include <sys/malloc.h> 58 #include <sys/device.h> 59 #include <sys/conf.h> 60 #include <sys/exec.h> 61 #include <sys/selinfo.h> 62 #include <sys/audioio.h> 63 #include <sys/queue.h> 64 65 #include <machine/bus.h> 66 #include <machine/intr.h> 67 68 #include <dev/pci/pcidevs.h> 69 #include <dev/pci/pcivar.h> 70 71 #include <dev/audio_if.h> 72 #include <dev/mulaw.h> 73 #include <dev/auconv.h> 74 #include <dev/ic/ac97.h> 75 76 #include <dev/pci/auixpreg.h> 77 #include <dev/pci/auixpvar.h> 78 79 /* codec detection constant indicating the interrupt flags */ 80 #define ALL_CODECS_NOT_READY \ 81 (ATI_REG_ISR_CODEC0_NOT_READY | ATI_REG_ISR_CODEC1_NOT_READY |\ 82 ATI_REG_ISR_CODEC2_NOT_READY) 83 #define CODEC_CHECK_BITS (ALL_CODECS_NOT_READY|ATI_REG_ISR_NEW_FRAME) 84 85 /* why isn't this base address register not in the headerfile? */ 86 #define PCI_CBIO 0x10 87 88 /* macro's used */ 89 #define KERNADDR(p) ((void *)((p)->addr)) 90 #define DMAADDR(p) ((p)->map->dm_segs[0].ds_addr) 91 92 const struct pci_matchid auixp_pci_devices[] = { 93 { PCI_VENDOR_ATI, PCI_PRODUCT_ATI_SB200_AUDIO }, 94 { PCI_VENDOR_ATI, PCI_PRODUCT_ATI_SB300_AUDIO }, 95 { PCI_VENDOR_ATI, PCI_PRODUCT_ATI_SB400_AUDIO }, 96 { PCI_VENDOR_ATI, PCI_PRODUCT_ATI_SB600_AUDIO } 97 }; 98 99 struct cfdriver auixp_cd = { 100 NULL, "auixp", DV_DULL 101 }; 102 103 int auixp_match( struct device *, void *, void *); 104 void auixp_attach(struct device *, struct device *, void *); 105 int auixp_detach(struct device *, int); 106 107 int auixp_activate(struct device *, int); 108 109 struct cfattach auixp_ca = { 110 sizeof(struct auixp_softc), auixp_match, auixp_attach, 111 NULL, auixp_activate 112 }; 113 114 int auixp_open(void *v, int flags); 115 void auixp_close(void *v); 116 int auixp_query_encoding(void *, struct audio_encoding *); 117 int auixp_set_params(void *, int, int, struct audio_params *, 118 struct audio_params *); 119 int auixp_commit_settings(void *); 120 int auixp_round_blocksize(void *, int); 121 int auixp_trigger_output(void *, void *, void *, int, 122 void (*)(void *), void *, struct audio_params *); 123 int auixp_trigger_input(void *, void *, void *, int, 124 void (*)(void *), void *, struct audio_params *); 125 int auixp_halt_output(void *); 126 int auixp_halt_input(void *); 127 int auixp_set_port(void *, mixer_ctrl_t *); 128 int auixp_get_port(void *, mixer_ctrl_t *); 129 int auixp_query_devinfo(void *, mixer_devinfo_t *); 130 void * auixp_malloc(void *, int, size_t, int, int); 131 void auixp_free(void *, void *, int); 132 int auixp_getdev(void *, struct audio_device *); 133 size_t auixp_round_buffersize(void *, int, size_t); 134 int auixp_get_props(void *); 135 int auixp_intr(void *); 136 int auixp_allocmem(struct auixp_softc *, size_t, size_t, 137 struct auixp_dma *); 138 int auixp_freemem(struct auixp_softc *, struct auixp_dma *); 139 paddr_t auixp_mappage(void *, void *, off_t, int); 140 void auixp_get_default_params(void *, int, struct audio_params *); 141 142 /* Supporting subroutines */ 143 int auixp_init(struct auixp_softc *); 144 void auixp_autodetect_codecs(struct auixp_softc *); 145 void auixp_post_config(void *); 146 147 void auixp_reset_aclink(struct auixp_softc *); 148 int auixp_attach_codec(void *, struct ac97_codec_if *); 149 int auixp_read_codec(void *, u_int8_t, u_int16_t *); 150 int auixp_write_codec(void *, u_int8_t, u_int16_t); 151 int auixp_wait_for_codecs(struct auixp_softc *, const char *); 152 void auixp_reset_codec(void *); 153 enum ac97_host_flags auixp_flags_codec(void *); 154 155 void auixp_enable_dma(struct auixp_softc *, struct auixp_dma *); 156 void auixp_disable_dma(struct auixp_softc *, struct auixp_dma *); 157 void auixp_enable_interrupts(struct auixp_softc *); 158 void auixp_disable_interrupts(struct auixp_softc *); 159 160 void auixp_link_daisychain(struct auixp_softc *, 161 struct auixp_dma *, struct auixp_dma *, int, int); 162 int auixp_allocate_dma_chain(struct auixp_softc *, struct auixp_dma **); 163 void auixp_program_dma_chain(struct auixp_softc *, struct auixp_dma *); 164 void auixp_dma_update(struct auixp_softc *, struct auixp_dma *); 165 void auixp_update_busbusy(struct auixp_softc *); 166 167 #ifdef DEBUG_AUIXP 168 #define DPRINTF(x) printf x; 169 #else 170 #define DPRINTF(x) 171 #endif 172 173 struct audio_hw_if auixp_hw_if = { 174 auixp_open, 175 auixp_close, 176 NULL, /* drain */ 177 auixp_query_encoding, 178 auixp_set_params, 179 auixp_round_blocksize, 180 auixp_commit_settings, 181 NULL, /* init_output */ 182 NULL, /* init_input */ 183 NULL, /* start_output */ 184 NULL, /* start_input */ 185 auixp_halt_output, 186 auixp_halt_input, 187 NULL, /* speaker_ctl */ 188 auixp_getdev, 189 NULL, /* getfd */ 190 auixp_set_port, 191 auixp_get_port, 192 auixp_query_devinfo, 193 auixp_malloc, 194 auixp_free, 195 auixp_round_buffersize, 196 auixp_mappage, 197 auixp_get_props, 198 auixp_trigger_output, 199 auixp_trigger_input, 200 auixp_get_default_params 201 }; 202 203 int 204 auixp_open(void *v, int flags) 205 { 206 207 return 0; 208 } 209 210 void 211 auixp_close(void *v) 212 { 213 } 214 215 void 216 auixp_get_default_params(void *v, int mode, struct audio_params *params) 217 { 218 ac97_get_default_params(params); 219 } 220 221 int 222 auixp_query_encoding(void *hdl, struct audio_encoding *aep) 223 { 224 switch (aep->index) { 225 case 0: 226 strlcpy(aep->name, AudioEulinear, sizeof aep->name); 227 aep->encoding = AUDIO_ENCODING_ULINEAR; 228 aep->precision = 8; 229 aep->flags = AUDIO_ENCODINGFLAG_EMULATED; 230 break; 231 case 1: 232 strlcpy(aep->name, AudioEmulaw, sizeof aep->name); 233 aep->encoding = AUDIO_ENCODING_ULAW; 234 aep->precision = 8; 235 aep->flags = AUDIO_ENCODINGFLAG_EMULATED; 236 break; 237 case 2: 238 strlcpy(aep->name, AudioEalaw, sizeof aep->name); 239 aep->encoding = AUDIO_ENCODING_ALAW; 240 aep->precision = 8; 241 aep->flags = AUDIO_ENCODINGFLAG_EMULATED; 242 break; 243 case 3: 244 strlcpy(aep->name, AudioEslinear, sizeof aep->name); 245 aep->encoding = AUDIO_ENCODING_SLINEAR; 246 aep->precision = 8; 247 aep->flags = AUDIO_ENCODINGFLAG_EMULATED; 248 break; 249 case 4: 250 strlcpy(aep->name, AudioEslinear_le, sizeof aep->name); 251 aep->encoding = AUDIO_ENCODING_SLINEAR_LE; 252 aep->precision = 16; 253 aep->flags = 0; 254 break; 255 case 5: 256 strlcpy(aep->name, AudioEulinear_le, sizeof aep->name); 257 aep->encoding = AUDIO_ENCODING_ULINEAR_LE; 258 aep->precision = 16; 259 aep->flags = AUDIO_ENCODINGFLAG_EMULATED; 260 break; 261 case 6: 262 strlcpy(aep->name, AudioEslinear_be, sizeof aep->name); 263 aep->encoding = AUDIO_ENCODING_SLINEAR_BE; 264 aep->precision = 16; 265 aep->flags = AUDIO_ENCODINGFLAG_EMULATED; 266 break; 267 case 7: 268 strlcpy(aep->name, AudioEulinear_be, sizeof aep->name); 269 aep->encoding = AUDIO_ENCODING_ULINEAR_BE; 270 aep->precision = 16; 271 aep->flags = AUDIO_ENCODINGFLAG_EMULATED; 272 break; 273 default: 274 return (EINVAL); 275 } 276 aep->bps = AUDIO_BPS(aep->precision); 277 aep->msb = 1; 278 279 return (0); 280 } 281 282 283 /* commit setting and program ATI IXP chip */ 284 int 285 auixp_commit_settings(void *hdl) 286 { 287 struct auixp_codec *co; 288 struct auixp_softc *sc; 289 bus_space_tag_t iot; 290 bus_space_handle_t ioh; 291 struct audio_params *params; 292 u_int32_t value; 293 294 /* XXX would it be better to stop interrupts first? XXX */ 295 co = (struct auixp_codec *) hdl; 296 sc = co->sc; 297 iot = sc->sc_iot; 298 ioh = sc->sc_ioh; 299 300 /* process input settings */ 301 params = &sc->sc_play_params; 302 303 /* set input interleaving (precision) */ 304 value = bus_space_read_4(iot, ioh, ATI_REG_CMD); 305 value &= ~ATI_REG_CMD_INTERLEAVE_IN; 306 if (params->precision <= 16) 307 value |= ATI_REG_CMD_INTERLEAVE_IN; 308 bus_space_write_4(iot, ioh, ATI_REG_CMD, value); 309 310 /* process output settings */ 311 params = &sc->sc_play_params; 312 313 value = bus_space_read_4(iot, ioh, ATI_REG_OUT_DMA_SLOT); 314 value &= ~ATI_REG_OUT_DMA_SLOT_MASK; 315 316 /* TODO SPDIF case for 8 channels */ 317 switch (params->channels) { 318 case 6: 319 value |= ATI_REG_OUT_DMA_SLOT_BIT(7) | 320 ATI_REG_OUT_DMA_SLOT_BIT(8); 321 /* FALLTHROUGH */ 322 case 4: 323 value |= ATI_REG_OUT_DMA_SLOT_BIT(6) | 324 ATI_REG_OUT_DMA_SLOT_BIT(9); 325 /* FALLTHROUGH */ 326 default: 327 value |= ATI_REG_OUT_DMA_SLOT_BIT(3) | 328 ATI_REG_OUT_DMA_SLOT_BIT(4); 329 break; 330 } 331 /* set output threshold */ 332 value |= 0x04 << ATI_REG_OUT_DMA_THRESHOLD_SHIFT; 333 bus_space_write_4(iot, ioh, ATI_REG_OUT_DMA_SLOT, value); 334 335 /* set output interleaving (precision) */ 336 value = bus_space_read_4(iot, ioh, ATI_REG_CMD); 337 value &= ~ATI_REG_CMD_INTERLEAVE_OUT; 338 if (params->precision <= 16) 339 value |= ATI_REG_CMD_INTERLEAVE_OUT; 340 bus_space_write_4(iot, ioh, ATI_REG_CMD, value); 341 342 /* enable 6 channel reordering */ 343 value = bus_space_read_4(iot, ioh, ATI_REG_6CH_REORDER); 344 value &= ~ATI_REG_6CH_REORDER_EN; 345 if (params->channels == 6) 346 value |= ATI_REG_6CH_REORDER_EN; 347 bus_space_write_4(iot, ioh, ATI_REG_6CH_REORDER, value); 348 349 if (sc->has_spdif) { 350 /* set SPDIF (if present) */ 351 value = bus_space_read_4(iot, ioh, ATI_REG_CMD); 352 value &= ~ATI_REG_CMD_SPDF_CONFIG_MASK; 353 value |= ATI_REG_CMD_SPDF_CONFIG_34; /* NetBSD AC'97 default */ 354 355 /* XXX this is probably not necessary unless splitted XXX */ 356 value &= ~ATI_REG_CMD_INTERLEAVE_SPDF; 357 if (params->precision <= 16) 358 value |= ATI_REG_CMD_INTERLEAVE_SPDF; 359 bus_space_write_4(iot, ioh, ATI_REG_CMD, value); 360 } 361 362 return 0; 363 } 364 365 366 /* set audio properties in desired setting */ 367 int 368 auixp_set_params(void *hdl, int setmode, int usemode, 369 struct audio_params *play, struct audio_params *rec) 370 { 371 struct auixp_codec *co; 372 int error; 373 u_int temprate; 374 375 co = (struct auixp_codec *) hdl; 376 if (setmode & AUMODE_PLAY) { 377 play->factor = 1; 378 play->sw_code = NULL; 379 if (play->channels > 2) 380 play->channels = 2; 381 if (play->precision > 16) 382 play->precision = 16; 383 switch(play->encoding) { 384 case AUDIO_ENCODING_ULAW: 385 switch (play->channels) { 386 case 1: 387 play->factor = 4; 388 play->sw_code = mulaw_to_slinear16_le_mts; 389 break; 390 case 2: 391 play->factor = 2; 392 play->sw_code = mulaw_to_slinear16_le; 393 break; 394 default: 395 return (EINVAL); 396 } 397 break; 398 case AUDIO_ENCODING_SLINEAR_LE: 399 switch (play->precision) { 400 case 8: 401 switch (play->channels) { 402 case 1: 403 play->factor = 4; 404 play->sw_code = linear8_to_linear16_le_mts; 405 break; 406 case 2: 407 play->factor = 2; 408 play->sw_code = linear8_to_linear16_le; 409 break; 410 default: 411 return (EINVAL); 412 } 413 break; 414 case 16: 415 switch (play->channels) { 416 case 1: 417 play->factor = 2; 418 play->sw_code = noswap_bytes_mts; 419 break; 420 case 2: 421 break; 422 default: 423 return (EINVAL); 424 } 425 break; 426 default: 427 return (EINVAL); 428 } 429 break; 430 case AUDIO_ENCODING_ULINEAR_LE: 431 switch (play->precision) { 432 case 8: 433 switch (play->channels) { 434 case 1: 435 play->factor = 4; 436 play->sw_code = ulinear8_to_linear16_le_mts; 437 break; 438 case 2: 439 play->factor = 2; 440 play->sw_code = ulinear8_to_linear16_le; 441 break; 442 default: 443 return (EINVAL); 444 } 445 break; 446 case 16: 447 switch (play->channels) { 448 case 1: 449 play->factor = 2; 450 play->sw_code = change_sign16_le_mts; 451 break; 452 case 2: 453 play->sw_code = change_sign16_le; 454 break; 455 default: 456 return (EINVAL); 457 } 458 break; 459 default: 460 return (EINVAL); 461 } 462 break; 463 case AUDIO_ENCODING_ALAW: 464 switch (play->channels) { 465 case 1: 466 play->factor = 4; 467 play->sw_code = alaw_to_slinear16_le_mts; 468 break; 469 case 2: 470 play->factor = 2; 471 play->sw_code = alaw_to_slinear16_le; 472 break; 473 default: 474 return (EINVAL); 475 } 476 break; 477 case AUDIO_ENCODING_SLINEAR_BE: 478 switch (play->precision) { 479 case 8: 480 switch (play->channels) { 481 case 1: 482 play->factor = 4; 483 play->sw_code = linear8_to_linear16_le_mts; 484 break; 485 case 2: 486 play->factor = 2; 487 play->sw_code = linear8_to_linear16_le; 488 break; 489 default: 490 return (EINVAL); 491 } 492 break; 493 case 16: 494 switch (play->channels) { 495 case 1: 496 play->factor = 2; 497 play->sw_code = swap_bytes_mts; 498 break; 499 case 2: 500 play->sw_code = swap_bytes; 501 break; 502 default: 503 return (EINVAL); 504 } 505 break; 506 default: 507 return (EINVAL); 508 } 509 break; 510 case AUDIO_ENCODING_ULINEAR_BE: 511 switch (play->precision) { 512 case 8: 513 switch (play->channels) { 514 case 1: 515 play->factor = 4; 516 play->sw_code = ulinear8_to_linear16_le_mts; 517 break; 518 case 2: 519 play->factor = 2; 520 play->sw_code = ulinear8_to_linear16_le; 521 break; 522 default: 523 return (EINVAL); 524 } 525 break; 526 case 16: 527 switch (play->channels) { 528 case 1: 529 play->factor = 2; 530 play->sw_code = swap_bytes_change_sign16_le_mts; 531 break; 532 case 2: 533 play->sw_code = swap_bytes_change_sign16_le; 534 break; 535 default: 536 return (EINVAL); 537 } 538 break; 539 default: 540 return (EINVAL); 541 } 542 break; 543 default: 544 return (EINVAL); 545 } 546 play->bps = AUDIO_BPS(play->precision); 547 play->msb = 1; 548 549 temprate = play->sample_rate; 550 error = ac97_set_rate(co->codec_if, 551 AC97_REG_PCM_LFE_DAC_RATE, &play->sample_rate); 552 if (error) 553 return (error); 554 555 play->sample_rate = temprate; 556 error = ac97_set_rate(co->codec_if, 557 AC97_REG_PCM_SURR_DAC_RATE, &play->sample_rate); 558 if (error) 559 return (error); 560 561 play->sample_rate = temprate; 562 error = ac97_set_rate(co->codec_if, 563 AC97_REG_PCM_FRONT_DAC_RATE, &play->sample_rate); 564 if (error) 565 return (error); 566 567 } 568 569 if (setmode & AUMODE_RECORD) { 570 rec->factor = 1; 571 rec->sw_code = 0; 572 if (rec->channels > 2) 573 rec->channels = 2; 574 if (rec->precision > 16) 575 rec->precision = 16; 576 switch(rec->encoding) { 577 case AUDIO_ENCODING_ULAW: 578 rec->sw_code = ulinear8_to_mulaw; 579 break; 580 case AUDIO_ENCODING_SLINEAR_LE: 581 if (rec->precision == 8) 582 rec->sw_code = change_sign8; 583 break; 584 case AUDIO_ENCODING_ULINEAR_LE: 585 if (rec->precision == 16) 586 rec->sw_code = change_sign16_le; 587 break; 588 case AUDIO_ENCODING_ALAW: 589 rec->sw_code = ulinear8_to_alaw; 590 break; 591 case AUDIO_ENCODING_SLINEAR_BE: 592 if (rec->precision == 16) 593 rec->sw_code = swap_bytes; 594 else 595 rec->sw_code = change_sign8; 596 break; 597 case AUDIO_ENCODING_ULINEAR_BE: 598 if (rec->precision == 16) 599 rec->sw_code = swap_bytes_change_sign16_le; 600 break; 601 default: 602 return (EINVAL); 603 } 604 rec->bps = AUDIO_BPS(rec->precision); 605 rec->msb = 1; 606 607 error = ac97_set_rate(co->codec_if, AC97_REG_PCM_LR_ADC_RATE, 608 &rec->sample_rate); 609 if (error) 610 return (error); 611 } 612 613 return (0); 614 } 615 616 617 /* called to translate a requested blocksize to a hw-possible one */ 618 int 619 auixp_round_blocksize(void *v, int blk) 620 { 621 622 blk = (blk + 0x1f) & ~0x1f; 623 /* Be conservative; align to 32 bytes and maximise it to 64 kb */ 624 if (blk > 0x10000) 625 blk = 0x10000; 626 627 return blk; 628 } 629 630 631 /* 632 * allocate dma capable memory and record its information for later retrieval 633 * when we program the dma chain itself. The trigger routines passes on the 634 * kernel virtual address we return here as a reference to the mapping. 635 */ 636 void * 637 auixp_malloc(void *hdl, int direction, size_t size, int pool, int flags) 638 { 639 struct auixp_codec *co; 640 struct auixp_softc *sc; 641 struct auixp_dma *dma; 642 int error; 643 644 co = (struct auixp_codec *) hdl; 645 sc = co->sc; 646 /* get us a auixp_dma structure */ 647 dma = malloc(sizeof(*dma), pool, flags); 648 if (!dma) 649 return NULL; 650 651 /* get us a dma buffer itself */ 652 error = auixp_allocmem(sc, size, 16, dma); 653 if (error) { 654 free(dma, pool, 0); 655 printf("%s: auixp_malloc: not enough memory\n", 656 sc->sc_dev.dv_xname); 657 return NULL; 658 } 659 SLIST_INSERT_HEAD(&sc->sc_dma_list, dma, dma_chain); 660 661 DPRINTF(("auixp_malloc: returning kern %p, hw 0x%08x for %d bytes " 662 "in %d segs\n", KERNADDR(dma), (u_int32_t) DMAADDR(dma), dma->size, 663 dma->nsegs) 664 ); 665 666 return KERNADDR(dma); 667 } 668 669 /* 670 * free and release dma capable memory we allocated before and remove its 671 * recording 672 */ 673 void 674 auixp_free(void *hdl, void *addr, int pool) 675 { 676 struct auixp_codec *co; 677 struct auixp_softc *sc; 678 struct auixp_dma *dma; 679 680 co = (struct auixp_codec *) hdl; 681 sc = co->sc; 682 SLIST_FOREACH(dma, &sc->sc_dma_list, dma_chain) { 683 if (KERNADDR(dma) == addr) { 684 SLIST_REMOVE(&sc->sc_dma_list, dma, auixp_dma, 685 dma_chain); 686 auixp_freemem(sc, dma); 687 free(dma, pool, 0); 688 return; 689 } 690 } 691 } 692 693 int 694 auixp_getdev(void *v, struct audio_device *adp) 695 { 696 struct auixp_softc *sc = v; 697 *adp = sc->sc_audev; 698 return 0; 699 } 700 701 /* pass request to AC'97 codec code */ 702 int 703 auixp_set_port(void *hdl, mixer_ctrl_t *mc) 704 { 705 struct auixp_codec *co; 706 707 co = (struct auixp_codec *) hdl; 708 return co->codec_if->vtbl->mixer_set_port(co->codec_if, mc); 709 } 710 711 712 /* pass request to AC'97 codec code */ 713 int 714 auixp_get_port(void *hdl, mixer_ctrl_t *mc) 715 { 716 struct auixp_codec *co; 717 718 co = (struct auixp_codec *) hdl; 719 return co->codec_if->vtbl->mixer_get_port(co->codec_if, mc); 720 } 721 722 /* pass request to AC'97 codec code */ 723 int 724 auixp_query_devinfo(void *hdl, mixer_devinfo_t *di) 725 { 726 struct auixp_codec *co; 727 728 co = (struct auixp_codec *) hdl; 729 return co->codec_if->vtbl->query_devinfo(co->codec_if, di); 730 } 731 732 733 size_t 734 auixp_round_buffersize(void *hdl, int direction, size_t bufsize) 735 { 736 737 /* XXX force maximum? i.e. 256 kb? */ 738 return bufsize; 739 } 740 741 742 int 743 auixp_get_props(void *hdl) 744 { 745 746 return AUDIO_PROP_MMAP | AUDIO_PROP_INDEPENDENT | AUDIO_PROP_FULLDUPLEX; 747 } 748 749 750 /* 751 * A dma descriptor has dma->nsegs segments defined in dma->segs set up when 752 * we claimed the memory. 753 * 754 * Due to our demand for one contiguous DMA area, we only have one segment. A 755 * c_dma structure is about 3 kb for the 256 entries we maximally program 756 * -arbitrary limit AFAIK- so all is most likely to be in one segment/page 757 * anyway. 758 * 759 * XXX ought to implement fragmented dma area XXX 760 * 761 * Note that _v variables depict kernel virtual addresses, _p variables depict 762 * physical addresses. 763 */ 764 void 765 auixp_link_daisychain(struct auixp_softc *sc, 766 struct auixp_dma *c_dma, struct auixp_dma *s_dma, 767 int blksize, int blocks) 768 { 769 atiixp_dma_desc_t *caddr_v, *next_caddr_v; 770 u_int32_t caddr_p, next_caddr_p, saddr_p; 771 int i; 772 773 /* just make sure we are not changing when its running */ 774 auixp_disable_dma(sc, c_dma); 775 776 /* setup dma chain start addresses */ 777 caddr_v = KERNADDR(c_dma); 778 caddr_p = DMAADDR(c_dma); 779 saddr_p = DMAADDR(s_dma); 780 781 /* program the requested number of blocks */ 782 for (i = 0; i < blocks; i++) { 783 /* clear the block just in case */ 784 bzero(caddr_v, sizeof(atiixp_dma_desc_t)); 785 786 /* round robin the chain dma addresses for its successor */ 787 next_caddr_v = caddr_v + 1; 788 next_caddr_p = caddr_p + sizeof(atiixp_dma_desc_t); 789 790 if (i == blocks-1) { 791 next_caddr_v = KERNADDR(c_dma); 792 next_caddr_p = DMAADDR(c_dma); 793 } 794 795 /* fill in the hardware dma chain descriptor in little-endian */ 796 caddr_v->addr = htole32(saddr_p); 797 caddr_v->status = htole16(0); 798 caddr_v->size = htole16((blksize >> 2)); /* in dwords (!!!) */ 799 caddr_v->next = htole32(next_caddr_p); 800 801 /* advance slot */ 802 saddr_p += blksize; /* XXX assuming contiguous XXX */ 803 caddr_v = next_caddr_v; 804 caddr_p = next_caddr_p; 805 } 806 } 807 808 809 int 810 auixp_allocate_dma_chain(struct auixp_softc *sc, struct auixp_dma **dmap) 811 { 812 struct auixp_dma *dma; 813 int error; 814 815 /* allocate keeper of dma area */ 816 *dmap = NULL; 817 dma = malloc(sizeof(*dma), M_DEVBUF, M_NOWAIT | M_ZERO); 818 if (!dma) 819 return ENOMEM; 820 821 /* allocate for daisychain of IXP hardware-dma descriptors */ 822 error = auixp_allocmem(sc, DMA_DESC_CHAIN * sizeof(atiixp_dma_desc_t), 823 16, dma); 824 if (error) { 825 printf("%s: can't malloc dma descriptor chain\n", 826 sc->sc_dev.dv_xname); 827 free(dma, M_DEVBUF, 0); 828 return ENOMEM; 829 } 830 831 /* return info and initialise structure */ 832 dma->intr = NULL; 833 dma->intrarg = NULL; 834 835 *dmap = dma; 836 return 0; 837 } 838 839 840 /* program dma chain in its link address descriptor */ 841 void 842 auixp_program_dma_chain(struct auixp_softc *sc, struct auixp_dma *dma) 843 { 844 bus_space_tag_t iot; 845 bus_space_handle_t ioh; 846 u_int32_t value; 847 848 iot = sc->sc_iot; 849 ioh = sc->sc_ioh; 850 /* get hardware start address of DMA chain and set valid-flag in it */ 851 /* XXX always at start? XXX */ 852 value = DMAADDR(dma); 853 value = value | ATI_REG_LINKPTR_EN; 854 855 /* reset linkpointer */ 856 bus_space_write_4(iot, ioh, dma->linkptr, 0); 857 858 /* reset this DMA engine */ 859 auixp_disable_dma(sc, dma); 860 auixp_enable_dma(sc, dma); 861 862 /* program new DMA linkpointer */ 863 bus_space_write_4(iot, ioh, dma->linkptr, value); 864 } 865 866 867 /* called from interrupt code to signal end of one dma-slot */ 868 void 869 auixp_dma_update(struct auixp_softc *sc, struct auixp_dma *dma) 870 { 871 872 /* be very paranoid */ 873 if (!dma) 874 panic("auixp: update: dma = NULL"); 875 if (!dma->intr) 876 panic("auixp: update: dma->intr = NULL"); 877 878 /* request more input from upper layer */ 879 (*dma->intr)(dma->intrarg); 880 } 881 882 883 /* 884 * The magic `busbusy' bit that needs to be set when dma is active; allowing 885 * busmastering? 886 */ 887 void 888 auixp_update_busbusy(struct auixp_softc *sc) 889 { 890 bus_space_tag_t iot; 891 bus_space_handle_t ioh; 892 u_int32_t value; 893 int running; 894 895 iot = sc->sc_iot; 896 ioh = sc->sc_ioh; 897 /* set bus-busy flag when either recording or playing is performed */ 898 value = bus_space_read_4(iot, ioh, ATI_REG_IER); 899 value &= ~ATI_REG_IER_SET_BUS_BUSY; 900 901 running = ((sc->sc_output_dma->running) || (sc->sc_input_dma->running)); 902 if (running) 903 value |= ATI_REG_IER_SET_BUS_BUSY; 904 905 bus_space_write_4(iot, ioh, ATI_REG_IER, value); 906 907 } 908 909 910 /* 911 * Called from upper audio layer to request playing audio, only called once; 912 * audio is refilled by calling the intr() function when space is available 913 * again. 914 */ 915 /* XXX almost literally a copy of trigger-input; could be factorised XXX */ 916 int 917 auixp_trigger_output(void *hdl, void *start, void *end, int blksize, 918 void (*intr)(void *), void *intrarg, struct audio_params *param) 919 { 920 struct auixp_codec *co; 921 struct auixp_softc *sc; 922 struct auixp_dma *chain_dma; 923 struct auixp_dma *sound_dma; 924 u_int32_t blocks; 925 926 co = (struct auixp_codec *) hdl; 927 sc = co->sc; 928 chain_dma = sc->sc_output_dma; 929 /* add functions to call back */ 930 chain_dma->intr = intr; 931 chain_dma->intrarg = intrarg; 932 933 /* 934 * Program output DMA chain with blocks from [start...end] with 935 * blksize fragments. 936 * 937 * NOTE, we can assume its in one block since we asked for it to be in 938 * one contiguous blob; XXX change this? XXX 939 */ 940 blocks = (size_t) (((caddr_t) end) - ((caddr_t) start)) / blksize; 941 942 /* lookup `start' address in our list of DMA area's */ 943 SLIST_FOREACH(sound_dma, &sc->sc_dma_list, dma_chain) { 944 if (KERNADDR(sound_dma) == start) 945 break; 946 } 947 948 /* not ours ? then bail out */ 949 if (!sound_dma) { 950 printf("%s: auixp_trigger_output: bad sound addr %p\n", 951 sc->sc_dev.dv_xname, start); 952 return EINVAL; 953 } 954 955 /* link round-robin daisychain and program hardware */ 956 auixp_link_daisychain(sc, chain_dma, sound_dma, blksize, blocks); 957 auixp_program_dma_chain(sc, chain_dma); 958 959 /* mark we are now able to run now */ 960 mtx_enter(&audio_lock); 961 chain_dma->running = 1; 962 963 /* update bus-flags; XXX programs more flags XXX */ 964 auixp_update_busbusy(sc); 965 mtx_leave(&audio_lock); 966 967 /* callbacks happen in interrupt routine */ 968 return 0; 969 } 970 971 972 /* halt output of audio, just disable its dma and update bus state */ 973 int 974 auixp_halt_output(void *hdl) 975 { 976 struct auixp_codec *co; 977 struct auixp_softc *sc; 978 struct auixp_dma *dma; 979 980 mtx_enter(&audio_lock); 981 co = (struct auixp_codec *) hdl; 982 sc = co->sc; 983 dma = sc->sc_output_dma; 984 auixp_disable_dma(sc, dma); 985 986 dma->running = 0; 987 auixp_update_busbusy(sc); 988 mtx_leave(&audio_lock); 989 return 0; 990 } 991 992 993 /* XXX almost literally a copy of trigger-output; could be factorised XXX */ 994 int 995 auixp_trigger_input(void *hdl, void *start, void *end, int blksize, 996 void (*intr)(void *), void *intrarg, struct audio_params *param) 997 { 998 struct auixp_codec *co; 999 struct auixp_softc *sc; 1000 struct auixp_dma *chain_dma; 1001 struct auixp_dma *sound_dma; 1002 u_int32_t blocks; 1003 1004 co = (struct auixp_codec *) hdl; 1005 sc = co->sc; 1006 chain_dma = sc->sc_input_dma; 1007 /* add functions to call back */ 1008 chain_dma->intr = intr; 1009 chain_dma->intrarg = intrarg; 1010 1011 /* 1012 * Program output DMA chain with blocks from [start...end] with 1013 * blksize fragments. 1014 * 1015 * NOTE, we can assume its in one block since we asked for it to be in 1016 * one contiguous blob; XXX change this? XXX 1017 */ 1018 blocks = (size_t) (((caddr_t) end) - ((caddr_t) start)) / blksize; 1019 1020 /* lookup `start' address in our list of DMA area's */ 1021 SLIST_FOREACH(sound_dma, &sc->sc_dma_list, dma_chain) { 1022 if (KERNADDR(sound_dma) == start) 1023 break; 1024 } 1025 1026 /* not ours ? then bail out */ 1027 if (!sound_dma) { 1028 printf("%s: auixp_trigger_input: bad sound addr %p\n", 1029 sc->sc_dev.dv_xname, start); 1030 return EINVAL; 1031 } 1032 1033 /* link round-robin daisychain and program hardware */ 1034 auixp_link_daisychain(sc, chain_dma, sound_dma, blksize, blocks); 1035 auixp_program_dma_chain(sc, chain_dma); 1036 1037 /* mark we are now able to run now */ 1038 mtx_enter(&audio_lock); 1039 chain_dma->running = 1; 1040 1041 /* update bus-flags; XXX programs more flags XXX */ 1042 auixp_update_busbusy(sc); 1043 mtx_leave(&audio_lock); 1044 1045 /* callbacks happen in interrupt routine */ 1046 return 0; 1047 } 1048 1049 1050 /* halt sampling audio, just disable its dma and update bus state */ 1051 int 1052 auixp_halt_input(void *hdl) 1053 { 1054 struct auixp_codec *co; 1055 struct auixp_softc *sc; 1056 struct auixp_dma *dma; 1057 1058 mtx_enter(&audio_lock); 1059 co = (struct auixp_codec *) hdl; 1060 sc = co->sc; 1061 dma = sc->sc_input_dma; 1062 auixp_disable_dma(sc, dma); 1063 1064 dma->running = 0; 1065 auixp_update_busbusy(sc); 1066 1067 mtx_leave(&audio_lock); 1068 return 0; 1069 } 1070 1071 1072 /* 1073 * IXP audio interrupt handler 1074 * 1075 * note that we return the number of bits handled; the return value is not 1076 * documented but I saw it implemented in other drivers. Probably returning a 1077 * value > 0 means "I've dealt with it" 1078 * 1079 */ 1080 int 1081 auixp_intr(void *softc) 1082 { 1083 struct auixp_softc *sc; 1084 bus_space_tag_t iot; 1085 bus_space_handle_t ioh; 1086 u_int32_t status, enable, detected_codecs; 1087 int ret; 1088 1089 mtx_enter(&audio_lock); 1090 sc = softc; 1091 iot = sc->sc_iot; 1092 ioh = sc->sc_ioh; 1093 ret = 0; 1094 /* get status from the interrupt status register */ 1095 status = bus_space_read_4(iot, ioh, ATI_REG_ISR); 1096 1097 if (status == 0) { 1098 mtx_leave(&audio_lock); 1099 return 0; 1100 } 1101 1102 DPRINTF(("%s: (status = %x)\n", sc->sc_dev.dv_xname, status)); 1103 1104 /* check DMA UPDATE flags for input & output */ 1105 if (status & ATI_REG_ISR_IN_STATUS) { 1106 ret++; DPRINTF(("IN_STATUS\n")); 1107 auixp_dma_update(sc, sc->sc_input_dma); 1108 } 1109 if (status & ATI_REG_ISR_OUT_STATUS) { 1110 ret++; DPRINTF(("OUT_STATUS\n")); 1111 auixp_dma_update(sc, sc->sc_output_dma); 1112 } 1113 1114 /* XXX XRUN flags not used/needed yet; should i implement it? XXX */ 1115 /* acknowledge the interrupts nevertheless */ 1116 if (status & ATI_REG_ISR_IN_XRUN) { 1117 ret++; DPRINTF(("IN_XRUN\n")); 1118 /* auixp_dma_xrun(sc, sc->sc_input_dma); */ 1119 } 1120 if (status & ATI_REG_ISR_OUT_XRUN) { 1121 ret++; DPRINTF(("OUT_XRUN\n")); 1122 /* auixp_dma_xrun(sc, sc->sc_output_dma); */ 1123 } 1124 1125 /* check if we are looking for codec detection */ 1126 if (status & CODEC_CHECK_BITS) { 1127 ret++; 1128 /* mark missing codecs as not ready */ 1129 detected_codecs = status & CODEC_CHECK_BITS; 1130 sc->sc_codec_not_ready_bits |= detected_codecs; 1131 1132 /* disable detected interrupt sources */ 1133 enable = bus_space_read_4(iot, ioh, ATI_REG_IER); 1134 enable &= ~detected_codecs; 1135 bus_space_write_4(iot, ioh, ATI_REG_IER, enable); 1136 } 1137 1138 /* acknowledge interrupt sources */ 1139 bus_space_write_4(iot, ioh, ATI_REG_ISR, status); 1140 mtx_leave(&audio_lock); 1141 return ret; 1142 } 1143 1144 1145 /* allocate memory for dma purposes; on failure of any of the steps, roll back */ 1146 int 1147 auixp_allocmem(struct auixp_softc *sc, size_t size, 1148 size_t align, struct auixp_dma *dma) 1149 { 1150 int error; 1151 1152 /* remember size */ 1153 dma->size = size; 1154 1155 /* allocate DMA safe memory but in just one segment for now :( */ 1156 error = bus_dmamem_alloc(sc->sc_dmat, dma->size, align, 0, 1157 dma->segs, sizeof(dma->segs) / sizeof(dma->segs[0]), &dma->nsegs, 1158 BUS_DMA_NOWAIT); 1159 if (error) 1160 return error; 1161 1162 /* 1163 * map allocated memory into kernel virtual address space and keep it 1164 * coherent with the CPU. 1165 */ 1166 error = bus_dmamem_map(sc->sc_dmat, dma->segs, dma->nsegs, dma->size, 1167 &dma->addr, BUS_DMA_NOWAIT | BUS_DMA_COHERENT); 1168 if (error) 1169 goto free; 1170 1171 /* allocate associated dma handle and initialize it. */ 1172 error = bus_dmamap_create(sc->sc_dmat, dma->size, 1, dma->size, 0, 1173 BUS_DMA_NOWAIT, &dma->map); 1174 if (error) 1175 goto unmap; 1176 1177 /* 1178 * load the dma handle with mappings for a dma transfer; all pages 1179 * need to be wired. 1180 */ 1181 error = bus_dmamap_load(sc->sc_dmat, dma->map, dma->addr, dma->size, NULL, 1182 BUS_DMA_NOWAIT); 1183 if (error) 1184 goto destroy; 1185 1186 return 0; 1187 1188 destroy: 1189 bus_dmamap_destroy(sc->sc_dmat, dma->map); 1190 unmap: 1191 bus_dmamem_unmap(sc->sc_dmat, dma->addr, dma->size); 1192 free: 1193 bus_dmamem_free(sc->sc_dmat, dma->segs, dma->nsegs); 1194 1195 return error; 1196 } 1197 1198 1199 /* undo dma mapping and release memory allocated */ 1200 int 1201 auixp_freemem(struct auixp_softc *sc, struct auixp_dma *p) 1202 { 1203 1204 bus_dmamap_unload(sc->sc_dmat, p->map); 1205 bus_dmamap_destroy(sc->sc_dmat, p->map); 1206 bus_dmamem_unmap(sc->sc_dmat, p->addr, p->size); 1207 bus_dmamem_free(sc->sc_dmat, p->segs, p->nsegs); 1208 1209 return 0; 1210 } 1211 1212 1213 /* memory map dma memory */ 1214 paddr_t 1215 auixp_mappage(void *hdl, void *mem, off_t off, int prot) 1216 { 1217 struct auixp_codec *co; 1218 struct auixp_softc *sc; 1219 struct auixp_dma *p; 1220 1221 co = (struct auixp_codec *) hdl; 1222 sc = co->sc; 1223 /* for sanity */ 1224 if (off < 0) 1225 return -1; 1226 1227 /* look up allocated DMA area */ 1228 SLIST_FOREACH(p, &sc->sc_dma_list, dma_chain) { 1229 if (KERNADDR(p) == mem) 1230 break; 1231 } 1232 1233 /* have we found it ? */ 1234 if (!p) 1235 return -1; 1236 1237 /* return mmap'd region */ 1238 return bus_dmamem_mmap(sc->sc_dmat, p->segs, p->nsegs, 1239 off, prot, BUS_DMA_WAITOK); 1240 } 1241 1242 int 1243 auixp_match(struct device *dev, void *match, void *aux) 1244 { 1245 return (pci_matchbyid((struct pci_attach_args *)aux, auixp_pci_devices, 1246 sizeof(auixp_pci_devices)/sizeof(auixp_pci_devices[0]))); 1247 } 1248 1249 int 1250 auixp_activate(struct device *self, int act) 1251 { 1252 struct auixp_softc *sc = (struct auixp_softc *)self; 1253 int rv = 0; 1254 1255 switch (act) { 1256 case DVACT_SUSPEND: 1257 auixp_disable_interrupts(sc); 1258 break; 1259 case DVACT_RESUME: 1260 auixp_init(sc); 1261 ac97_resume(&sc->sc_codec.host_if, sc->sc_codec.codec_if); 1262 rv = config_activate_children(self, act); 1263 break; 1264 default: 1265 rv = config_activate_children(self, act); 1266 break; 1267 } 1268 return (rv); 1269 } 1270 1271 void 1272 auixp_attach(struct device *parent, struct device *self, void *aux) 1273 { 1274 struct auixp_softc *sc; 1275 struct pci_attach_args *pa; 1276 pcitag_t tag; 1277 pci_chipset_tag_t pc; 1278 pci_intr_handle_t ih; 1279 const char *intrstr; 1280 1281 sc = (struct auixp_softc *)self; 1282 pa = (struct pci_attach_args *)aux; 1283 tag = pa->pa_tag; 1284 pc = pa->pa_pc; 1285 1286 /* map memory; its not sized -> what is the size? max PCI slot size? */ 1287 if (pci_mapreg_map(pa, PCI_CBIO, PCI_MAPREG_TYPE_MEM, 0, 1288 &sc->sc_iot, &sc->sc_ioh, &sc->sc_iob, &sc->sc_ios, 0)) { 1289 printf(": can't map mem space\n"); 1290 return; 1291 } 1292 1293 /* Initialize softc */ 1294 sc->sc_tag = tag; 1295 sc->sc_pct = pc; 1296 sc->sc_dmat = pa->pa_dmat; 1297 SLIST_INIT(&sc->sc_dma_list); 1298 1299 /* get us the auixp_dma structures */ 1300 auixp_allocate_dma_chain(sc, &sc->sc_output_dma); 1301 auixp_allocate_dma_chain(sc, &sc->sc_input_dma); 1302 1303 /* when that fails we are dead in the water */ 1304 if (!sc->sc_output_dma || !sc->sc_input_dma) 1305 return; 1306 1307 #if 0 1308 /* could preliminary program DMA chain */ 1309 auixp_program_dma_chain(sc, sc->sc_output_dma); 1310 auixp_program_dma_chain(sc, sc->sc_input_dma); 1311 #endif 1312 1313 if (pci_intr_map(pa, &ih)) { 1314 printf(": can't map interrupt\n"); 1315 return; 1316 } 1317 intrstr = pci_intr_string(pc, ih); 1318 sc->sc_ih = pci_intr_establish(pc, ih, IPL_AUDIO | IPL_MPSAFE, 1319 auixp_intr, sc, sc->sc_dev.dv_xname); 1320 if (sc->sc_ih == NULL) { 1321 printf(": can't establish interrupt"); 1322 if (intrstr != NULL) 1323 printf(" at %s", intrstr); 1324 printf("\n"); 1325 return; 1326 } 1327 printf(": %s\n", intrstr); 1328 1329 strlcpy(sc->sc_audev.name, "ATI IXP AC97", sizeof sc->sc_audev.name); 1330 snprintf(sc->sc_audev.version, sizeof sc->sc_audev.version, "0x%02x", 1331 PCI_REVISION(pa->pa_class)); 1332 strlcpy(sc->sc_audev.config, sc->sc_dev.dv_xname, 1333 sizeof sc->sc_audev.config); 1334 1335 /* power up chip */ 1336 pci_set_powerstate(pc, tag, PCI_PMCSR_STATE_D0); 1337 1338 /* init chip */ 1339 if (auixp_init(sc) == -1) { 1340 printf("%s: auixp_attach: unable to initialize the card\n", 1341 sc->sc_dev.dv_xname); 1342 return; 1343 } 1344 1345 /* 1346 * delay further configuration of codecs and audio after interrupts 1347 * are enabled. 1348 */ 1349 mountroothook_establish(auixp_post_config, self); 1350 } 1351 1352 /* called from autoconfigure system when interrupts are enabled */ 1353 void 1354 auixp_post_config(void *self) 1355 { 1356 struct auixp_softc *sc; 1357 1358 sc = (struct auixp_softc *)self; 1359 /* detect the AC97 codecs */ 1360 auixp_autodetect_codecs(sc); 1361 1362 /* Bail if no codecs attached. */ 1363 if (!sc->sc_codec.present) { 1364 printf("%s: no codecs detected or initialised\n", 1365 sc->sc_dev.dv_xname); 1366 return; 1367 } 1368 1369 audio_attach_mi(&auixp_hw_if, &sc->sc_codec, &sc->sc_dev); 1370 1371 #if notyet 1372 /* copy formats and invalidate entries not suitable for codec0 */ 1373 sc->has_4ch = AC97_IS_4CH(sc->sc_codec.codec_if); 1374 sc->has_6ch = AC97_IS_6CH(sc->sc_codec.codec_if); 1375 sc->is_fixed = AC97_IS_FIXED_RATE(sc->sc_codec.codec_if); 1376 sc->has_spdif = AC97_HAS_SPDIF(sc->sc_codec.codec_if); 1377 #endif 1378 1379 if (sc->has_spdif) 1380 sc->has_spdif = 0; 1381 1382 /* fill in the missing details about the dma channels. */ 1383 /* for output */ 1384 sc->sc_output_dma->linkptr = ATI_REG_OUT_DMA_LINKPTR; 1385 sc->sc_output_dma->dma_enable_bit = ATI_REG_CMD_OUT_DMA_EN | 1386 ATI_REG_CMD_SEND_EN; 1387 /* have spdif? then this too! XXX not seeing LED yet! XXX */ 1388 if (sc->has_spdif) 1389 sc->sc_output_dma->dma_enable_bit |= ATI_REG_CMD_SPDF_OUT_EN; 1390 1391 /* and for input */ 1392 sc->sc_input_dma->linkptr = ATI_REG_IN_DMA_LINKPTR; 1393 sc->sc_input_dma->dma_enable_bit = ATI_REG_CMD_IN_DMA_EN | 1394 ATI_REG_CMD_RECEIVE_EN; 1395 1396 /* done! now enable all interrupts we can service */ 1397 auixp_enable_interrupts(sc); 1398 } 1399 1400 void 1401 auixp_enable_interrupts(struct auixp_softc *sc) 1402 { 1403 bus_space_tag_t iot; 1404 bus_space_handle_t ioh; 1405 u_int32_t value; 1406 1407 iot = sc->sc_iot; 1408 ioh = sc->sc_ioh; 1409 /* clear all pending */ 1410 bus_space_write_4(iot, ioh, ATI_REG_ISR, 0xffffffff); 1411 1412 /* enable all relevant interrupt sources we can handle */ 1413 value = bus_space_read_4(iot, ioh, ATI_REG_IER); 1414 1415 value |= ATI_REG_IER_IO_STATUS_EN; 1416 #ifdef notyet 1417 value |= ATI_REG_IER_IN_XRUN_EN; 1418 value |= ATI_REG_IER_OUT_XRUN_EN; 1419 1420 value |= ATI_REG_IER_SPDIF_XRUN_EN; 1421 value |= ATI_REG_IER_SPDF_STATUS_EN; 1422 #endif 1423 1424 bus_space_write_4(iot, ioh, ATI_REG_IER, value); 1425 } 1426 1427 void 1428 auixp_disable_interrupts(struct auixp_softc *sc) 1429 { 1430 bus_space_tag_t iot; 1431 bus_space_handle_t ioh; 1432 1433 iot = sc->sc_iot; 1434 ioh = sc->sc_ioh; 1435 /* disable all interrupt sources */ 1436 bus_space_write_4(iot, ioh, ATI_REG_IER, 0); 1437 1438 /* clear all pending */ 1439 bus_space_write_4(iot, ioh, ATI_REG_ISR, 0xffffffff); 1440 } 1441 1442 /* dismantle what we've set up by undoing setup */ 1443 int 1444 auixp_detach(struct device *self, int flags) 1445 { 1446 struct auixp_softc *sc; 1447 1448 sc = (struct auixp_softc *)self; 1449 /* XXX shouldn't we just reset the chip? XXX */ 1450 /* 1451 * should we explicitly disable interrupt generation and acknowledge 1452 * what's left on? better be safe than sorry. 1453 */ 1454 auixp_disable_interrupts(sc); 1455 1456 /* tear down .... */ 1457 config_detach(&sc->sc_dev, flags); /* XXX OK? XXX */ 1458 1459 if (sc->sc_ih != NULL) 1460 pci_intr_disestablish(sc->sc_pct, sc->sc_ih); 1461 if (sc->sc_ios) 1462 bus_space_unmap(sc->sc_iot, sc->sc_ioh, sc->sc_ios); 1463 return 0; 1464 } 1465 1466 1467 /* 1468 * codec handling 1469 * 1470 * IXP audio support can have upto 3 codecs! are they chained ? or 1471 * alternative outlets with the same audio feed i.e. with different mixer 1472 * settings? XXX does NetBSD support more than one audio codec? XXX 1473 */ 1474 1475 1476 int 1477 auixp_attach_codec(void *aux, struct ac97_codec_if *codec_if) 1478 { 1479 struct auixp_codec *ixp_codec; 1480 1481 ixp_codec = aux; 1482 ixp_codec->codec_if = codec_if; 1483 1484 return 0; 1485 } 1486 1487 int 1488 auixp_read_codec(void *aux, u_int8_t reg, u_int16_t *result) 1489 { 1490 struct auixp_codec *co; 1491 struct auixp_softc *sc; 1492 bus_space_tag_t iot; 1493 bus_space_handle_t ioh; 1494 u_int32_t data; 1495 int timeout; 1496 1497 co = aux; 1498 sc = co->sc; 1499 iot = sc->sc_iot; 1500 ioh = sc->sc_ioh; 1501 if (auixp_wait_for_codecs(sc, "read_codec")) 1502 return 0xffff; 1503 1504 /* build up command for reading codec register */ 1505 data = (reg << ATI_REG_PHYS_OUT_ADDR_SHIFT) | 1506 ATI_REG_PHYS_OUT_ADDR_EN | 1507 ATI_REG_PHYS_OUT_RW | 1508 co->codec_nr; 1509 1510 bus_space_write_4(iot, ioh, ATI_REG_PHYS_OUT_ADDR, data); 1511 1512 if (auixp_wait_for_codecs(sc, "read_codec")) 1513 return 0xffff; 1514 1515 /* wait until codec info is clocked in */ 1516 timeout = 500; /* 500*2 usec -> 0.001 sec */ 1517 do { 1518 data = bus_space_read_4(iot, ioh, ATI_REG_PHYS_IN_ADDR); 1519 if (data & ATI_REG_PHYS_IN_READ_FLAG) { 1520 DPRINTF(("read ac'97 codec reg 0x%x = 0x%08x\n", 1521 reg, data >> ATI_REG_PHYS_IN_DATA_SHIFT)); 1522 *result = data >> ATI_REG_PHYS_IN_DATA_SHIFT; 1523 return 0; 1524 } 1525 DELAY(2); 1526 timeout--; 1527 } while (timeout > 0); 1528 1529 if (reg < 0x7c) 1530 printf("%s: codec read timeout! (reg %x)\n", 1531 sc->sc_dev.dv_xname, reg); 1532 1533 return 0xffff; 1534 } 1535 1536 int 1537 auixp_write_codec(void *aux, u_int8_t reg, u_int16_t data) 1538 { 1539 struct auixp_codec *co; 1540 struct auixp_softc *sc; 1541 bus_space_tag_t iot; 1542 bus_space_handle_t ioh; 1543 u_int32_t value; 1544 1545 DPRINTF(("write ac'97 codec reg 0x%x = 0x%08x\n", reg, data)); 1546 co = aux; 1547 sc = co->sc; 1548 iot = sc->sc_iot; 1549 ioh = sc->sc_ioh; 1550 if (auixp_wait_for_codecs(sc, "write_codec")) 1551 return -1; 1552 1553 /* build up command for writing codec register */ 1554 value = (((u_int32_t) data) << ATI_REG_PHYS_OUT_DATA_SHIFT) | 1555 (((u_int32_t) reg) << ATI_REG_PHYS_OUT_ADDR_SHIFT) | 1556 ATI_REG_PHYS_OUT_ADDR_EN | 1557 co->codec_nr; 1558 1559 bus_space_write_4(iot, ioh, ATI_REG_PHYS_OUT_ADDR, value); 1560 1561 return 0; 1562 } 1563 1564 void 1565 auixp_reset_codec(void *aux) 1566 { 1567 1568 /* nothing to be done? */ 1569 } 1570 1571 enum ac97_host_flags 1572 auixp_flags_codec(void *aux) 1573 { 1574 struct auixp_codec *ixp_codec; 1575 1576 ixp_codec = aux; 1577 return ixp_codec->codec_flags; 1578 } 1579 1580 int 1581 auixp_wait_for_codecs(struct auixp_softc *sc, const char *func) 1582 { 1583 bus_space_tag_t iot; 1584 bus_space_handle_t ioh; 1585 u_int32_t value; 1586 int timeout; 1587 1588 iot = sc->sc_iot; 1589 ioh = sc->sc_ioh; 1590 /* wait until all codec transfers are done */ 1591 timeout = 500; /* 500*2 usec -> 0.001 sec */ 1592 do { 1593 value = bus_space_read_4(iot, ioh, ATI_REG_PHYS_OUT_ADDR); 1594 if ((value & ATI_REG_PHYS_OUT_ADDR_EN) == 0) 1595 return 0; 1596 1597 DELAY(2); 1598 timeout--; 1599 } while (timeout > 0); 1600 1601 printf("%s: %s: timed out\n", func, sc->sc_dev.dv_xname); 1602 return -1; 1603 } 1604 1605 void 1606 auixp_autodetect_codecs(struct auixp_softc *sc) 1607 { 1608 bus_space_tag_t iot; 1609 bus_space_handle_t ioh; 1610 pcireg_t subdev; 1611 struct auixp_codec *codec; 1612 int timeout; 1613 1614 iot = sc->sc_iot; 1615 ioh = sc->sc_ioh; 1616 subdev = pci_conf_read(sc->sc_pct, sc->sc_tag, PCI_SUBSYS_ID_REG); 1617 1618 /* ATI IXP can have upto 3 codecs; mark all codecs as not existing */ 1619 sc->sc_codec_not_ready_bits = 0; 1620 1621 /* enable all codecs to interrupt as well as the new frame interrupt */ 1622 bus_space_write_4(iot, ioh, ATI_REG_IER, CODEC_CHECK_BITS); 1623 1624 /* wait for the interrupts to happen */ 1625 timeout = 100; /* 100.000 usec -> 0.1 sec */ 1626 1627 while (timeout > 0) { 1628 DELAY(1000); 1629 if (sc->sc_codec_not_ready_bits) 1630 break; 1631 timeout--; 1632 } 1633 1634 if (timeout == 0) 1635 printf("%s: WARNING: timeout during codec detection; " 1636 "codecs might be present but haven't interrupted\n", 1637 sc->sc_dev.dv_xname); 1638 1639 /* disable all interrupts for now */ 1640 auixp_disable_interrupts(sc); 1641 1642 /* Attach AC97 host interfaces */ 1643 codec = &sc->sc_codec; 1644 bzero(codec, sizeof(struct auixp_codec)); 1645 1646 codec->sc = sc; 1647 1648 codec->host_if.arg = codec; 1649 codec->host_if.attach = auixp_attach_codec; 1650 codec->host_if.read = auixp_read_codec; 1651 codec->host_if.write = auixp_write_codec; 1652 codec->host_if.reset = auixp_reset_codec; 1653 codec->host_if.flags = auixp_flags_codec; 1654 switch (subdev) { 1655 case 0x1311462: /* MSI S270 */ 1656 case 0x1611462: /* LG K1 Express */ 1657 case 0x3511462: /* MSI L725 */ 1658 case 0x4711462: /* MSI L720 */ 1659 case 0x0611462: /* MSI S250 */ 1660 codec->codec_flags = AC97_HOST_ALC650_PIN47_IS_EAPD; 1661 break; 1662 } 1663 1664 if (!(sc->sc_codec_not_ready_bits & ATI_REG_ISR_CODEC0_NOT_READY)) { 1665 /* codec 0 present */ 1666 DPRINTF(("auixp : YAY! codec 0 present!\n")); 1667 if (ac97_attach(&sc->sc_codec.host_if) == 0) { 1668 sc->sc_codec.codec_nr = 0; 1669 sc->sc_codec.present = 1; 1670 return; 1671 } 1672 } 1673 1674 if (!(sc->sc_codec_not_ready_bits & ATI_REG_ISR_CODEC1_NOT_READY)) { 1675 /* codec 1 present */ 1676 DPRINTF(("auixp : YAY! codec 1 present!\n")); 1677 if (ac97_attach(&sc->sc_codec.host_if) == 0) { 1678 sc->sc_codec.codec_nr = 1; 1679 sc->sc_codec.present = 1; 1680 return; 1681 } 1682 } 1683 1684 if (!(sc->sc_codec_not_ready_bits & ATI_REG_ISR_CODEC2_NOT_READY)) { 1685 /* codec 2 present */ 1686 DPRINTF(("auixp : YAY! codec 2 present!\n")); 1687 if (ac97_attach(&sc->sc_codec.host_if) == 0) { 1688 sc->sc_codec.codec_nr = 2; 1689 sc->sc_codec.present = 1; 1690 return; 1691 } 1692 } 1693 } 1694 1695 void 1696 auixp_disable_dma(struct auixp_softc *sc, struct auixp_dma *dma) 1697 { 1698 bus_space_tag_t iot; 1699 bus_space_handle_t ioh; 1700 u_int32_t value; 1701 1702 iot = sc->sc_iot; 1703 ioh = sc->sc_ioh; 1704 /* lets not stress the DMA engine more than necessary */ 1705 value = bus_space_read_4(iot, ioh, ATI_REG_CMD); 1706 if (value & dma->dma_enable_bit) { 1707 value &= ~dma->dma_enable_bit; 1708 bus_space_write_4(iot, ioh, ATI_REG_CMD, value); 1709 } 1710 } 1711 1712 void 1713 auixp_enable_dma(struct auixp_softc *sc, struct auixp_dma *dma) 1714 { 1715 bus_space_tag_t iot; 1716 bus_space_handle_t ioh; 1717 u_int32_t value; 1718 1719 iot = sc->sc_iot; 1720 ioh = sc->sc_ioh; 1721 /* lets not stress the DMA engine more than necesssary */ 1722 value = bus_space_read_4(iot, ioh, ATI_REG_CMD); 1723 if (!(value & dma->dma_enable_bit)) { 1724 value |= dma->dma_enable_bit; 1725 bus_space_write_4(iot, ioh, ATI_REG_CMD, value); 1726 } 1727 } 1728 1729 void 1730 auixp_reset_aclink(struct auixp_softc *sc) 1731 { 1732 bus_space_tag_t iot; 1733 bus_space_handle_t ioh; 1734 u_int32_t value, timeout; 1735 1736 iot = sc->sc_iot; 1737 ioh = sc->sc_ioh; 1738 1739 /* if power is down, power it up */ 1740 value = bus_space_read_4(iot, ioh, ATI_REG_CMD); 1741 if (value & ATI_REG_CMD_POWERDOWN) { 1742 printf("%s: powering up\n", sc->sc_dev.dv_xname); 1743 1744 /* explicitly enable power */ 1745 value &= ~ATI_REG_CMD_POWERDOWN; 1746 bus_space_write_4(iot, ioh, ATI_REG_CMD, value); 1747 1748 /* have to wait at least 10 usec for it to initialise */ 1749 DELAY(20); 1750 }; 1751 1752 printf("%s: soft resetting aclink\n", sc->sc_dev.dv_xname); 1753 1754 /* perform a soft reset */ 1755 value = bus_space_read_4(iot, ioh, ATI_REG_CMD); 1756 value |= ATI_REG_CMD_AC_SOFT_RESET; 1757 bus_space_write_4(iot, ioh, ATI_REG_CMD, value); 1758 1759 /* need to read the CMD reg and wait aprox. 10 usec to init */ 1760 value = bus_space_read_4(iot, ioh, ATI_REG_CMD); 1761 DELAY(20); 1762 1763 /* clear soft reset flag again */ 1764 value = bus_space_read_4(iot, ioh, ATI_REG_CMD); 1765 value &= ~ATI_REG_CMD_AC_SOFT_RESET; 1766 bus_space_write_4(iot, ioh, ATI_REG_CMD, value); 1767 1768 /* check if the ac-link is working; reset device otherwise */ 1769 timeout = 10; 1770 value = bus_space_read_4(iot, ioh, ATI_REG_CMD); 1771 while (!(value & ATI_REG_CMD_ACLINK_ACTIVE)) { 1772 printf("%s: not up; resetting aclink hardware\n", 1773 sc->sc_dev.dv_xname); 1774 1775 /* dip aclink reset but keep the acsync */ 1776 value &= ~ATI_REG_CMD_AC_RESET; 1777 value |= ATI_REG_CMD_AC_SYNC; 1778 bus_space_write_4(iot, ioh, ATI_REG_CMD, value); 1779 1780 /* need to read CMD again and wait again (clocking in issue?) */ 1781 value = bus_space_read_4(iot, ioh, ATI_REG_CMD); 1782 DELAY(20); 1783 1784 /* assert aclink reset again */ 1785 value = bus_space_read_4(iot, ioh, ATI_REG_CMD); 1786 value |= ATI_REG_CMD_AC_RESET; 1787 bus_space_write_4(iot, ioh, ATI_REG_CMD, value); 1788 1789 /* check if its active now */ 1790 value = bus_space_read_4(iot, ioh, ATI_REG_CMD); 1791 1792 timeout--; 1793 if (timeout == 0) break; 1794 }; 1795 1796 if (timeout == 0) { 1797 printf("%s: giving up aclink reset\n", sc->sc_dev.dv_xname); 1798 }; 1799 if (timeout != 10) { 1800 printf("%s: aclink hardware reset successful\n", 1801 sc->sc_dev.dv_xname); 1802 }; 1803 1804 /* assert reset and sync for safety */ 1805 value = bus_space_read_4(iot, ioh, ATI_REG_CMD); 1806 value |= ATI_REG_CMD_AC_SYNC | ATI_REG_CMD_AC_RESET; 1807 bus_space_write_4(iot, ioh, ATI_REG_CMD, value); 1808 } 1809 1810 /* chip hard init */ 1811 int 1812 auixp_init(struct auixp_softc *sc) 1813 { 1814 bus_space_tag_t iot; 1815 bus_space_handle_t ioh; 1816 u_int32_t value; 1817 1818 iot = sc->sc_iot; 1819 ioh = sc->sc_ioh; 1820 /* disable all interrupts and clear all sources */ 1821 auixp_disable_interrupts(sc); 1822 1823 /* clear all DMA enables (preserving rest of settings) */ 1824 value = bus_space_read_4(iot, ioh, ATI_REG_CMD); 1825 value &= ~( ATI_REG_CMD_IN_DMA_EN | 1826 ATI_REG_CMD_OUT_DMA_EN | 1827 ATI_REG_CMD_SPDF_OUT_EN ); 1828 bus_space_write_4(iot, ioh, ATI_REG_CMD, value); 1829 1830 /* Reset AC-link */ 1831 auixp_reset_aclink(sc); 1832 1833 /* 1834 * codecs get auto-detected later 1835 * 1836 * note: we are NOT enabling interrupts yet, no codecs have been 1837 * detected yet nor is anything else set up 1838 */ 1839 1840 return 0; 1841 } 1842