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