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