1 /* $OpenBSD: auvia.c,v 1.49 2011/07/03 15:47:16 matthew Exp $ */ 2 /* $NetBSD: auvia.c,v 1.28 2002/11/04 16:38:49 kent Exp $ */ 3 4 /*- 5 * Copyright (c) 2000 The NetBSD Foundation, Inc. 6 * All rights reserved. 7 * 8 * This code is derived from software contributed to The NetBSD Foundation 9 * by Tyler C. Sarna 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions and the following disclaimer. 16 * 2. Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in the 18 * documentation and/or other materials provided with the distribution. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 30 * POSSIBILITY OF SUCH DAMAGE. 31 */ 32 33 /* 34 * VIA Technologies VT82C686A Southbridge Audio Driver 35 * 36 * Documentation links: 37 * 38 * ftp://ftp.alsa-project.org/pub/manuals/via/686a.pdf 39 */ 40 41 #include <sys/param.h> 42 #include <sys/systm.h> 43 #include <sys/malloc.h> 44 #include <sys/device.h> 45 #include <sys/audioio.h> 46 47 #include <dev/pci/pcidevs.h> 48 #include <dev/pci/pcivar.h> 49 50 #include <dev/audio_if.h> 51 #include <dev/mulaw.h> 52 #include <dev/auconv.h> 53 54 #include <dev/ic/ac97.h> 55 56 #include <dev/pci/auviavar.h> 57 58 struct auvia_dma { 59 struct auvia_dma *next; 60 caddr_t addr; 61 size_t size; 62 bus_dmamap_t map; 63 bus_dma_segment_t seg; 64 }; 65 66 struct auvia_dma_op { 67 u_int32_t ptr; 68 u_int32_t flags; 69 #define AUVIA_DMAOP_EOL 0x80000000 70 #define AUVIA_DMAOP_FLAG 0x40000000 71 #define AUVIA_DMAOP_STOP 0x20000000 72 #define AUVIA_DMAOP_COUNT(x) ((x)&0x00FFFFFF) 73 }; 74 75 int auvia_match(struct device *, void *, void *); 76 void auvia_attach(struct device *, struct device *, void *); 77 int auvia_open(void *, int); 78 void auvia_close(void *); 79 int auvia_query_encoding(void *, struct audio_encoding *); 80 void auvia_set_params_sub(struct auvia_softc *, struct auvia_softc_chan *, 81 struct audio_params *); 82 int auvia_set_params(void *, int, int, struct audio_params *, 83 struct audio_params *); 84 void auvia_get_default_params(void *, int, struct audio_params *); 85 int auvia_round_blocksize(void *, int); 86 int auvia_halt_output(void *); 87 int auvia_halt_input(void *); 88 int auvia_getdev(void *, struct audio_device *); 89 int auvia_set_port(void *, mixer_ctrl_t *); 90 int auvia_get_port(void *, mixer_ctrl_t *); 91 int auvia_query_devinfo(void *, mixer_devinfo_t *); 92 void * auvia_malloc(void *, int, size_t, int, int); 93 void auvia_free(void *, void *, int); 94 size_t auvia_round_buffersize(void *, int, size_t); 95 paddr_t auvia_mappage(void *, void *, off_t, int); 96 int auvia_get_props(void *); 97 int auvia_build_dma_ops(struct auvia_softc *, struct auvia_softc_chan *, 98 struct auvia_dma *, void *, void *, int); 99 int auvia_trigger_output(void *, void *, void *, int, void (*)(void *), 100 void *, struct audio_params *); 101 int auvia_trigger_input(void *, void *, void *, int, void (*)(void *), 102 void *, struct audio_params *); 103 104 int auvia_intr(void *); 105 106 int auvia_activate(struct device *, int); 107 108 struct cfdriver auvia_cd = { 109 NULL, "auvia", DV_DULL 110 }; 111 112 struct cfattach auvia_ca = { 113 sizeof (struct auvia_softc), auvia_match, auvia_attach, 114 NULL, auvia_activate 115 }; 116 117 #define AUVIA_PCICONF_JUNK 0x40 118 #define AUVIA_PCICONF_ENABLES 0x00FF0000 /* reg 42 mask */ 119 #define AUVIA_PCICONF_ACLINKENAB 0x00008000 /* ac link enab */ 120 #define AUVIA_PCICONF_ACNOTRST 0x00004000 /* ~(ac reset) */ 121 #define AUVIA_PCICONF_ACSYNC 0x00002000 /* ac sync */ 122 #define AUVIA_PCICONF_ACVSR 0x00000800 /* var. samp. rate */ 123 #define AUVIA_PCICONF_ACSGD 0x00000400 /* SGD enab */ 124 #define AUVIA_PCICONF_ACFM 0x00000200 /* FM enab */ 125 #define AUVIA_PCICONF_ACSB 0x00000100 /* SB enab */ 126 #define AUVIA_PCICONF_PRIVALID 0x00000001 /* primary codec rdy */ 127 128 #define AUVIA_PLAY_BASE 0x00 129 #define AUVIA_RECORD_BASE 0x10 130 131 /* *_RP_* are offsets from AUVIA_PLAY_BASE or AUVIA_RECORD_BASE */ 132 #define AUVIA_RP_STAT 0x00 133 #define AUVIA_RPSTAT_INTR 0x03 134 #define AUVIA_RP_CONTROL 0x01 135 #define AUVIA_RPCTRL_START 0x80 136 #define AUVIA_RPCTRL_TERMINATE 0x40 137 #define AUVIA_RPCTRL_AUTOSTART 0x20 138 /* The following are 8233 specific */ 139 #define AUVIA_RPCTRL_STOP 0x04 140 #define AUVIA_RPCTRL_EOL 0x02 141 #define AUVIA_RPCTRL_FLAG 0x01 142 #define AUVIA_RP_MODE 0x02 /* 82c686 specific */ 143 #define AUVIA_RPMODE_INTR_FLAG 0x01 144 #define AUVIA_RPMODE_INTR_EOL 0x02 145 #define AUVIA_RPMODE_STEREO 0x10 146 #define AUVIA_RPMODE_16BIT 0x20 147 #define AUVIA_RPMODE_AUTOSTART 0x80 148 #define AUVIA_RP_DMAOPS_BASE 0x04 149 150 #define VIA8233_RP_DXS_LVOL 0x02 151 #define VIA8233_RP_DXS_RVOL 0x03 152 #define VIA8233_RP_RATEFMT 0x08 153 #define VIA8233_RATEFMT_48K 0xfffff 154 #define VIA8233_RATEFMT_STEREO 0x00100000 155 #define VIA8233_RATEFMT_16BIT 0x00200000 156 157 #define VIA_RP_DMAOPS_COUNT 0x0c 158 159 #define VIA8233_MP_BASE 0x40 160 /* STAT, CONTROL, DMAOPS_BASE, DMAOPS_COUNT are valid */ 161 #define VIA8233_OFF_MP_FORMAT 0x02 162 #define VIA8233_MP_FORMAT_8BIT 0x00 163 #define VIA8233_MP_FORMAT_16BIT 0x80 164 #define VIA8233_MP_FORMAT_CHANNLE_MASK 0x70 /* 1, 2, 4, 6 */ 165 #define VIA8233_OFF_MP_SCRATCH 0x03 166 #define VIA8233_OFF_MP_STOP 0x08 167 168 #define VIA8233_WR_BASE 0x60 169 170 #define AUVIA_CODEC_CTL 0x80 171 #define AUVIA_CODEC_READ 0x00800000 172 #define AUVIA_CODEC_BUSY 0x01000000 173 #define AUVIA_CODEC_PRIVALID 0x02000000 174 #define AUVIA_CODEC_INDEX(x) ((x)<<16) 175 176 #define CH_WRITE1(sc, ch, off, v) \ 177 bus_space_write_1((sc)->sc_iot, (sc)->sc_ioh, (ch)->sc_base + (off), v) 178 #define CH_WRITE4(sc, ch, off, v) \ 179 bus_space_write_4((sc)->sc_iot, (sc)->sc_ioh, (ch)->sc_base + (off), v) 180 #define CH_READ1(sc, ch, off) \ 181 bus_space_read_1((sc)->sc_iot, (sc)->sc_ioh, (ch)->sc_base + (off)) 182 #define CH_READ4(sc, ch, off) \ 183 bus_space_read_4((sc)->sc_iot, (sc)->sc_ioh, (ch)->sc_base + (off)) 184 185 #define TIMEOUT 50 186 187 struct audio_hw_if auvia_hw_if = { 188 auvia_open, 189 auvia_close, 190 NULL, /* drain */ 191 auvia_query_encoding, 192 auvia_set_params, 193 auvia_round_blocksize, 194 NULL, /* commit_settings */ 195 NULL, /* init_output */ 196 NULL, /* init_input */ 197 NULL, /* start_output */ 198 NULL, /* start_input */ 199 auvia_halt_output, 200 auvia_halt_input, 201 NULL, /* speaker_ctl */ 202 auvia_getdev, 203 NULL, /* setfd */ 204 auvia_set_port, 205 auvia_get_port, 206 auvia_query_devinfo, 207 auvia_malloc, 208 auvia_free, 209 auvia_round_buffersize, 210 auvia_mappage, 211 auvia_get_props, 212 auvia_trigger_output, 213 auvia_trigger_input, 214 auvia_get_default_params 215 }; 216 217 int auvia_attach_codec(void *, struct ac97_codec_if *); 218 int auvia_write_codec(void *, u_int8_t, u_int16_t); 219 int auvia_read_codec(void *, u_int8_t, u_int16_t *); 220 void auvia_reset_codec(void *); 221 int auvia_waitready_codec(struct auvia_softc *sc); 222 int auvia_waitvalid_codec(struct auvia_softc *sc); 223 void auvia_spdif_event(void *, int); 224 225 int auvia_resume(struct auvia_softc *); 226 227 const struct pci_matchid auvia_devices[] = { 228 { PCI_VENDOR_VIATECH, PCI_PRODUCT_VIATECH_VT82C686A_AC97 }, 229 { PCI_VENDOR_VIATECH, PCI_PRODUCT_VIATECH_VT8233_AC97 }, 230 }; 231 232 int 233 auvia_match(struct device *parent, void *match, void *aux) 234 { 235 return (pci_matchbyid((struct pci_attach_args *)aux, auvia_devices, 236 nitems(auvia_devices))); 237 } 238 239 int 240 auvia_activate(struct device *self, int act) 241 { 242 struct auvia_softc *sc = (struct auvia_softc *)self; 243 int rv = 0; 244 245 switch (act) { 246 case DVACT_QUIESCE: 247 rv = config_activate_children(self, act); 248 break; 249 case DVACT_SUSPEND: 250 break; 251 case DVACT_RESUME: 252 auvia_resume(sc); 253 rv = config_activate_children(self, act); 254 break; 255 case DVACT_DEACTIVATE: 256 break; 257 } 258 return (rv); 259 } 260 261 262 void 263 auvia_attach(struct device *parent, struct device *self, void *aux) 264 { 265 struct pci_attach_args *pa = aux; 266 struct auvia_softc *sc = (struct auvia_softc *) self; 267 const char *intrstr = NULL; 268 struct mixer_ctrl ctl; 269 pci_chipset_tag_t pc = pa->pa_pc; 270 pcitag_t pt = pa->pa_tag; 271 pci_intr_handle_t ih; 272 bus_size_t iosize; 273 pcireg_t pr; 274 int r, i; 275 276 sc->sc_play.sc_base = AUVIA_PLAY_BASE; 277 sc->sc_record.sc_base = AUVIA_RECORD_BASE; 278 if (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_VIATECH_VT8233_AC97) { 279 sc->sc_flags |= AUVIA_FLAGS_VT8233; 280 sc->sc_play.sc_base = VIA8233_MP_BASE; 281 sc->sc_record.sc_base = VIA8233_WR_BASE; 282 } 283 284 if (pci_mapreg_map(pa, 0x10, PCI_MAPREG_TYPE_IO, 0, &sc->sc_iot, 285 &sc->sc_ioh, NULL, &iosize, 0)) { 286 printf(": can't map i/o space\n"); 287 return; 288 } 289 290 sc->sc_dmat = pa->pa_dmat; 291 sc->sc_pc = pc; 292 sc->sc_pt = pt; 293 294 if (pci_intr_map(pa, &ih)) { 295 printf(": couldn't map interrupt\n"); 296 bus_space_unmap(sc->sc_iot, sc->sc_ioh, iosize); 297 return; 298 } 299 intrstr = pci_intr_string(pc, ih); 300 301 sc->sc_ih = pci_intr_establish(pc, ih, IPL_AUDIO, auvia_intr, sc, 302 sc->sc_dev.dv_xname); 303 if (sc->sc_ih == NULL) { 304 printf(": couldn't establish interrupt"); 305 if (intrstr != NULL) 306 printf(" at %s", intrstr); 307 printf("\n"); 308 bus_space_unmap(sc->sc_iot, sc->sc_ioh, iosize); 309 return; 310 } 311 312 printf(": %s\n", intrstr); 313 314 /* disable SBPro compat & others */ 315 pr = pci_conf_read(pc, pt, AUVIA_PCICONF_JUNK); 316 317 pr &= ~AUVIA_PCICONF_ENABLES; /* clear compat function enables */ 318 /* XXX what to do about MIDI, FM, joystick? */ 319 320 pr |= (AUVIA_PCICONF_ACLINKENAB | AUVIA_PCICONF_ACNOTRST | 321 AUVIA_PCICONF_ACVSR | AUVIA_PCICONF_ACSGD); 322 323 pr &= ~(AUVIA_PCICONF_ACFM | AUVIA_PCICONF_ACSB); 324 325 pci_conf_write(pc, pt, AUVIA_PCICONF_JUNK, pr); 326 sc->sc_pci_junk = pr; 327 328 sc->host_if.arg = sc; 329 sc->host_if.attach = auvia_attach_codec; 330 sc->host_if.read = auvia_read_codec; 331 sc->host_if.write = auvia_write_codec; 332 sc->host_if.reset = auvia_reset_codec; 333 sc->host_if.spdif_event = auvia_spdif_event; 334 335 if ((r = ac97_attach(&sc->host_if)) != 0) { 336 printf("%s: can't attach codec (error 0x%X)\n", 337 sc->sc_dev.dv_xname, r); 338 pci_intr_disestablish(pc, sc->sc_ih); 339 bus_space_unmap(sc->sc_iot, sc->sc_ioh, iosize); 340 return; 341 } 342 343 /* disable mutes */ 344 for (i = 0; i < 4; i++) { 345 static struct { 346 char *class, *device; 347 } d[] = { 348 { AudioCoutputs, AudioNmaster}, 349 { AudioCinputs, AudioNdac}, 350 { AudioCinputs, AudioNcd}, 351 { AudioCrecord, AudioNvolume}, 352 }; 353 354 ctl.type = AUDIO_MIXER_ENUM; 355 ctl.un.ord = 0; 356 357 ctl.dev = sc->codec_if->vtbl->get_portnum_by_name(sc->codec_if, 358 d[i].class, d[i].device, AudioNmute); 359 auvia_set_port(sc, &ctl); 360 } 361 362 /* set a reasonable default volume */ 363 364 ctl.type = AUDIO_MIXER_VALUE; 365 ctl.un.value.num_channels = 2; 366 ctl.un.value.level[AUDIO_MIXER_LEVEL_LEFT] = \ 367 ctl.un.value.level[AUDIO_MIXER_LEVEL_RIGHT] = 199; 368 369 ctl.dev = sc->codec_if->vtbl->get_portnum_by_name(sc->codec_if, 370 AudioCoutputs, AudioNmaster, NULL); 371 auvia_set_port(sc, &ctl); 372 373 audio_attach_mi(&auvia_hw_if, sc, &sc->sc_dev); 374 sc->codec_if->vtbl->unlock(sc->codec_if); 375 } 376 377 378 int 379 auvia_attach_codec(void *addr, struct ac97_codec_if *cif) 380 { 381 struct auvia_softc *sc = addr; 382 383 sc->codec_if = cif; 384 385 return 0; 386 } 387 388 389 void 390 auvia_reset_codec(void *addr) 391 { 392 int i; 393 struct auvia_softc *sc = addr; 394 pcireg_t r; 395 396 /* perform a codec cold reset */ 397 398 r = pci_conf_read(sc->sc_pc, sc->sc_pt, AUVIA_PCICONF_JUNK); 399 400 r &= ~AUVIA_PCICONF_ACNOTRST; /* enable RESET (active low) */ 401 pci_conf_write(sc->sc_pc, sc->sc_pt, AUVIA_PCICONF_JUNK, r); 402 delay(2); 403 404 r |= AUVIA_PCICONF_ACNOTRST; /* disable RESET (inactive high) */ 405 pci_conf_write(sc->sc_pc, sc->sc_pt, AUVIA_PCICONF_JUNK, r); 406 delay(200); 407 408 for (i = 500000; i != 0 && !(pci_conf_read(sc->sc_pc, sc->sc_pt, 409 AUVIA_PCICONF_JUNK) & AUVIA_PCICONF_PRIVALID); i--) 410 DELAY(1); 411 if (i == 0) 412 printf("%s: codec reset timed out\n", sc->sc_dev.dv_xname); 413 } 414 415 416 int 417 auvia_waitready_codec(struct auvia_softc *sc) 418 { 419 int i; 420 421 /* poll until codec not busy */ 422 for (i = 0; (i < TIMEOUT) && (bus_space_read_4(sc->sc_iot, sc->sc_ioh, 423 AUVIA_CODEC_CTL) & AUVIA_CODEC_BUSY); i++) 424 delay(1); 425 426 if (i >= TIMEOUT) { 427 printf("%s: codec busy\n", sc->sc_dev.dv_xname); 428 return 1; 429 } 430 431 return 0; 432 } 433 434 435 int 436 auvia_waitvalid_codec(struct auvia_softc *sc) 437 { 438 int i; 439 440 /* poll until codec valid */ 441 for (i = 0; (i < TIMEOUT) && !(bus_space_read_4(sc->sc_iot, sc->sc_ioh, 442 AUVIA_CODEC_CTL) & AUVIA_CODEC_PRIVALID); i++) 443 delay(1); 444 445 if (i >= TIMEOUT) { 446 printf("%s: codec invalid\n", sc->sc_dev.dv_xname); 447 return 1; 448 } 449 450 return 0; 451 } 452 453 454 int 455 auvia_write_codec(void *addr, u_int8_t reg, u_int16_t val) 456 { 457 struct auvia_softc *sc = addr; 458 459 if (auvia_waitready_codec(sc)) 460 return 1; 461 462 bus_space_write_4(sc->sc_iot, sc->sc_ioh, AUVIA_CODEC_CTL, 463 AUVIA_CODEC_PRIVALID | AUVIA_CODEC_INDEX(reg) | val); 464 465 return 0; 466 } 467 468 469 int 470 auvia_read_codec(void *addr, u_int8_t reg, u_int16_t *val) 471 { 472 struct auvia_softc *sc = addr; 473 474 if (auvia_waitready_codec(sc)) 475 return 1; 476 477 bus_space_write_4(sc->sc_iot, sc->sc_ioh, AUVIA_CODEC_CTL, 478 AUVIA_CODEC_PRIVALID | AUVIA_CODEC_READ | AUVIA_CODEC_INDEX(reg)); 479 480 if (auvia_waitready_codec(sc)) 481 return 1; 482 483 if (auvia_waitvalid_codec(sc)) 484 return 1; 485 486 *val = bus_space_read_2(sc->sc_iot, sc->sc_ioh, AUVIA_CODEC_CTL); 487 488 return 0; 489 } 490 491 492 void 493 auvia_spdif_event(void *addr, int flag) 494 { 495 struct auvia_softc *sc = addr; 496 sc->sc_spdif = flag; 497 } 498 499 int 500 auvia_open(void *addr, int flags) 501 { 502 struct auvia_softc *sc = addr; 503 sc->codec_if->vtbl->lock(sc->codec_if); 504 return 0; 505 } 506 507 508 void 509 auvia_close(void *addr) 510 { 511 struct auvia_softc *sc = addr; 512 sc->codec_if->vtbl->unlock(sc->codec_if); 513 514 auvia_halt_output(sc); 515 auvia_halt_input(sc); 516 517 sc->sc_play.sc_intr = NULL; 518 sc->sc_record.sc_intr = NULL; 519 } 520 521 522 int 523 auvia_query_encoding(void *addr, struct audio_encoding *fp) 524 { 525 struct auvia_softc *sc = addr; 526 527 if (sc->sc_spdif) { 528 switch (fp->index) { 529 case 0: 530 strlcpy(fp->name, AudioEslinear_le, sizeof fp->name); 531 fp->encoding = AUDIO_ENCODING_SLINEAR_LE; 532 fp->precision = 16; 533 fp->flags = 0; 534 fp->bps = 2; 535 fp->msb = 1; 536 return (0); 537 default: 538 return (EINVAL); 539 } 540 } else { 541 switch (fp->index) { 542 case 0: 543 strlcpy(fp->name, AudioEulinear, sizeof fp->name); 544 fp->encoding = AUDIO_ENCODING_ULINEAR; 545 fp->precision = 8; 546 fp->flags = 0; 547 break; 548 case 1: 549 strlcpy(fp->name, AudioEmulaw, sizeof fp->name); 550 fp->encoding = AUDIO_ENCODING_ULAW; 551 fp->precision = 8; 552 fp->flags = AUDIO_ENCODINGFLAG_EMULATED; 553 break; 554 case 2: 555 strlcpy(fp->name, AudioEalaw, sizeof fp->name); 556 fp->encoding = AUDIO_ENCODING_ALAW; 557 fp->precision = 8; 558 fp->flags = AUDIO_ENCODINGFLAG_EMULATED; 559 break; 560 case 3: 561 strlcpy(fp->name, AudioEslinear, sizeof fp->name); 562 fp->encoding = AUDIO_ENCODING_SLINEAR; 563 fp->precision = 8; 564 fp->flags = AUDIO_ENCODINGFLAG_EMULATED; 565 break; 566 case 4: 567 strlcpy(fp->name, AudioEslinear_le, sizeof fp->name); 568 fp->encoding = AUDIO_ENCODING_SLINEAR_LE; 569 fp->precision = 16; 570 fp->flags = 0; 571 break; 572 case 5: 573 strlcpy(fp->name, AudioEulinear_le, sizeof fp->name); 574 fp->encoding = AUDIO_ENCODING_ULINEAR_LE; 575 fp->precision = 16; 576 fp->flags = AUDIO_ENCODINGFLAG_EMULATED; 577 break; 578 case 6: 579 strlcpy(fp->name, AudioEslinear_be, sizeof fp->name); 580 fp->encoding = AUDIO_ENCODING_SLINEAR_BE; 581 fp->precision = 16; 582 fp->flags = AUDIO_ENCODINGFLAG_EMULATED; 583 break; 584 case 7: 585 strlcpy(fp->name, AudioEulinear_be, sizeof fp->name); 586 fp->encoding = AUDIO_ENCODING_ULINEAR_BE; 587 fp->precision = 16; 588 fp->flags = AUDIO_ENCODINGFLAG_EMULATED; 589 break; 590 default: 591 return (EINVAL); 592 } 593 fp->bps = AUDIO_BPS(fp->precision); 594 fp->msb = 1; 595 596 return (0); 597 } 598 } 599 600 void 601 auvia_set_params_sub(struct auvia_softc *sc, struct auvia_softc_chan *ch, 602 struct audio_params *p) 603 { 604 u_int32_t v; 605 u_int16_t regval; 606 607 if (!(sc->sc_flags & AUVIA_FLAGS_VT8233)) { 608 regval = (p->channels == 2 ? AUVIA_RPMODE_STEREO : 0) 609 | (p->precision * p->factor == 16 ? 610 AUVIA_RPMODE_16BIT : 0) 611 | AUVIA_RPMODE_INTR_FLAG | AUVIA_RPMODE_INTR_EOL 612 | AUVIA_RPMODE_AUTOSTART; 613 ch->sc_reg = regval; 614 } else if (ch->sc_base != VIA8233_MP_BASE) { 615 v = CH_READ4(sc, ch, VIA8233_RP_RATEFMT); 616 v &= ~(VIA8233_RATEFMT_48K | VIA8233_RATEFMT_STEREO 617 | VIA8233_RATEFMT_16BIT); 618 619 v |= VIA8233_RATEFMT_48K * (p->sample_rate / 20) 620 / (48000 / 20); 621 if (p->channels == 2) 622 v |= VIA8233_RATEFMT_STEREO; 623 if (p->precision == 16) 624 v |= VIA8233_RATEFMT_16BIT; 625 626 CH_WRITE4(sc, ch, VIA8233_RP_RATEFMT, v); 627 } else { 628 static const u_int32_t slottab[7] = 629 { 0, 0xff000011, 0xff000021, 0, 630 0xff004321, 0, 0xff436521}; 631 632 regval = (p->precision == 16 633 ? VIA8233_MP_FORMAT_16BIT : VIA8233_MP_FORMAT_8BIT) 634 | (p->channels << 4); 635 CH_WRITE1(sc, ch, VIA8233_OFF_MP_FORMAT, regval); 636 CH_WRITE4(sc, ch, VIA8233_OFF_MP_STOP, slottab[p->channels]); 637 } 638 } 639 640 void 641 auvia_get_default_params(void *addr, int mode, struct audio_params *params) 642 { 643 ac97_get_default_params(params); 644 } 645 646 int 647 auvia_set_params(void *addr, int setmode, int usemode, 648 struct audio_params *play, struct audio_params *rec) 649 { 650 struct auvia_softc *sc = addr; 651 struct auvia_softc_chan *ch; 652 struct audio_params *p; 653 struct ac97_codec_if* codec = sc->codec_if; 654 int reg, mode; 655 u_int16_t ext_id; 656 657 /* for mode in (RECORD, PLAY) */ 658 for (mode = AUMODE_RECORD; mode != -1; 659 mode = mode == AUMODE_RECORD ? AUMODE_PLAY : -1) { 660 if ((setmode & mode) == 0) 661 continue; 662 663 if (mode == AUMODE_PLAY) { 664 p = play; 665 ch = &sc->sc_play; 666 reg = AC97_REG_PCM_FRONT_DAC_RATE; 667 } else { 668 p = rec; 669 ch = &sc->sc_record; 670 reg = AC97_REG_PCM_LR_ADC_RATE; 671 } 672 673 if (ch->sc_base == VIA8233_MP_BASE && mode == AUMODE_PLAY) { 674 ext_id = codec->vtbl->get_caps(codec); 675 if (p->channels == 1) { 676 /* ok */ 677 } else if (p->channels == 2) { 678 /* ok */ 679 } else if (p->channels == 4 680 && ext_id & AC97_EXT_AUDIO_SDAC) { 681 /* ok */ 682 } else if (p->channels == 6 683 && (ext_id & AC97_BITS_6CH) == AC97_BITS_6CH) { 684 /* ok */ 685 } else { 686 p->channels = 2; 687 } 688 } else { 689 if (p->channels > 2) 690 p->channels = 2; 691 } 692 693 if (p->sample_rate < 4000) 694 p->sample_rate = 4000; 695 if (p->sample_rate > 48000) 696 p->sample_rate = 48000; 697 if (p->precision > 16) 698 p->precision = 16; 699 700 /* XXX only 16-bit 48kHz slinear_le if s/pdif enabled ? */ 701 if (sc->sc_spdif) { 702 p->sample_rate = 48000; 703 p->precision = 16; 704 p->encoding = AUDIO_ENCODING_SLINEAR_LE; 705 } 706 707 /* XXX only 16-bit 48kHz slinear_le if s/pdif enabled ? */ 708 if (sc->sc_spdif && 709 ((p->sample_rate != 48000) || (p->precision != 16) || 710 (p->encoding != AUDIO_ENCODING_SLINEAR_LE))) 711 return (EINVAL); 712 713 if (AC97_IS_FIXED_RATE(codec)) { 714 p->sample_rate = AC97_SINGLE_RATE; 715 } else { 716 if (codec->vtbl->set_rate(codec, reg, &p->sample_rate)) 717 return (EINVAL); 718 719 if (ch->sc_base == VIA8233_MP_BASE && 720 mode == AUMODE_PLAY) { 721 reg = AC97_REG_PCM_SURR_DAC_RATE; 722 if (p->channels >= 4 723 && codec->vtbl->set_rate(codec, reg, 724 &p->sample_rate)) 725 return (EINVAL); 726 reg = AC97_REG_PCM_LFE_DAC_RATE; 727 if (p->channels == 6 728 && codec->vtbl->set_rate(codec, reg, 729 &p->sample_rate)) 730 return (EINVAL); 731 } 732 } 733 734 p->factor = 1; 735 p->sw_code = 0; 736 switch (p->encoding) { 737 case AUDIO_ENCODING_SLINEAR_BE: 738 if (p->precision == 16) 739 p->sw_code = swap_bytes; 740 else 741 p->sw_code = change_sign8; 742 break; 743 case AUDIO_ENCODING_SLINEAR_LE: 744 if (p->precision != 16) 745 p->sw_code = change_sign8; 746 break; 747 case AUDIO_ENCODING_ULINEAR_BE: 748 if (p->precision == 16) 749 p->sw_code = mode == AUMODE_PLAY? 750 swap_bytes_change_sign16_le : 751 change_sign16_swap_bytes_le; 752 break; 753 case AUDIO_ENCODING_ULINEAR_LE: 754 if (p->precision == 16) 755 p->sw_code = change_sign16_le; 756 break; 757 case AUDIO_ENCODING_ULAW: 758 if (mode == AUMODE_PLAY) { 759 p->factor = 2; 760 p->sw_code = mulaw_to_slinear16_le; 761 } else 762 p->sw_code = ulinear8_to_mulaw; 763 break; 764 case AUDIO_ENCODING_ALAW: 765 if (mode == AUMODE_PLAY) { 766 p->factor = 2; 767 p->sw_code = alaw_to_slinear16_le; 768 } else 769 p->sw_code = ulinear8_to_alaw; 770 break; 771 case AUDIO_ENCODING_SLINEAR: 772 case AUDIO_ENCODING_ULINEAR: 773 break; 774 default: 775 return (EINVAL); 776 } 777 auvia_set_params_sub(sc, ch, p); 778 779 p->bps = AUDIO_BPS(p->precision); 780 p->msb = 1; 781 } 782 783 return 0; 784 } 785 786 787 int 788 auvia_round_blocksize(void *addr, int blk) 789 { 790 struct auvia_softc *sc = addr; 791 792 if (sc->bufsize / blk > AUVIA_DMALIST_MAX) 793 blk = sc->bufsize / AUVIA_DMALIST_MAX + 1; 794 return ((blk + 31) & -32); 795 } 796 797 798 int 799 auvia_halt_output(void *addr) 800 { 801 struct auvia_softc *sc = addr; 802 struct auvia_softc_chan *ch = &(sc->sc_play); 803 804 CH_WRITE1(sc, ch, AUVIA_RP_CONTROL, AUVIA_RPCTRL_TERMINATE); 805 ch->sc_intr = NULL; 806 return 0; 807 } 808 809 810 int 811 auvia_halt_input(void *addr) 812 { 813 struct auvia_softc *sc = addr; 814 struct auvia_softc_chan *ch = &(sc->sc_record); 815 816 CH_WRITE1(sc, ch, AUVIA_RP_CONTROL, AUVIA_RPCTRL_TERMINATE); 817 ch->sc_intr = NULL; 818 return 0; 819 } 820 821 822 int 823 auvia_getdev(void *addr, struct audio_device *retp) 824 { 825 struct auvia_softc *sc = addr; 826 827 if (retp) { 828 strncpy(retp->name, 829 sc->sc_flags & AUVIA_FLAGS_VT8233? "VIA VT8233" : 830 "VIA VT82C686A", sizeof(retp->name)); 831 strncpy(retp->version, sc->sc_revision, sizeof(retp->version)); 832 strncpy(retp->config, "auvia", sizeof(retp->config)); 833 } 834 835 return 0; 836 } 837 838 839 int 840 auvia_set_port(void *addr, mixer_ctrl_t *cp) 841 { 842 struct auvia_softc *sc = addr; 843 844 return (sc->codec_if->vtbl->mixer_set_port(sc->codec_if, cp)); 845 } 846 847 848 int 849 auvia_get_port(void *addr, mixer_ctrl_t *cp) 850 { 851 struct auvia_softc *sc = addr; 852 853 return (sc->codec_if->vtbl->mixer_get_port(sc->codec_if, cp)); 854 } 855 856 857 int 858 auvia_query_devinfo(void *addr, mixer_devinfo_t *dip) 859 { 860 struct auvia_softc *sc = addr; 861 862 return (sc->codec_if->vtbl->query_devinfo(sc->codec_if, dip)); 863 } 864 865 866 void * 867 auvia_malloc(void *addr, int direction, size_t size, int pool, int flags) 868 { 869 struct auvia_softc *sc = addr; 870 struct auvia_dma *p; 871 int error; 872 int rseg; 873 874 p = malloc(sizeof(*p), pool, flags); 875 if (!p) 876 return 0; 877 878 p->size = size; 879 if ((error = bus_dmamem_alloc(sc->sc_dmat, size, PAGE_SIZE, 0, &p->seg, 880 1, &rseg, BUS_DMA_NOWAIT)) != 0) { 881 printf("%s: unable to allocate dma, error = %d\n", 882 sc->sc_dev.dv_xname, error); 883 goto fail_alloc; 884 } 885 886 if ((error = bus_dmamem_map(sc->sc_dmat, &p->seg, rseg, size, &p->addr, 887 BUS_DMA_NOWAIT | BUS_DMA_COHERENT)) != 0) { 888 printf("%s: unable to map dma, error = %d\n", 889 sc->sc_dev.dv_xname, error); 890 goto fail_map; 891 } 892 893 if ((error = bus_dmamap_create(sc->sc_dmat, size, 1, size, 0, 894 BUS_DMA_NOWAIT, &p->map)) != 0) { 895 printf("%s: unable to create dma map, error = %d\n", 896 sc->sc_dev.dv_xname, error); 897 goto fail_create; 898 } 899 900 if ((error = bus_dmamap_load(sc->sc_dmat, p->map, p->addr, size, NULL, 901 BUS_DMA_NOWAIT)) != 0) { 902 printf("%s: unable to load dma map, error = %d\n", 903 sc->sc_dev.dv_xname, error); 904 goto fail_load; 905 } 906 907 p->next = sc->sc_dmas; 908 sc->sc_dmas = p; 909 910 return p->addr; 911 912 913 fail_load: 914 bus_dmamap_destroy(sc->sc_dmat, p->map); 915 fail_create: 916 bus_dmamem_unmap(sc->sc_dmat, p->addr, size); 917 fail_map: 918 bus_dmamem_free(sc->sc_dmat, &p->seg, 1); 919 fail_alloc: 920 free(p, pool); 921 return 0; 922 } 923 924 925 void 926 auvia_free(void *addr, void *ptr, int pool) 927 { 928 struct auvia_softc *sc = addr; 929 struct auvia_dma **pp, *p; 930 931 for (pp = &(sc->sc_dmas); (p = *pp) != NULL; pp = &p->next) 932 if (p->addr == ptr) { 933 bus_dmamap_unload(sc->sc_dmat, p->map); 934 bus_dmamap_destroy(sc->sc_dmat, p->map); 935 bus_dmamem_unmap(sc->sc_dmat, p->addr, p->size); 936 bus_dmamem_free(sc->sc_dmat, &p->seg, 1); 937 938 *pp = p->next; 939 free(p, pool); 940 return; 941 } 942 943 panic("auvia_free: trying to free unallocated memory"); 944 } 945 946 size_t 947 auvia_round_buffersize(void *addr, int direction, size_t bufsize) 948 { 949 struct auvia_softc *sc = addr; 950 951 sc->bufsize = bufsize; 952 return bufsize; 953 } 954 955 paddr_t 956 auvia_mappage(void *addr, void *mem, off_t off, int prot) 957 { 958 struct auvia_softc *sc = addr; 959 struct auvia_dma *p; 960 961 if (off < 0) 962 return -1; 963 964 for (p = sc->sc_dmas; p && p->addr != mem; p = p->next) 965 ; 966 967 if (!p) 968 return -1; 969 970 return bus_dmamem_mmap(sc->sc_dmat, &p->seg, 1, off, prot, 971 BUS_DMA_WAITOK); 972 } 973 974 975 int 976 auvia_get_props(void *addr) 977 { 978 int props; 979 980 props = AUDIO_PROP_MMAP|AUDIO_PROP_INDEPENDENT|AUDIO_PROP_FULLDUPLEX; 981 982 return props; 983 } 984 985 986 int 987 auvia_build_dma_ops(struct auvia_softc *sc, struct auvia_softc_chan *ch, 988 struct auvia_dma *p, void *start, void *end, int blksize) 989 { 990 struct auvia_dma_op *op; 991 struct auvia_dma *dp; 992 bus_addr_t s; 993 size_t l; 994 int segs; 995 996 s = p->map->dm_segs[0].ds_addr; 997 l = (vaddr_t)end - (vaddr_t)start; 998 segs = howmany(l, blksize); 999 if (segs > AUVIA_DMALIST_MAX) { 1000 panic("%s: build_dma_ops: too many DMA segments", 1001 sc->sc_dev.dv_xname); 1002 } 1003 1004 if (segs > ch->sc_dma_op_count) { 1005 /* if old list was too small, free it */ 1006 if (ch->sc_dma_ops) 1007 auvia_free(sc, ch->sc_dma_ops, M_DEVBUF); 1008 1009 ch->sc_dma_ops = auvia_malloc(sc, 0, 1010 sizeof(struct auvia_dma_op) * segs, M_DEVBUF, M_WAITOK); 1011 1012 for (dp = sc->sc_dmas; dp && 1013 dp->addr != (void *)(ch->sc_dma_ops); dp = dp->next) 1014 ; 1015 1016 if (!dp) 1017 panic("%s: build_dma_ops: where'd my memory go??? " 1018 "address (%p)", sc->sc_dev.dv_xname, 1019 ch->sc_dma_ops); 1020 1021 ch->sc_dma_op_count = segs; 1022 ch->sc_dma_ops_dma = dp; 1023 } 1024 1025 op = ch->sc_dma_ops; 1026 1027 while (l) { 1028 op->ptr = htole32(s); 1029 l = l - min(l, blksize); 1030 /* if last block */ 1031 op->flags = htole32((l? AUVIA_DMAOP_FLAG : AUVIA_DMAOP_EOL) | blksize); 1032 s += blksize; 1033 op++; 1034 } 1035 1036 return 0; 1037 } 1038 1039 1040 int 1041 auvia_trigger_output(void *addr, void *start, void *end, int blksize, 1042 void (*intr)(void *), void *arg, struct audio_params *param) 1043 { 1044 struct auvia_softc *sc = addr; 1045 struct auvia_softc_chan *ch = &(sc->sc_play); 1046 struct auvia_dma *p; 1047 1048 for (p = sc->sc_dmas; p && p->addr != start; p = p->next) 1049 ; 1050 1051 if (!p) 1052 panic("auvia_trigger_output: request with bad start " 1053 "address (%p)", start); 1054 1055 if (auvia_build_dma_ops(sc, ch, p, start, end, blksize)) { 1056 return 1; 1057 } 1058 1059 ch->sc_intr = intr; 1060 ch->sc_arg = arg; 1061 1062 CH_WRITE4(sc, ch, AUVIA_RP_DMAOPS_BASE, 1063 ch->sc_dma_ops_dma->map->dm_segs[0].ds_addr); 1064 1065 if (sc->sc_flags & AUVIA_FLAGS_VT8233) { 1066 if (ch->sc_base != VIA8233_MP_BASE) { 1067 CH_WRITE1(sc, ch, VIA8233_RP_DXS_LVOL, 0); 1068 CH_WRITE1(sc, ch, VIA8233_RP_DXS_RVOL, 0); 1069 } 1070 CH_WRITE1(sc, ch, AUVIA_RP_CONTROL, 1071 AUVIA_RPCTRL_START | AUVIA_RPCTRL_AUTOSTART | 1072 AUVIA_RPCTRL_STOP | AUVIA_RPCTRL_EOL | AUVIA_RPCTRL_FLAG); 1073 } else { 1074 CH_WRITE1(sc, ch, AUVIA_RP_MODE, ch->sc_reg); 1075 CH_WRITE1(sc, ch, AUVIA_RP_CONTROL, AUVIA_RPCTRL_START); 1076 } 1077 1078 return 0; 1079 } 1080 1081 1082 int 1083 auvia_trigger_input(void *addr, void *start, void *end, int blksize, 1084 void (*intr)(void *), void *arg, struct audio_params *param) 1085 { 1086 struct auvia_softc *sc = addr; 1087 struct auvia_softc_chan *ch = &(sc->sc_record); 1088 struct auvia_dma *p; 1089 1090 for (p = sc->sc_dmas; p && p->addr != start; p = p->next) 1091 ; 1092 1093 if (!p) 1094 panic("auvia_trigger_input: request with bad start " 1095 "address (%p)", start); 1096 1097 if (auvia_build_dma_ops(sc, ch, p, start, end, blksize)) 1098 return 1; 1099 1100 ch->sc_intr = intr; 1101 ch->sc_arg = arg; 1102 1103 CH_WRITE4(sc, ch, AUVIA_RP_DMAOPS_BASE, 1104 ch->sc_dma_ops_dma->map->dm_segs[0].ds_addr); 1105 1106 if (sc->sc_flags & AUVIA_FLAGS_VT8233) { 1107 if (ch->sc_base != VIA8233_MP_BASE) { 1108 CH_WRITE1(sc, ch, VIA8233_RP_DXS_LVOL, 0); 1109 CH_WRITE1(sc, ch, VIA8233_RP_DXS_RVOL, 0); 1110 } 1111 CH_WRITE1(sc, ch, AUVIA_RP_CONTROL, 1112 AUVIA_RPCTRL_START | AUVIA_RPCTRL_AUTOSTART | 1113 AUVIA_RPCTRL_STOP | AUVIA_RPCTRL_EOL | AUVIA_RPCTRL_FLAG); 1114 } else { 1115 CH_WRITE1(sc, ch, AUVIA_RP_MODE, ch->sc_reg); 1116 CH_WRITE1(sc, ch, AUVIA_RP_CONTROL, AUVIA_RPCTRL_START); 1117 } 1118 return 0; 1119 } 1120 1121 1122 int 1123 auvia_intr(void *arg) 1124 { 1125 struct auvia_softc *sc = arg; 1126 struct auvia_softc_chan *ch; 1127 u_int8_t r; 1128 int i = 0; 1129 1130 1131 ch = &sc->sc_record; 1132 r = CH_READ1(sc, ch, AUVIA_RP_STAT); 1133 if (r & AUVIA_RPSTAT_INTR) { 1134 if (sc->sc_record.sc_intr) 1135 sc->sc_record.sc_intr(sc->sc_record.sc_arg); 1136 1137 /* clear interrupts */ 1138 CH_WRITE1(sc, ch, AUVIA_RP_STAT, AUVIA_RPSTAT_INTR); 1139 1140 i++; 1141 } 1142 ch = &sc->sc_play; 1143 r = CH_READ1(sc, ch, AUVIA_RP_STAT); 1144 if (r & AUVIA_RPSTAT_INTR) { 1145 if (sc->sc_play.sc_intr) 1146 sc->sc_play.sc_intr(sc->sc_play.sc_arg); 1147 1148 /* clear interrupts */ 1149 CH_WRITE1(sc, ch, AUVIA_RP_STAT, AUVIA_RPSTAT_INTR); 1150 1151 i++; 1152 } 1153 1154 return (i? 1 : 0); 1155 } 1156 1157 1158 int 1159 auvia_resume(struct auvia_softc *sc) 1160 { 1161 pci_conf_read(sc->sc_pc, sc->sc_pt, AUVIA_PCICONF_JUNK); 1162 pci_conf_write(sc->sc_pc, sc->sc_pt, AUVIA_PCICONF_JUNK, 1163 sc->sc_pci_junk); 1164 1165 ac97_resume(&sc->host_if, sc->codec_if); 1166 1167 return (0); 1168 } 1169 1170