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