1 /* $OpenBSD: auixp.c,v 1.42 2020/01/24 03:29:55 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/param.h> 54 #include <sys/errno.h> 55 #include <sys/systm.h> 56 #include <sys/malloc.h> 57 #include <sys/device.h> 58 #include <sys/conf.h> 59 #include <sys/exec.h> 60 #include <sys/selinfo.h> 61 #include <sys/audioio.h> 62 #include <sys/queue.h> 63 64 #include <machine/bus.h> 65 66 #include <dev/pci/pcidevs.h> 67 #include <dev/pci/pcivar.h> 68 69 #include <dev/audio_if.h> 70 #include <dev/ic/ac97.h> 71 72 #include <dev/pci/auixpreg.h> 73 #include <dev/pci/auixpvar.h> 74 75 /* codec detection constant indicating the interrupt flags */ 76 #define ALL_CODECS_NOT_READY \ 77 (ATI_REG_ISR_CODEC0_NOT_READY | ATI_REG_ISR_CODEC1_NOT_READY |\ 78 ATI_REG_ISR_CODEC2_NOT_READY) 79 #define CODEC_CHECK_BITS (ALL_CODECS_NOT_READY|ATI_REG_ISR_NEW_FRAME) 80 81 /* why isn't this base address register not in the headerfile? */ 82 #define PCI_CBIO 0x10 83 84 /* macro's used */ 85 #define KERNADDR(p) ((void *)((p)->addr)) 86 #define DMAADDR(p) ((p)->map->dm_segs[0].ds_addr) 87 88 const struct pci_matchid auixp_pci_devices[] = { 89 { PCI_VENDOR_ATI, PCI_PRODUCT_ATI_SB200_AUDIO }, 90 { PCI_VENDOR_ATI, PCI_PRODUCT_ATI_SB300_AUDIO }, 91 { PCI_VENDOR_ATI, PCI_PRODUCT_ATI_SB400_AUDIO }, 92 { PCI_VENDOR_ATI, PCI_PRODUCT_ATI_SB600_AUDIO } 93 }; 94 95 struct cfdriver auixp_cd = { 96 NULL, "auixp", DV_DULL 97 }; 98 99 int auixp_match( struct device *, void *, void *); 100 void auixp_attach(struct device *, struct device *, void *); 101 int auixp_detach(struct device *, int); 102 103 int auixp_activate(struct device *, int); 104 105 struct cfattach auixp_ca = { 106 sizeof(struct auixp_softc), auixp_match, auixp_attach, 107 NULL, auixp_activate 108 }; 109 110 int auixp_open(void *v, int flags); 111 void auixp_close(void *v); 112 int auixp_set_params(void *, int, int, struct audio_params *, 113 struct audio_params *); 114 int auixp_commit_settings(void *); 115 int auixp_round_blocksize(void *, int); 116 int auixp_trigger_output(void *, void *, void *, int, 117 void (*)(void *), void *, struct audio_params *); 118 int auixp_trigger_input(void *, void *, void *, int, 119 void (*)(void *), void *, struct audio_params *); 120 int auixp_halt_output(void *); 121 int auixp_halt_input(void *); 122 int auixp_set_port(void *, mixer_ctrl_t *); 123 int auixp_get_port(void *, mixer_ctrl_t *); 124 int auixp_query_devinfo(void *, mixer_devinfo_t *); 125 void * auixp_malloc(void *, int, size_t, int, int); 126 void auixp_free(void *, void *, int); 127 int auixp_get_props(void *); 128 int auixp_intr(void *); 129 int auixp_allocmem(struct auixp_softc *, size_t, size_t, 130 struct auixp_dma *); 131 int auixp_freemem(struct auixp_softc *, struct auixp_dma *); 132 133 /* Supporting subroutines */ 134 int auixp_init(struct auixp_softc *); 135 void auixp_autodetect_codecs(struct auixp_softc *); 136 void auixp_post_config(struct device *); 137 138 void auixp_reset_aclink(struct auixp_softc *); 139 int auixp_attach_codec(void *, struct ac97_codec_if *); 140 int auixp_read_codec(void *, u_int8_t, u_int16_t *); 141 int auixp_write_codec(void *, u_int8_t, u_int16_t); 142 int auixp_wait_for_codecs(struct auixp_softc *, const char *); 143 void auixp_reset_codec(void *); 144 enum ac97_host_flags auixp_flags_codec(void *); 145 146 void auixp_enable_dma(struct auixp_softc *, struct auixp_dma *); 147 void auixp_disable_dma(struct auixp_softc *, struct auixp_dma *); 148 void auixp_enable_interrupts(struct auixp_softc *); 149 void auixp_disable_interrupts(struct auixp_softc *); 150 151 void auixp_link_daisychain(struct auixp_softc *, 152 struct auixp_dma *, struct auixp_dma *, int, int); 153 int auixp_allocate_dma_chain(struct auixp_softc *, struct auixp_dma **); 154 void auixp_program_dma_chain(struct auixp_softc *, struct auixp_dma *); 155 void auixp_dma_update(struct auixp_softc *, struct auixp_dma *); 156 void auixp_update_busbusy(struct auixp_softc *); 157 158 #ifdef DEBUG_AUIXP 159 #define DPRINTF(x) printf x; 160 #else 161 #define DPRINTF(x) 162 #endif 163 164 struct audio_hw_if auixp_hw_if = { 165 auixp_open, 166 auixp_close, 167 auixp_set_params, 168 auixp_round_blocksize, 169 auixp_commit_settings, 170 NULL, /* init_output */ 171 NULL, /* init_input */ 172 NULL, /* start_output */ 173 NULL, /* start_input */ 174 auixp_halt_output, 175 auixp_halt_input, 176 NULL, /* speaker_ctl */ 177 NULL, /* getfd */ 178 auixp_set_port, 179 auixp_get_port, 180 auixp_query_devinfo, 181 auixp_malloc, 182 auixp_free, 183 NULL, /* round_buffersize */ 184 auixp_get_props, 185 auixp_trigger_output, 186 auixp_trigger_input 187 }; 188 189 int 190 auixp_open(void *v, int flags) 191 { 192 193 return 0; 194 } 195 196 void 197 auixp_close(void *v) 198 { 199 } 200 201 /* commit setting and program ATI IXP chip */ 202 int 203 auixp_commit_settings(void *hdl) 204 { 205 struct auixp_codec *co; 206 struct auixp_softc *sc; 207 bus_space_tag_t iot; 208 bus_space_handle_t ioh; 209 struct audio_params *params; 210 u_int32_t value; 211 212 /* XXX would it be better to stop interrupts first? XXX */ 213 co = (struct auixp_codec *) hdl; 214 sc = co->sc; 215 iot = sc->sc_iot; 216 ioh = sc->sc_ioh; 217 218 /* process input settings */ 219 params = &sc->sc_play_params; 220 221 /* set input interleaving (precision) */ 222 value = bus_space_read_4(iot, ioh, ATI_REG_CMD); 223 value &= ~ATI_REG_CMD_INTERLEAVE_IN; 224 if (params->precision <= 16) 225 value |= ATI_REG_CMD_INTERLEAVE_IN; 226 bus_space_write_4(iot, ioh, ATI_REG_CMD, value); 227 228 /* process output settings */ 229 params = &sc->sc_play_params; 230 231 value = bus_space_read_4(iot, ioh, ATI_REG_OUT_DMA_SLOT); 232 value &= ~ATI_REG_OUT_DMA_SLOT_MASK; 233 234 /* TODO SPDIF case for 8 channels */ 235 switch (params->channels) { 236 case 6: 237 value |= ATI_REG_OUT_DMA_SLOT_BIT(7) | 238 ATI_REG_OUT_DMA_SLOT_BIT(8); 239 /* FALLTHROUGH */ 240 case 4: 241 value |= ATI_REG_OUT_DMA_SLOT_BIT(6) | 242 ATI_REG_OUT_DMA_SLOT_BIT(9); 243 /* FALLTHROUGH */ 244 default: 245 value |= ATI_REG_OUT_DMA_SLOT_BIT(3) | 246 ATI_REG_OUT_DMA_SLOT_BIT(4); 247 break; 248 } 249 /* set output threshold */ 250 value |= 0x04 << ATI_REG_OUT_DMA_THRESHOLD_SHIFT; 251 bus_space_write_4(iot, ioh, ATI_REG_OUT_DMA_SLOT, value); 252 253 /* set output interleaving (precision) */ 254 value = bus_space_read_4(iot, ioh, ATI_REG_CMD); 255 value &= ~ATI_REG_CMD_INTERLEAVE_OUT; 256 if (params->precision <= 16) 257 value |= ATI_REG_CMD_INTERLEAVE_OUT; 258 bus_space_write_4(iot, ioh, ATI_REG_CMD, value); 259 260 /* enable 6 channel reordering */ 261 value = bus_space_read_4(iot, ioh, ATI_REG_6CH_REORDER); 262 value &= ~ATI_REG_6CH_REORDER_EN; 263 if (params->channels == 6) 264 value |= ATI_REG_6CH_REORDER_EN; 265 bus_space_write_4(iot, ioh, ATI_REG_6CH_REORDER, value); 266 267 if (sc->has_spdif) { 268 /* set SPDIF (if present) */ 269 value = bus_space_read_4(iot, ioh, ATI_REG_CMD); 270 value &= ~ATI_REG_CMD_SPDF_CONFIG_MASK; 271 value |= ATI_REG_CMD_SPDF_CONFIG_34; /* NetBSD AC'97 default */ 272 273 /* XXX this is probably not necessary unless splitted XXX */ 274 value &= ~ATI_REG_CMD_INTERLEAVE_SPDF; 275 if (params->precision <= 16) 276 value |= ATI_REG_CMD_INTERLEAVE_SPDF; 277 bus_space_write_4(iot, ioh, ATI_REG_CMD, value); 278 } 279 280 return 0; 281 } 282 283 284 /* set audio properties in desired setting */ 285 int 286 auixp_set_params(void *hdl, int setmode, int usemode, 287 struct audio_params *play, struct audio_params *rec) 288 { 289 struct auixp_codec *co; 290 int error; 291 u_int temprate; 292 293 co = (struct auixp_codec *) hdl; 294 if (setmode & AUMODE_PLAY) { 295 play->channels = 2; 296 play->precision = 16; 297 switch(play->encoding) { 298 case AUDIO_ENCODING_SLINEAR_LE: 299 break; 300 default: 301 return (EINVAL); 302 } 303 play->bps = AUDIO_BPS(play->precision); 304 play->msb = 1; 305 306 temprate = play->sample_rate; 307 error = ac97_set_rate(co->codec_if, 308 AC97_REG_PCM_LFE_DAC_RATE, &play->sample_rate); 309 if (error) 310 return (error); 311 312 play->sample_rate = temprate; 313 error = ac97_set_rate(co->codec_if, 314 AC97_REG_PCM_SURR_DAC_RATE, &play->sample_rate); 315 if (error) 316 return (error); 317 318 play->sample_rate = temprate; 319 error = ac97_set_rate(co->codec_if, 320 AC97_REG_PCM_FRONT_DAC_RATE, &play->sample_rate); 321 if (error) 322 return (error); 323 324 } 325 326 if (setmode & AUMODE_RECORD) { 327 rec->channels = 2; 328 rec->precision = 16; 329 switch(rec->encoding) { 330 case AUDIO_ENCODING_SLINEAR_LE: 331 break; 332 default: 333 return (EINVAL); 334 } 335 rec->bps = AUDIO_BPS(rec->precision); 336 rec->msb = 1; 337 338 error = ac97_set_rate(co->codec_if, AC97_REG_PCM_LR_ADC_RATE, 339 &rec->sample_rate); 340 if (error) 341 return (error); 342 } 343 344 return (0); 345 } 346 347 348 /* called to translate a requested blocksize to a hw-possible one */ 349 int 350 auixp_round_blocksize(void *v, int blk) 351 { 352 353 blk = (blk + 0x1f) & ~0x1f; 354 /* Be conservative; align to 32 bytes and maximise it to 64 kb */ 355 if (blk > 0x10000) 356 blk = 0x10000; 357 358 return blk; 359 } 360 361 362 /* 363 * allocate dma capable memory and record its information for later retrieval 364 * when we program the dma chain itself. The trigger routines passes on the 365 * kernel virtual address we return here as a reference to the mapping. 366 */ 367 void * 368 auixp_malloc(void *hdl, int direction, size_t size, int pool, int flags) 369 { 370 struct auixp_codec *co; 371 struct auixp_softc *sc; 372 struct auixp_dma *dma; 373 int error; 374 375 co = (struct auixp_codec *) hdl; 376 sc = co->sc; 377 /* get us a auixp_dma structure */ 378 dma = malloc(sizeof(*dma), pool, flags); 379 if (!dma) 380 return NULL; 381 382 /* get us a dma buffer itself */ 383 error = auixp_allocmem(sc, size, 16, dma); 384 if (error) { 385 free(dma, pool, sizeof(*dma)); 386 printf("%s: auixp_malloc: not enough memory\n", 387 sc->sc_dev.dv_xname); 388 return NULL; 389 } 390 SLIST_INSERT_HEAD(&sc->sc_dma_list, dma, dma_chain); 391 392 DPRINTF(("auixp_malloc: returning kern %p, hw 0x%08x for %d bytes " 393 "in %d segs\n", KERNADDR(dma), (u_int32_t) DMAADDR(dma), dma->size, 394 dma->nsegs) 395 ); 396 397 return KERNADDR(dma); 398 } 399 400 /* 401 * free and release dma capable memory we allocated before and remove its 402 * recording 403 */ 404 void 405 auixp_free(void *hdl, void *addr, int pool) 406 { 407 struct auixp_codec *co; 408 struct auixp_softc *sc; 409 struct auixp_dma *dma; 410 411 co = (struct auixp_codec *) hdl; 412 sc = co->sc; 413 SLIST_FOREACH(dma, &sc->sc_dma_list, dma_chain) { 414 if (KERNADDR(dma) == addr) { 415 SLIST_REMOVE(&sc->sc_dma_list, dma, auixp_dma, 416 dma_chain); 417 auixp_freemem(sc, dma); 418 free(dma, pool, sizeof(*dma)); 419 return; 420 } 421 } 422 } 423 424 /* pass request to AC'97 codec code */ 425 int 426 auixp_set_port(void *hdl, mixer_ctrl_t *mc) 427 { 428 struct auixp_codec *co; 429 430 co = (struct auixp_codec *) hdl; 431 return co->codec_if->vtbl->mixer_set_port(co->codec_if, mc); 432 } 433 434 435 /* pass request to AC'97 codec code */ 436 int 437 auixp_get_port(void *hdl, mixer_ctrl_t *mc) 438 { 439 struct auixp_codec *co; 440 441 co = (struct auixp_codec *) hdl; 442 return co->codec_if->vtbl->mixer_get_port(co->codec_if, mc); 443 } 444 445 /* pass request to AC'97 codec code */ 446 int 447 auixp_query_devinfo(void *hdl, mixer_devinfo_t *di) 448 { 449 struct auixp_codec *co; 450 451 co = (struct auixp_codec *) hdl; 452 return co->codec_if->vtbl->query_devinfo(co->codec_if, di); 453 } 454 455 int 456 auixp_get_props(void *hdl) 457 { 458 459 return AUDIO_PROP_MMAP | AUDIO_PROP_INDEPENDENT | AUDIO_PROP_FULLDUPLEX; 460 } 461 462 463 /* 464 * A dma descriptor has dma->nsegs segments defined in dma->segs set up when 465 * we claimed the memory. 466 * 467 * Due to our demand for one contiguous DMA area, we only have one segment. A 468 * c_dma structure is about 3 kb for the 256 entries we maximally program 469 * -arbitrary limit AFAIK- so all is most likely to be in one segment/page 470 * anyway. 471 * 472 * XXX ought to implement fragmented dma area XXX 473 * 474 * Note that _v variables depict kernel virtual addresses, _p variables depict 475 * physical addresses. 476 */ 477 void 478 auixp_link_daisychain(struct auixp_softc *sc, 479 struct auixp_dma *c_dma, struct auixp_dma *s_dma, 480 int blksize, int blocks) 481 { 482 atiixp_dma_desc_t *caddr_v, *next_caddr_v; 483 u_int32_t caddr_p, next_caddr_p, saddr_p; 484 int i; 485 486 /* just make sure we are not changing when its running */ 487 auixp_disable_dma(sc, c_dma); 488 489 /* setup dma chain start addresses */ 490 caddr_v = KERNADDR(c_dma); 491 caddr_p = DMAADDR(c_dma); 492 saddr_p = DMAADDR(s_dma); 493 494 /* program the requested number of blocks */ 495 for (i = 0; i < blocks; i++) { 496 /* clear the block just in case */ 497 bzero(caddr_v, sizeof(atiixp_dma_desc_t)); 498 499 /* round robin the chain dma addresses for its successor */ 500 next_caddr_v = caddr_v + 1; 501 next_caddr_p = caddr_p + sizeof(atiixp_dma_desc_t); 502 503 if (i == blocks-1) { 504 next_caddr_v = KERNADDR(c_dma); 505 next_caddr_p = DMAADDR(c_dma); 506 } 507 508 /* fill in the hardware dma chain descriptor in little-endian */ 509 caddr_v->addr = htole32(saddr_p); 510 caddr_v->status = htole16(0); 511 caddr_v->size = htole16((blksize >> 2)); /* in dwords (!!!) */ 512 caddr_v->next = htole32(next_caddr_p); 513 514 /* advance slot */ 515 saddr_p += blksize; /* XXX assuming contiguous XXX */ 516 caddr_v = next_caddr_v; 517 caddr_p = next_caddr_p; 518 } 519 } 520 521 522 int 523 auixp_allocate_dma_chain(struct auixp_softc *sc, struct auixp_dma **dmap) 524 { 525 struct auixp_dma *dma; 526 int error; 527 528 /* allocate keeper of dma area */ 529 *dmap = NULL; 530 dma = malloc(sizeof(*dma), M_DEVBUF, M_NOWAIT | M_ZERO); 531 if (!dma) 532 return ENOMEM; 533 534 /* allocate for daisychain of IXP hardware-dma descriptors */ 535 error = auixp_allocmem(sc, DMA_DESC_CHAIN * sizeof(atiixp_dma_desc_t), 536 16, dma); 537 if (error) { 538 printf("%s: can't malloc dma descriptor chain\n", 539 sc->sc_dev.dv_xname); 540 free(dma, M_DEVBUF, sizeof(*dma)); 541 return ENOMEM; 542 } 543 544 /* return info and initialise structure */ 545 dma->intr = NULL; 546 dma->intrarg = NULL; 547 548 *dmap = dma; 549 return 0; 550 } 551 552 553 /* program dma chain in its link address descriptor */ 554 void 555 auixp_program_dma_chain(struct auixp_softc *sc, struct auixp_dma *dma) 556 { 557 bus_space_tag_t iot; 558 bus_space_handle_t ioh; 559 u_int32_t value; 560 561 iot = sc->sc_iot; 562 ioh = sc->sc_ioh; 563 /* get hardware start address of DMA chain and set valid-flag in it */ 564 /* XXX always at start? XXX */ 565 value = DMAADDR(dma); 566 value = value | ATI_REG_LINKPTR_EN; 567 568 /* reset linkpointer */ 569 bus_space_write_4(iot, ioh, dma->linkptr, 0); 570 571 /* reset this DMA engine */ 572 auixp_disable_dma(sc, dma); 573 auixp_enable_dma(sc, dma); 574 575 /* program new DMA linkpointer */ 576 bus_space_write_4(iot, ioh, dma->linkptr, value); 577 } 578 579 580 /* called from interrupt code to signal end of one dma-slot */ 581 void 582 auixp_dma_update(struct auixp_softc *sc, struct auixp_dma *dma) 583 { 584 585 /* be very paranoid */ 586 if (!dma) 587 panic("auixp: update: dma = NULL"); 588 if (!dma->intr) 589 panic("auixp: update: dma->intr = NULL"); 590 591 /* request more input from upper layer */ 592 (*dma->intr)(dma->intrarg); 593 } 594 595 596 /* 597 * The magic `busbusy' bit that needs to be set when dma is active; allowing 598 * busmastering? 599 */ 600 void 601 auixp_update_busbusy(struct auixp_softc *sc) 602 { 603 bus_space_tag_t iot; 604 bus_space_handle_t ioh; 605 u_int32_t value; 606 int running; 607 608 iot = sc->sc_iot; 609 ioh = sc->sc_ioh; 610 /* set bus-busy flag when either recording or playing is performed */ 611 value = bus_space_read_4(iot, ioh, ATI_REG_IER); 612 value &= ~ATI_REG_IER_SET_BUS_BUSY; 613 614 running = ((sc->sc_output_dma->running) || (sc->sc_input_dma->running)); 615 if (running) 616 value |= ATI_REG_IER_SET_BUS_BUSY; 617 618 bus_space_write_4(iot, ioh, ATI_REG_IER, value); 619 620 } 621 622 623 /* 624 * Called from upper audio layer to request playing audio, only called once; 625 * audio is refilled by calling the intr() function when space is available 626 * again. 627 */ 628 /* XXX almost literally a copy of trigger-input; could be factorised XXX */ 629 int 630 auixp_trigger_output(void *hdl, void *start, void *end, int blksize, 631 void (*intr)(void *), void *intrarg, struct audio_params *param) 632 { 633 struct auixp_codec *co; 634 struct auixp_softc *sc; 635 struct auixp_dma *chain_dma; 636 struct auixp_dma *sound_dma; 637 u_int32_t blocks; 638 639 co = (struct auixp_codec *) hdl; 640 sc = co->sc; 641 chain_dma = sc->sc_output_dma; 642 /* add functions to call back */ 643 chain_dma->intr = intr; 644 chain_dma->intrarg = intrarg; 645 646 /* 647 * Program output DMA chain with blocks from [start...end] with 648 * blksize fragments. 649 * 650 * NOTE, we can assume its in one block since we asked for it to be in 651 * one contiguous blob; XXX change this? XXX 652 */ 653 blocks = (size_t) (((caddr_t) end) - ((caddr_t) start)) / blksize; 654 655 /* lookup `start' address in our list of DMA area's */ 656 SLIST_FOREACH(sound_dma, &sc->sc_dma_list, dma_chain) { 657 if (KERNADDR(sound_dma) == start) 658 break; 659 } 660 661 /* not ours ? then bail out */ 662 if (!sound_dma) { 663 printf("%s: auixp_trigger_output: bad sound addr %p\n", 664 sc->sc_dev.dv_xname, start); 665 return EINVAL; 666 } 667 668 /* link round-robin daisychain and program hardware */ 669 auixp_link_daisychain(sc, chain_dma, sound_dma, blksize, blocks); 670 auixp_program_dma_chain(sc, chain_dma); 671 672 /* mark we are now able to run now */ 673 mtx_enter(&audio_lock); 674 chain_dma->running = 1; 675 676 /* update bus-flags; XXX programs more flags XXX */ 677 auixp_update_busbusy(sc); 678 mtx_leave(&audio_lock); 679 680 /* callbacks happen in interrupt routine */ 681 return 0; 682 } 683 684 685 /* halt output of audio, just disable its dma and update bus state */ 686 int 687 auixp_halt_output(void *hdl) 688 { 689 struct auixp_codec *co; 690 struct auixp_softc *sc; 691 struct auixp_dma *dma; 692 693 mtx_enter(&audio_lock); 694 co = (struct auixp_codec *) hdl; 695 sc = co->sc; 696 dma = sc->sc_output_dma; 697 auixp_disable_dma(sc, dma); 698 699 dma->running = 0; 700 auixp_update_busbusy(sc); 701 mtx_leave(&audio_lock); 702 return 0; 703 } 704 705 706 /* XXX almost literally a copy of trigger-output; could be factorised XXX */ 707 int 708 auixp_trigger_input(void *hdl, void *start, void *end, int blksize, 709 void (*intr)(void *), void *intrarg, struct audio_params *param) 710 { 711 struct auixp_codec *co; 712 struct auixp_softc *sc; 713 struct auixp_dma *chain_dma; 714 struct auixp_dma *sound_dma; 715 u_int32_t blocks; 716 717 co = (struct auixp_codec *) hdl; 718 sc = co->sc; 719 chain_dma = sc->sc_input_dma; 720 /* add functions to call back */ 721 chain_dma->intr = intr; 722 chain_dma->intrarg = intrarg; 723 724 /* 725 * Program output DMA chain with blocks from [start...end] with 726 * blksize fragments. 727 * 728 * NOTE, we can assume its in one block since we asked for it to be in 729 * one contiguous blob; XXX change this? XXX 730 */ 731 blocks = (size_t) (((caddr_t) end) - ((caddr_t) start)) / blksize; 732 733 /* lookup `start' address in our list of DMA area's */ 734 SLIST_FOREACH(sound_dma, &sc->sc_dma_list, dma_chain) { 735 if (KERNADDR(sound_dma) == start) 736 break; 737 } 738 739 /* not ours ? then bail out */ 740 if (!sound_dma) { 741 printf("%s: auixp_trigger_input: bad sound addr %p\n", 742 sc->sc_dev.dv_xname, start); 743 return EINVAL; 744 } 745 746 /* link round-robin daisychain and program hardware */ 747 auixp_link_daisychain(sc, chain_dma, sound_dma, blksize, blocks); 748 auixp_program_dma_chain(sc, chain_dma); 749 750 /* mark we are now able to run now */ 751 mtx_enter(&audio_lock); 752 chain_dma->running = 1; 753 754 /* update bus-flags; XXX programs more flags XXX */ 755 auixp_update_busbusy(sc); 756 mtx_leave(&audio_lock); 757 758 /* callbacks happen in interrupt routine */ 759 return 0; 760 } 761 762 763 /* halt sampling audio, just disable its dma and update bus state */ 764 int 765 auixp_halt_input(void *hdl) 766 { 767 struct auixp_codec *co; 768 struct auixp_softc *sc; 769 struct auixp_dma *dma; 770 771 mtx_enter(&audio_lock); 772 co = (struct auixp_codec *) hdl; 773 sc = co->sc; 774 dma = sc->sc_input_dma; 775 auixp_disable_dma(sc, dma); 776 777 dma->running = 0; 778 auixp_update_busbusy(sc); 779 780 mtx_leave(&audio_lock); 781 return 0; 782 } 783 784 785 /* 786 * IXP audio interrupt handler 787 * 788 * note that we return the number of bits handled; the return value is not 789 * documented but I saw it implemented in other drivers. Probably returning a 790 * value > 0 means "I've dealt with it" 791 * 792 */ 793 int 794 auixp_intr(void *softc) 795 { 796 struct auixp_softc *sc; 797 bus_space_tag_t iot; 798 bus_space_handle_t ioh; 799 u_int32_t status, enable, detected_codecs; 800 int ret; 801 802 mtx_enter(&audio_lock); 803 sc = softc; 804 iot = sc->sc_iot; 805 ioh = sc->sc_ioh; 806 ret = 0; 807 /* get status from the interrupt status register */ 808 status = bus_space_read_4(iot, ioh, ATI_REG_ISR); 809 810 if (status == 0) { 811 mtx_leave(&audio_lock); 812 return 0; 813 } 814 815 DPRINTF(("%s: (status = %x)\n", sc->sc_dev.dv_xname, status)); 816 817 /* check DMA UPDATE flags for input & output */ 818 if (status & ATI_REG_ISR_IN_STATUS) { 819 ret++; DPRINTF(("IN_STATUS\n")); 820 auixp_dma_update(sc, sc->sc_input_dma); 821 } 822 if (status & ATI_REG_ISR_OUT_STATUS) { 823 ret++; DPRINTF(("OUT_STATUS\n")); 824 auixp_dma_update(sc, sc->sc_output_dma); 825 } 826 827 /* XXX XRUN flags not used/needed yet; should i implement it? XXX */ 828 /* acknowledge the interrupts nevertheless */ 829 if (status & ATI_REG_ISR_IN_XRUN) { 830 ret++; DPRINTF(("IN_XRUN\n")); 831 /* auixp_dma_xrun(sc, sc->sc_input_dma); */ 832 } 833 if (status & ATI_REG_ISR_OUT_XRUN) { 834 ret++; DPRINTF(("OUT_XRUN\n")); 835 /* auixp_dma_xrun(sc, sc->sc_output_dma); */ 836 } 837 838 /* check if we are looking for codec detection */ 839 if (status & CODEC_CHECK_BITS) { 840 ret++; 841 /* mark missing codecs as not ready */ 842 detected_codecs = status & CODEC_CHECK_BITS; 843 sc->sc_codec_not_ready_bits |= detected_codecs; 844 845 /* disable detected interrupt sources */ 846 enable = bus_space_read_4(iot, ioh, ATI_REG_IER); 847 enable &= ~detected_codecs; 848 bus_space_write_4(iot, ioh, ATI_REG_IER, enable); 849 } 850 851 /* acknowledge interrupt sources */ 852 bus_space_write_4(iot, ioh, ATI_REG_ISR, status); 853 mtx_leave(&audio_lock); 854 return ret; 855 } 856 857 858 /* allocate memory for dma purposes; on failure of any of the steps, roll back */ 859 int 860 auixp_allocmem(struct auixp_softc *sc, size_t size, 861 size_t align, struct auixp_dma *dma) 862 { 863 int error; 864 865 /* remember size */ 866 dma->size = size; 867 868 /* allocate DMA safe memory but in just one segment for now :( */ 869 error = bus_dmamem_alloc(sc->sc_dmat, dma->size, align, 0, 870 dma->segs, sizeof(dma->segs) / sizeof(dma->segs[0]), &dma->nsegs, 871 BUS_DMA_NOWAIT); 872 if (error) 873 return error; 874 875 /* 876 * map allocated memory into kernel virtual address space and keep it 877 * coherent with the CPU. 878 */ 879 error = bus_dmamem_map(sc->sc_dmat, dma->segs, dma->nsegs, dma->size, 880 &dma->addr, BUS_DMA_NOWAIT | BUS_DMA_COHERENT); 881 if (error) 882 goto free; 883 884 /* allocate associated dma handle and initialize it. */ 885 error = bus_dmamap_create(sc->sc_dmat, dma->size, 1, dma->size, 0, 886 BUS_DMA_NOWAIT, &dma->map); 887 if (error) 888 goto unmap; 889 890 /* 891 * load the dma handle with mappings for a dma transfer; all pages 892 * need to be wired. 893 */ 894 error = bus_dmamap_load(sc->sc_dmat, dma->map, dma->addr, dma->size, NULL, 895 BUS_DMA_NOWAIT); 896 if (error) 897 goto destroy; 898 899 return 0; 900 901 destroy: 902 bus_dmamap_destroy(sc->sc_dmat, dma->map); 903 unmap: 904 bus_dmamem_unmap(sc->sc_dmat, dma->addr, dma->size); 905 free: 906 bus_dmamem_free(sc->sc_dmat, dma->segs, dma->nsegs); 907 908 return error; 909 } 910 911 912 /* undo dma mapping and release memory allocated */ 913 int 914 auixp_freemem(struct auixp_softc *sc, struct auixp_dma *p) 915 { 916 917 bus_dmamap_unload(sc->sc_dmat, p->map); 918 bus_dmamap_destroy(sc->sc_dmat, p->map); 919 bus_dmamem_unmap(sc->sc_dmat, p->addr, p->size); 920 bus_dmamem_free(sc->sc_dmat, p->segs, p->nsegs); 921 922 return 0; 923 } 924 925 int 926 auixp_match(struct device *dev, void *match, void *aux) 927 { 928 return (pci_matchbyid((struct pci_attach_args *)aux, auixp_pci_devices, 929 sizeof(auixp_pci_devices)/sizeof(auixp_pci_devices[0]))); 930 } 931 932 int 933 auixp_activate(struct device *self, int act) 934 { 935 struct auixp_softc *sc = (struct auixp_softc *)self; 936 int rv = 0; 937 938 switch (act) { 939 case DVACT_SUSPEND: 940 auixp_disable_interrupts(sc); 941 break; 942 case DVACT_RESUME: 943 auixp_init(sc); 944 ac97_resume(&sc->sc_codec.host_if, sc->sc_codec.codec_if); 945 rv = config_activate_children(self, act); 946 break; 947 default: 948 rv = config_activate_children(self, act); 949 break; 950 } 951 return (rv); 952 } 953 954 void 955 auixp_attach(struct device *parent, struct device *self, void *aux) 956 { 957 struct auixp_softc *sc; 958 struct pci_attach_args *pa; 959 pcitag_t tag; 960 pci_chipset_tag_t pc; 961 pci_intr_handle_t ih; 962 const char *intrstr; 963 964 sc = (struct auixp_softc *)self; 965 pa = (struct pci_attach_args *)aux; 966 tag = pa->pa_tag; 967 pc = pa->pa_pc; 968 969 /* map memory; its not sized -> what is the size? max PCI slot size? */ 970 if (pci_mapreg_map(pa, PCI_CBIO, PCI_MAPREG_TYPE_MEM, 0, 971 &sc->sc_iot, &sc->sc_ioh, &sc->sc_iob, &sc->sc_ios, 0)) { 972 printf(": can't map mem space\n"); 973 return; 974 } 975 976 /* Initialize softc */ 977 sc->sc_tag = tag; 978 sc->sc_pct = pc; 979 sc->sc_dmat = pa->pa_dmat; 980 SLIST_INIT(&sc->sc_dma_list); 981 982 /* get us the auixp_dma structures */ 983 auixp_allocate_dma_chain(sc, &sc->sc_output_dma); 984 auixp_allocate_dma_chain(sc, &sc->sc_input_dma); 985 986 /* when that fails we are dead in the water */ 987 if (!sc->sc_output_dma || !sc->sc_input_dma) 988 return; 989 990 #if 0 991 /* could preliminary program DMA chain */ 992 auixp_program_dma_chain(sc, sc->sc_output_dma); 993 auixp_program_dma_chain(sc, sc->sc_input_dma); 994 #endif 995 996 if (pci_intr_map(pa, &ih)) { 997 printf(": can't map interrupt\n"); 998 return; 999 } 1000 intrstr = pci_intr_string(pc, ih); 1001 sc->sc_ih = pci_intr_establish(pc, ih, IPL_AUDIO | IPL_MPSAFE, 1002 auixp_intr, sc, sc->sc_dev.dv_xname); 1003 if (sc->sc_ih == NULL) { 1004 printf(": can't establish interrupt"); 1005 if (intrstr != NULL) 1006 printf(" at %s", intrstr); 1007 printf("\n"); 1008 return; 1009 } 1010 printf(": %s\n", intrstr); 1011 1012 /* power up chip */ 1013 pci_set_powerstate(pc, tag, PCI_PMCSR_STATE_D0); 1014 1015 /* init chip */ 1016 if (auixp_init(sc) == -1) { 1017 printf("%s: auixp_attach: unable to initialize the card\n", 1018 sc->sc_dev.dv_xname); 1019 return; 1020 } 1021 1022 /* 1023 * delay further configuration of codecs and audio after interrupts 1024 * are enabled. 1025 */ 1026 config_mountroot(self, auixp_post_config); 1027 } 1028 1029 /* called from autoconfigure system when interrupts are enabled */ 1030 void 1031 auixp_post_config(struct device *self) 1032 { 1033 struct auixp_softc *sc = (struct auixp_softc *)self; 1034 1035 /* detect the AC97 codecs */ 1036 auixp_autodetect_codecs(sc); 1037 1038 /* Bail if no codecs attached. */ 1039 if (!sc->sc_codec.present) { 1040 printf("%s: no codecs detected or initialised\n", 1041 sc->sc_dev.dv_xname); 1042 return; 1043 } 1044 1045 audio_attach_mi(&auixp_hw_if, &sc->sc_codec, &sc->sc_dev); 1046 1047 if (sc->has_spdif) 1048 sc->has_spdif = 0; 1049 1050 /* fill in the missing details about the dma channels. */ 1051 /* for output */ 1052 sc->sc_output_dma->linkptr = ATI_REG_OUT_DMA_LINKPTR; 1053 sc->sc_output_dma->dma_enable_bit = ATI_REG_CMD_OUT_DMA_EN | 1054 ATI_REG_CMD_SEND_EN; 1055 /* have spdif? then this too! XXX not seeing LED yet! XXX */ 1056 if (sc->has_spdif) 1057 sc->sc_output_dma->dma_enable_bit |= ATI_REG_CMD_SPDF_OUT_EN; 1058 1059 /* and for input */ 1060 sc->sc_input_dma->linkptr = ATI_REG_IN_DMA_LINKPTR; 1061 sc->sc_input_dma->dma_enable_bit = ATI_REG_CMD_IN_DMA_EN | 1062 ATI_REG_CMD_RECEIVE_EN; 1063 1064 /* done! now enable all interrupts we can service */ 1065 auixp_enable_interrupts(sc); 1066 } 1067 1068 void 1069 auixp_enable_interrupts(struct auixp_softc *sc) 1070 { 1071 bus_space_tag_t iot; 1072 bus_space_handle_t ioh; 1073 u_int32_t value; 1074 1075 iot = sc->sc_iot; 1076 ioh = sc->sc_ioh; 1077 /* clear all pending */ 1078 bus_space_write_4(iot, ioh, ATI_REG_ISR, 0xffffffff); 1079 1080 /* enable all relevant interrupt sources we can handle */ 1081 value = bus_space_read_4(iot, ioh, ATI_REG_IER); 1082 1083 value |= ATI_REG_IER_IO_STATUS_EN; 1084 1085 bus_space_write_4(iot, ioh, ATI_REG_IER, value); 1086 } 1087 1088 void 1089 auixp_disable_interrupts(struct auixp_softc *sc) 1090 { 1091 bus_space_tag_t iot; 1092 bus_space_handle_t ioh; 1093 1094 iot = sc->sc_iot; 1095 ioh = sc->sc_ioh; 1096 /* disable all interrupt sources */ 1097 bus_space_write_4(iot, ioh, ATI_REG_IER, 0); 1098 1099 /* clear all pending */ 1100 bus_space_write_4(iot, ioh, ATI_REG_ISR, 0xffffffff); 1101 } 1102 1103 /* dismantle what we've set up by undoing setup */ 1104 int 1105 auixp_detach(struct device *self, int flags) 1106 { 1107 struct auixp_softc *sc; 1108 1109 sc = (struct auixp_softc *)self; 1110 /* XXX shouldn't we just reset the chip? XXX */ 1111 /* 1112 * should we explicitly disable interrupt generation and acknowledge 1113 * what's left on? better be safe than sorry. 1114 */ 1115 auixp_disable_interrupts(sc); 1116 1117 /* tear down .... */ 1118 config_detach(&sc->sc_dev, flags); /* XXX OK? XXX */ 1119 1120 if (sc->sc_ih != NULL) 1121 pci_intr_disestablish(sc->sc_pct, sc->sc_ih); 1122 if (sc->sc_ios) 1123 bus_space_unmap(sc->sc_iot, sc->sc_ioh, sc->sc_ios); 1124 return 0; 1125 } 1126 1127 1128 /* 1129 * codec handling 1130 * 1131 * IXP audio support can have upto 3 codecs! are they chained ? or 1132 * alternative outlets with the same audio feed i.e. with different mixer 1133 * settings? XXX does NetBSD support more than one audio codec? XXX 1134 */ 1135 1136 1137 int 1138 auixp_attach_codec(void *aux, struct ac97_codec_if *codec_if) 1139 { 1140 struct auixp_codec *ixp_codec; 1141 1142 ixp_codec = aux; 1143 ixp_codec->codec_if = codec_if; 1144 1145 return 0; 1146 } 1147 1148 int 1149 auixp_read_codec(void *aux, u_int8_t reg, u_int16_t *result) 1150 { 1151 struct auixp_codec *co; 1152 struct auixp_softc *sc; 1153 bus_space_tag_t iot; 1154 bus_space_handle_t ioh; 1155 u_int32_t data; 1156 int timeout; 1157 1158 co = aux; 1159 sc = co->sc; 1160 iot = sc->sc_iot; 1161 ioh = sc->sc_ioh; 1162 if (auixp_wait_for_codecs(sc, "read_codec")) 1163 return 0xffff; 1164 1165 /* build up command for reading codec register */ 1166 data = (reg << ATI_REG_PHYS_OUT_ADDR_SHIFT) | 1167 ATI_REG_PHYS_OUT_ADDR_EN | 1168 ATI_REG_PHYS_OUT_RW | 1169 co->codec_nr; 1170 1171 bus_space_write_4(iot, ioh, ATI_REG_PHYS_OUT_ADDR, data); 1172 1173 if (auixp_wait_for_codecs(sc, "read_codec")) 1174 return 0xffff; 1175 1176 /* wait until codec info is clocked in */ 1177 timeout = 500; /* 500*2 usec -> 0.001 sec */ 1178 do { 1179 data = bus_space_read_4(iot, ioh, ATI_REG_PHYS_IN_ADDR); 1180 if (data & ATI_REG_PHYS_IN_READ_FLAG) { 1181 DPRINTF(("read ac'97 codec reg 0x%x = 0x%08x\n", 1182 reg, data >> ATI_REG_PHYS_IN_DATA_SHIFT)); 1183 *result = data >> ATI_REG_PHYS_IN_DATA_SHIFT; 1184 return 0; 1185 } 1186 DELAY(2); 1187 timeout--; 1188 } while (timeout > 0); 1189 1190 if (reg < 0x7c) 1191 printf("%s: codec read timeout! (reg %x)\n", 1192 sc->sc_dev.dv_xname, reg); 1193 1194 return 0xffff; 1195 } 1196 1197 int 1198 auixp_write_codec(void *aux, u_int8_t reg, u_int16_t data) 1199 { 1200 struct auixp_codec *co; 1201 struct auixp_softc *sc; 1202 bus_space_tag_t iot; 1203 bus_space_handle_t ioh; 1204 u_int32_t value; 1205 1206 DPRINTF(("write ac'97 codec reg 0x%x = 0x%08x\n", reg, data)); 1207 co = aux; 1208 sc = co->sc; 1209 iot = sc->sc_iot; 1210 ioh = sc->sc_ioh; 1211 if (auixp_wait_for_codecs(sc, "write_codec")) 1212 return -1; 1213 1214 /* build up command for writing codec register */ 1215 value = (((u_int32_t) data) << ATI_REG_PHYS_OUT_DATA_SHIFT) | 1216 (((u_int32_t) reg) << ATI_REG_PHYS_OUT_ADDR_SHIFT) | 1217 ATI_REG_PHYS_OUT_ADDR_EN | 1218 co->codec_nr; 1219 1220 bus_space_write_4(iot, ioh, ATI_REG_PHYS_OUT_ADDR, value); 1221 1222 return 0; 1223 } 1224 1225 void 1226 auixp_reset_codec(void *aux) 1227 { 1228 1229 /* nothing to be done? */ 1230 } 1231 1232 enum ac97_host_flags 1233 auixp_flags_codec(void *aux) 1234 { 1235 struct auixp_codec *ixp_codec; 1236 1237 ixp_codec = aux; 1238 return ixp_codec->codec_flags; 1239 } 1240 1241 int 1242 auixp_wait_for_codecs(struct auixp_softc *sc, const char *func) 1243 { 1244 bus_space_tag_t iot; 1245 bus_space_handle_t ioh; 1246 u_int32_t value; 1247 int timeout; 1248 1249 iot = sc->sc_iot; 1250 ioh = sc->sc_ioh; 1251 /* wait until all codec transfers are done */ 1252 timeout = 500; /* 500*2 usec -> 0.001 sec */ 1253 do { 1254 value = bus_space_read_4(iot, ioh, ATI_REG_PHYS_OUT_ADDR); 1255 if ((value & ATI_REG_PHYS_OUT_ADDR_EN) == 0) 1256 return 0; 1257 1258 DELAY(2); 1259 timeout--; 1260 } while (timeout > 0); 1261 1262 printf("%s: %s: timed out\n", func, sc->sc_dev.dv_xname); 1263 return -1; 1264 } 1265 1266 void 1267 auixp_autodetect_codecs(struct auixp_softc *sc) 1268 { 1269 bus_space_tag_t iot; 1270 bus_space_handle_t ioh; 1271 pcireg_t subdev; 1272 struct auixp_codec *codec; 1273 int timeout; 1274 1275 iot = sc->sc_iot; 1276 ioh = sc->sc_ioh; 1277 subdev = pci_conf_read(sc->sc_pct, sc->sc_tag, PCI_SUBSYS_ID_REG); 1278 1279 /* ATI IXP can have upto 3 codecs; mark all codecs as not existing */ 1280 sc->sc_codec_not_ready_bits = 0; 1281 1282 /* enable all codecs to interrupt as well as the new frame interrupt */ 1283 bus_space_write_4(iot, ioh, ATI_REG_IER, CODEC_CHECK_BITS); 1284 1285 /* wait for the interrupts to happen */ 1286 timeout = 100; /* 100.000 usec -> 0.1 sec */ 1287 1288 while (timeout > 0) { 1289 DELAY(1000); 1290 if (sc->sc_codec_not_ready_bits) 1291 break; 1292 timeout--; 1293 } 1294 1295 if (timeout == 0) 1296 printf("%s: WARNING: timeout during codec detection; " 1297 "codecs might be present but haven't interrupted\n", 1298 sc->sc_dev.dv_xname); 1299 1300 /* disable all interrupts for now */ 1301 auixp_disable_interrupts(sc); 1302 1303 /* Attach AC97 host interfaces */ 1304 codec = &sc->sc_codec; 1305 bzero(codec, sizeof(struct auixp_codec)); 1306 1307 codec->sc = sc; 1308 1309 codec->host_if.arg = codec; 1310 codec->host_if.attach = auixp_attach_codec; 1311 codec->host_if.read = auixp_read_codec; 1312 codec->host_if.write = auixp_write_codec; 1313 codec->host_if.reset = auixp_reset_codec; 1314 codec->host_if.flags = auixp_flags_codec; 1315 switch (subdev) { 1316 case 0x1311462: /* MSI S270 */ 1317 case 0x1611462: /* LG K1 Express */ 1318 case 0x3511462: /* MSI L725 */ 1319 case 0x4711462: /* MSI L720 */ 1320 case 0x0611462: /* MSI S250 */ 1321 codec->codec_flags = AC97_HOST_ALC650_PIN47_IS_EAPD; 1322 break; 1323 } 1324 1325 if (!(sc->sc_codec_not_ready_bits & ATI_REG_ISR_CODEC0_NOT_READY)) { 1326 /* codec 0 present */ 1327 DPRINTF(("auixp : YAY! codec 0 present!\n")); 1328 if (ac97_attach(&sc->sc_codec.host_if) == 0) { 1329 sc->sc_codec.codec_nr = 0; 1330 sc->sc_codec.present = 1; 1331 return; 1332 } 1333 } 1334 1335 if (!(sc->sc_codec_not_ready_bits & ATI_REG_ISR_CODEC1_NOT_READY)) { 1336 /* codec 1 present */ 1337 DPRINTF(("auixp : YAY! codec 1 present!\n")); 1338 if (ac97_attach(&sc->sc_codec.host_if) == 0) { 1339 sc->sc_codec.codec_nr = 1; 1340 sc->sc_codec.present = 1; 1341 return; 1342 } 1343 } 1344 1345 if (!(sc->sc_codec_not_ready_bits & ATI_REG_ISR_CODEC2_NOT_READY)) { 1346 /* codec 2 present */ 1347 DPRINTF(("auixp : YAY! codec 2 present!\n")); 1348 if (ac97_attach(&sc->sc_codec.host_if) == 0) { 1349 sc->sc_codec.codec_nr = 2; 1350 sc->sc_codec.present = 1; 1351 return; 1352 } 1353 } 1354 } 1355 1356 void 1357 auixp_disable_dma(struct auixp_softc *sc, struct auixp_dma *dma) 1358 { 1359 bus_space_tag_t iot; 1360 bus_space_handle_t ioh; 1361 u_int32_t value; 1362 1363 iot = sc->sc_iot; 1364 ioh = sc->sc_ioh; 1365 /* lets not stress the DMA engine more than necessary */ 1366 value = bus_space_read_4(iot, ioh, ATI_REG_CMD); 1367 if (value & dma->dma_enable_bit) { 1368 value &= ~dma->dma_enable_bit; 1369 bus_space_write_4(iot, ioh, ATI_REG_CMD, value); 1370 } 1371 } 1372 1373 void 1374 auixp_enable_dma(struct auixp_softc *sc, struct auixp_dma *dma) 1375 { 1376 bus_space_tag_t iot; 1377 bus_space_handle_t ioh; 1378 u_int32_t value; 1379 1380 iot = sc->sc_iot; 1381 ioh = sc->sc_ioh; 1382 /* lets not stress the DMA engine more than necesssary */ 1383 value = bus_space_read_4(iot, ioh, ATI_REG_CMD); 1384 if (!(value & dma->dma_enable_bit)) { 1385 value |= dma->dma_enable_bit; 1386 bus_space_write_4(iot, ioh, ATI_REG_CMD, value); 1387 } 1388 } 1389 1390 void 1391 auixp_reset_aclink(struct auixp_softc *sc) 1392 { 1393 bus_space_tag_t iot; 1394 bus_space_handle_t ioh; 1395 u_int32_t value, timeout; 1396 1397 iot = sc->sc_iot; 1398 ioh = sc->sc_ioh; 1399 1400 /* if power is down, power it up */ 1401 value = bus_space_read_4(iot, ioh, ATI_REG_CMD); 1402 if (value & ATI_REG_CMD_POWERDOWN) { 1403 printf("%s: powering up\n", sc->sc_dev.dv_xname); 1404 1405 /* explicitly enable power */ 1406 value &= ~ATI_REG_CMD_POWERDOWN; 1407 bus_space_write_4(iot, ioh, ATI_REG_CMD, value); 1408 1409 /* have to wait at least 10 usec for it to initialise */ 1410 DELAY(20); 1411 }; 1412 1413 printf("%s: soft resetting aclink\n", sc->sc_dev.dv_xname); 1414 1415 /* perform a soft reset */ 1416 value = bus_space_read_4(iot, ioh, ATI_REG_CMD); 1417 value |= ATI_REG_CMD_AC_SOFT_RESET; 1418 bus_space_write_4(iot, ioh, ATI_REG_CMD, value); 1419 1420 /* need to read the CMD reg and wait aprox. 10 usec to init */ 1421 value = bus_space_read_4(iot, ioh, ATI_REG_CMD); 1422 DELAY(20); 1423 1424 /* clear soft reset flag again */ 1425 value = bus_space_read_4(iot, ioh, ATI_REG_CMD); 1426 value &= ~ATI_REG_CMD_AC_SOFT_RESET; 1427 bus_space_write_4(iot, ioh, ATI_REG_CMD, value); 1428 1429 /* check if the ac-link is working; reset device otherwise */ 1430 timeout = 10; 1431 value = bus_space_read_4(iot, ioh, ATI_REG_CMD); 1432 while (!(value & ATI_REG_CMD_ACLINK_ACTIVE)) { 1433 printf("%s: not up; resetting aclink hardware\n", 1434 sc->sc_dev.dv_xname); 1435 1436 /* dip aclink reset but keep the acsync */ 1437 value &= ~ATI_REG_CMD_AC_RESET; 1438 value |= ATI_REG_CMD_AC_SYNC; 1439 bus_space_write_4(iot, ioh, ATI_REG_CMD, value); 1440 1441 /* need to read CMD again and wait again (clocking in issue?) */ 1442 value = bus_space_read_4(iot, ioh, ATI_REG_CMD); 1443 DELAY(20); 1444 1445 /* assert aclink reset again */ 1446 value = bus_space_read_4(iot, ioh, ATI_REG_CMD); 1447 value |= ATI_REG_CMD_AC_RESET; 1448 bus_space_write_4(iot, ioh, ATI_REG_CMD, value); 1449 1450 /* check if its active now */ 1451 value = bus_space_read_4(iot, ioh, ATI_REG_CMD); 1452 1453 timeout--; 1454 if (timeout == 0) break; 1455 }; 1456 1457 if (timeout == 0) { 1458 printf("%s: giving up aclink reset\n", sc->sc_dev.dv_xname); 1459 }; 1460 if (timeout != 10) { 1461 printf("%s: aclink hardware reset successful\n", 1462 sc->sc_dev.dv_xname); 1463 }; 1464 1465 /* assert reset and sync for safety */ 1466 value = bus_space_read_4(iot, ioh, ATI_REG_CMD); 1467 value |= ATI_REG_CMD_AC_SYNC | ATI_REG_CMD_AC_RESET; 1468 bus_space_write_4(iot, ioh, ATI_REG_CMD, value); 1469 } 1470 1471 /* chip hard init */ 1472 int 1473 auixp_init(struct auixp_softc *sc) 1474 { 1475 bus_space_tag_t iot; 1476 bus_space_handle_t ioh; 1477 u_int32_t value; 1478 1479 iot = sc->sc_iot; 1480 ioh = sc->sc_ioh; 1481 /* disable all interrupts and clear all sources */ 1482 auixp_disable_interrupts(sc); 1483 1484 /* clear all DMA enables (preserving rest of settings) */ 1485 value = bus_space_read_4(iot, ioh, ATI_REG_CMD); 1486 value &= ~( ATI_REG_CMD_IN_DMA_EN | 1487 ATI_REG_CMD_OUT_DMA_EN | 1488 ATI_REG_CMD_SPDF_OUT_EN ); 1489 bus_space_write_4(iot, ioh, ATI_REG_CMD, value); 1490 1491 /* Reset AC-link */ 1492 auixp_reset_aclink(sc); 1493 1494 /* 1495 * codecs get auto-detected later 1496 * 1497 * note: we are NOT enabling interrupts yet, no codecs have been 1498 * detected yet nor is anything else set up 1499 */ 1500 1501 return 0; 1502 } 1503