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