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