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