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