1 /*- 2 * Copyright (c) 2002 Orion Hodson <orion@freebsd.org> 3 * Portions of this code derived from via82c686.c: 4 * Copyright (c) 2000 David Jones <dej@ox.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. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 * 28 * $FreeBSD: src/sys/dev/sound/pci/via8233.c,v 1.20.2.3 2007/04/26 08:21:44 ariff Exp $ 29 */ 30 31 /* 32 * Credits due to: 33 * 34 * Grzybowski Rafal, Russell Davies, Mark Handley, Daniel O'Connor for 35 * comments, machine time, testing patches, and patience. VIA for 36 * providing specs. ALSA for helpful comments and some register poke 37 * ordering. 38 */ 39 40 #include <dev/sound/pcm/sound.h> 41 #include <dev/sound/pcm/ac97.h> 42 43 #include <bus/pci/pcireg.h> 44 #include <bus/pci/pcivar.h> 45 #include <sys/sysctl.h> 46 47 #include <dev/sound/pci/via8233.h> 48 49 SND_DECLARE_FILE("$DragonFly: src/sys/dev/sound/pci/via8233.c,v 1.10 2007/06/16 20:07:19 dillon Exp $"); 50 51 #define VIA8233_PCI_ID 0x30591106 52 53 #define VIA8233_REV_ID_8233PRE 0x10 54 #define VIA8233_REV_ID_8233C 0x20 55 #define VIA8233_REV_ID_8233 0x30 56 #define VIA8233_REV_ID_8233A 0x40 57 #define VIA8233_REV_ID_8235 0x50 58 #define VIA8233_REV_ID_8237 0x60 59 #define VIA8233_REV_ID_8251 0x70 60 61 #define SEGS_PER_CHAN 2 /* Segments per channel */ 62 #define NDXSCHANS 4 /* No of DXS channels */ 63 #define NMSGDCHANS 1 /* No of multichannel SGD */ 64 #define NWRCHANS 1 /* No of write channels */ 65 #define NCHANS (NWRCHANS + NDXSCHANS + NMSGDCHANS) 66 #define NSEGS NCHANS * SEGS_PER_CHAN /* Segments in SGD table */ 67 68 #define VIA_DEFAULT_BUFSZ 0x1000 69 70 /* we rely on this struct being packed to 64 bits */ 71 struct via_dma_op { 72 volatile u_int32_t ptr; 73 volatile u_int32_t flags; 74 #define VIA_DMAOP_EOL 0x80000000 75 #define VIA_DMAOP_FLAG 0x40000000 76 #define VIA_DMAOP_STOP 0x20000000 77 #define VIA_DMAOP_COUNT(x) ((x)&0x00FFFFFF) 78 }; 79 80 struct via_info; 81 82 struct via_chinfo { 83 struct via_info *parent; 84 struct pcm_channel *channel; 85 struct snd_dbuf *buffer; 86 struct via_dma_op *sgd_table; 87 bus_addr_t sgd_addr; 88 int dir, blksz; 89 int rbase; 90 }; 91 92 struct via_info { 93 bus_space_tag_t st; 94 bus_space_handle_t sh; 95 bus_dma_tag_t parent_dmat; 96 bus_dma_tag_t sgd_dmat; 97 bus_dmamap_t sgd_dmamap; 98 bus_addr_t sgd_addr; 99 100 struct resource *reg, *irq; 101 int regid, irqid; 102 void *ih; 103 struct ac97_info *codec; 104 105 unsigned int bufsz; 106 int dxs_src, dma_eol_wake; 107 108 struct via_chinfo pch[NDXSCHANS + NMSGDCHANS]; 109 struct via_chinfo rch[NWRCHANS]; 110 struct via_dma_op *sgd_table; 111 u_int16_t codec_caps; 112 u_int16_t n_dxs_registered; 113 sndlock_t lock; 114 }; 115 116 static u_int32_t via_fmt[] = { 117 AFMT_U8, 118 AFMT_STEREO | AFMT_U8, 119 AFMT_S16_LE, 120 AFMT_STEREO | AFMT_S16_LE, 121 0 122 }; 123 124 static struct pcmchan_caps via_vracaps = { 4000, 48000, via_fmt, 0 }; 125 static struct pcmchan_caps via_caps = { 48000, 48000, via_fmt, 0 }; 126 127 #ifdef SND_DYNSYSCTL 128 static int 129 sysctl_via8233_spdif_enable(SYSCTL_HANDLER_ARGS) 130 { 131 struct via_info *via; 132 device_t dev; 133 uint32_t r; 134 int err, new_en; 135 136 dev = oidp->oid_arg1; 137 via = pcm_getdevinfo(dev); 138 snd_mtxlock(via->lock); 139 r = pci_read_config(dev, VIA_PCI_SPDIF, 1); 140 snd_mtxunlock(via->lock); 141 new_en = (r & VIA_SPDIF_EN) ? 1 : 0; 142 err = sysctl_handle_int(oidp, &new_en, sizeof(new_en), req); 143 144 if (err || req->newptr == NULL) 145 return err; 146 if (new_en < 0 || new_en > 1) 147 return EINVAL; 148 149 if (new_en) 150 r |= VIA_SPDIF_EN; 151 else 152 r &= ~VIA_SPDIF_EN; 153 snd_mtxlock(via->lock); 154 pci_write_config(dev, VIA_PCI_SPDIF, r, 1); 155 snd_mtxunlock(via->lock); 156 157 return 0; 158 } 159 160 #if 0 161 static int 162 sysctl_via8233_dxs_src(SYSCTL_HANDLER_ARGS) 163 { 164 struct via_info *via; 165 device_t dev; 166 int err, val; 167 168 dev = oidp->oid_arg1; 169 via = pcm_getdevinfo(dev); 170 snd_mtxlock(via->lock); 171 val = via->dxs_src; 172 snd_mtxunlock(via->lock); 173 err = sysctl_handle_int(oidp, &val, sizeof(val), req); 174 175 if (err || req->newptr == NULL) 176 return err; 177 if (val < 0 || val > 1) 178 return EINVAL; 179 180 snd_mtxlock(via->lock); 181 via->dxs_src = val; 182 snd_mtxunlock(via->lock); 183 184 return 0; 185 } 186 #endif 187 #endif /* SND_DYNSYSCTL */ 188 189 static void 190 via_init_sysctls(device_t dev) 191 { 192 #ifdef SND_DYNSYSCTL 193 SYSCTL_ADD_PROC(snd_sysctl_tree(dev), 194 SYSCTL_CHILDREN(snd_sysctl_tree_top(dev)), 195 OID_AUTO, "spdif_enabled", 196 CTLTYPE_INT | CTLFLAG_RW, dev, sizeof(dev), 197 sysctl_via8233_spdif_enable, "I", 198 "Enable S/PDIF output on primary playback channel"); 199 #if 0 200 SYSCTL_ADD_PROC(snd_sysctl_tree(dev), 201 SYSCTL_CHILDREN(snd_sysctl_tree_top(dev)), 202 OID_AUTO, "via_dxs_src", 203 CTLTYPE_INT | CTLFLAG_RW, dev, sizeof(dev), 204 sysctl_via8233_dxs_src, "I", 205 "Enable VIA DXS Sample Rate Converter"); 206 #endif 207 #endif 208 } 209 210 static __inline u_int32_t 211 via_rd(struct via_info *via, int regno, int size) 212 { 213 switch (size) { 214 case 1: 215 return bus_space_read_1(via->st, via->sh, regno); 216 case 2: 217 return bus_space_read_2(via->st, via->sh, regno); 218 case 4: 219 return bus_space_read_4(via->st, via->sh, regno); 220 default: 221 return 0xFFFFFFFF; 222 } 223 } 224 225 static __inline void 226 via_wr(struct via_info *via, int regno, u_int32_t data, int size) 227 { 228 229 switch (size) { 230 case 1: 231 bus_space_write_1(via->st, via->sh, regno, data); 232 break; 233 case 2: 234 bus_space_write_2(via->st, via->sh, regno, data); 235 break; 236 case 4: 237 bus_space_write_4(via->st, via->sh, regno, data); 238 break; 239 } 240 } 241 242 /* -------------------------------------------------------------------- */ 243 /* Codec interface */ 244 245 static int 246 via_waitready_codec(struct via_info *via) 247 { 248 int i; 249 250 /* poll until codec not busy */ 251 for (i = 0; i < 1000; i++) { 252 if ((via_rd(via, VIA_AC97_CONTROL, 4) & VIA_AC97_BUSY) == 0) 253 return 0; 254 DELAY(1); 255 } 256 kprintf("via: codec busy\n"); 257 return 1; 258 } 259 260 static int 261 via_waitvalid_codec(struct via_info *via) 262 { 263 int i; 264 265 /* poll until codec valid */ 266 for (i = 0; i < 1000; i++) { 267 if (via_rd(via, VIA_AC97_CONTROL, 4) & VIA_AC97_CODEC00_VALID) 268 return 0; 269 DELAY(1); 270 } 271 kprintf("via: codec invalid\n"); 272 return 1; 273 } 274 275 static int 276 via_write_codec(kobj_t obj, void *addr, int reg, u_int32_t val) 277 { 278 struct via_info *via = addr; 279 280 if (via_waitready_codec(via)) return -1; 281 282 via_wr(via, VIA_AC97_CONTROL, 283 VIA_AC97_CODEC00_VALID | VIA_AC97_INDEX(reg) | 284 VIA_AC97_DATA(val), 4); 285 286 return 0; 287 } 288 289 static int 290 via_read_codec(kobj_t obj, void *addr, int reg) 291 { 292 struct via_info *via = addr; 293 294 if (via_waitready_codec(via)) 295 return -1; 296 297 via_wr(via, VIA_AC97_CONTROL, VIA_AC97_CODEC00_VALID | 298 VIA_AC97_READ | VIA_AC97_INDEX(reg), 4); 299 300 if (via_waitready_codec(via)) 301 return -1; 302 303 if (via_waitvalid_codec(via)) 304 return -1; 305 306 return via_rd(via, VIA_AC97_CONTROL, 2); 307 } 308 309 static kobj_method_t via_ac97_methods[] = { 310 KOBJMETHOD(ac97_read, via_read_codec), 311 KOBJMETHOD(ac97_write, via_write_codec), 312 KOBJMETHOD_END 313 }; 314 AC97_DECLARE(via_ac97); 315 316 /* -------------------------------------------------------------------- */ 317 318 static int 319 via_buildsgdt(struct via_chinfo *ch) 320 { 321 u_int32_t phys_addr, flag; 322 int i, seg_size; 323 324 seg_size = sndbuf_getsize(ch->buffer) / SEGS_PER_CHAN; 325 phys_addr = sndbuf_getbufaddr(ch->buffer); 326 327 for (i = 0; i < SEGS_PER_CHAN; i++) { 328 flag = (i == SEGS_PER_CHAN - 1) ? VIA_DMAOP_EOL : VIA_DMAOP_FLAG; 329 ch->sgd_table[i].ptr = phys_addr + (i * seg_size); 330 ch->sgd_table[i].flags = flag | seg_size; 331 } 332 333 return 0; 334 } 335 336 /* -------------------------------------------------------------------- */ 337 /* Format setting functions */ 338 339 static int 340 via8233wr_setformat(kobj_t obj, void *data, u_int32_t format) 341 { 342 struct via_chinfo *ch = data; 343 struct via_info *via = ch->parent; 344 345 u_int32_t f = WR_FORMAT_STOP_INDEX; 346 347 if (format & AFMT_STEREO) 348 f |= WR_FORMAT_STEREO; 349 if (format & AFMT_S16_LE) 350 f |= WR_FORMAT_16BIT; 351 snd_mtxlock(via->lock); 352 via_wr(via, VIA_WR0_FORMAT, f, 4); 353 snd_mtxunlock(via->lock); 354 355 return 0; 356 } 357 358 static int 359 via8233dxs_setformat(kobj_t obj, void *data, u_int32_t format) 360 { 361 struct via_chinfo *ch = data; 362 struct via_info *via = ch->parent; 363 u_int32_t r, v; 364 365 r = ch->rbase + VIA8233_RP_DXS_RATEFMT; 366 snd_mtxlock(via->lock); 367 v = via_rd(via, r, 4); 368 369 v &= ~(VIA8233_DXS_RATEFMT_STEREO | VIA8233_DXS_RATEFMT_16BIT); 370 if (format & AFMT_STEREO) 371 v |= VIA8233_DXS_RATEFMT_STEREO; 372 if (format & AFMT_16BIT) 373 v |= VIA8233_DXS_RATEFMT_16BIT; 374 via_wr(via, r, v, 4); 375 snd_mtxunlock(via->lock); 376 377 return 0; 378 } 379 380 static int 381 via8233msgd_setformat(kobj_t obj, void *data, u_int32_t format) 382 { 383 struct via_chinfo *ch = data; 384 struct via_info *via = ch->parent; 385 386 u_int32_t s = 0xff000000; 387 u_int8_t v = (format & AFMT_S16_LE) ? MC_SGD_16BIT : MC_SGD_8BIT; 388 389 if (format & AFMT_STEREO) { 390 v |= MC_SGD_CHANNELS(2); 391 s |= SLOT3(1) | SLOT4(2); 392 } else { 393 v |= MC_SGD_CHANNELS(1); 394 s |= SLOT3(1) | SLOT4(1); 395 } 396 397 snd_mtxlock(via->lock); 398 via_wr(via, VIA_MC_SLOT_SELECT, s, 4); 399 via_wr(via, VIA_MC_SGD_FORMAT, v, 1); 400 snd_mtxunlock(via->lock); 401 402 return 0; 403 } 404 405 /* -------------------------------------------------------------------- */ 406 /* Speed setting functions */ 407 408 static int 409 via8233wr_setspeed(kobj_t obj, void *data, u_int32_t speed) 410 { 411 struct via_chinfo *ch = data; 412 struct via_info *via = ch->parent; 413 414 if (via->codec_caps & AC97_EXTCAP_VRA) 415 return ac97_setrate(via->codec, AC97_REGEXT_LADCRATE, speed); 416 417 return 48000; 418 } 419 420 static int 421 via8233dxs_setspeed(kobj_t obj, void *data, u_int32_t speed) 422 { 423 struct via_chinfo *ch = data; 424 struct via_info *via = ch->parent; 425 u_int32_t r, v; 426 427 r = ch->rbase + VIA8233_RP_DXS_RATEFMT; 428 snd_mtxlock(via->lock); 429 v = via_rd(via, r, 4) & ~VIA8233_DXS_RATEFMT_48K; 430 431 /* Careful to avoid overflow (divide by 48 per vt8233c docs) */ 432 433 v |= VIA8233_DXS_RATEFMT_48K * (speed / 48) / (48000 / 48); 434 via_wr(via, r, v, 4); 435 snd_mtxunlock(via->lock); 436 437 return speed; 438 } 439 440 static int 441 via8233msgd_setspeed(kobj_t obj, void *data, u_int32_t speed) 442 { 443 struct via_chinfo *ch = data; 444 struct via_info *via = ch->parent; 445 446 if (via->codec_caps & AC97_EXTCAP_VRA) 447 return ac97_setrate(via->codec, AC97_REGEXT_FDACRATE, speed); 448 449 return 48000; 450 } 451 452 /* -------------------------------------------------------------------- */ 453 /* Format probing functions */ 454 455 static struct pcmchan_caps * 456 via8233wr_getcaps(kobj_t obj, void *data) 457 { 458 struct via_chinfo *ch = data; 459 struct via_info *via = ch->parent; 460 461 /* Controlled by ac97 registers */ 462 if (via->codec_caps & AC97_EXTCAP_VRA) 463 return &via_vracaps; 464 return &via_caps; 465 } 466 467 static struct pcmchan_caps * 468 via8233dxs_getcaps(kobj_t obj, void *data) 469 { 470 struct via_chinfo *ch = data; 471 struct via_info *via = ch->parent; 472 473 /* 474 * Controlled by onboard registers 475 * 476 * Apparently, few boards can do DXS sample rate 477 * conversion. 478 */ 479 if (via->dxs_src) 480 return &via_vracaps; 481 return &via_caps; 482 } 483 484 static struct pcmchan_caps * 485 via8233msgd_getcaps(kobj_t obj, void *data) 486 { 487 struct via_chinfo *ch = data; 488 struct via_info *via = ch->parent; 489 490 /* Controlled by ac97 registers */ 491 if (via->codec_caps & AC97_EXTCAP_VRA) 492 return &via_vracaps; 493 return &via_caps; 494 } 495 496 /* -------------------------------------------------------------------- */ 497 /* Common functions */ 498 499 static int 500 via8233chan_setblocksize(kobj_t obj, void *data, u_int32_t blocksize) 501 { 502 struct via_chinfo *ch = data; 503 504 sndbuf_resize(ch->buffer, SEGS_PER_CHAN, blocksize); 505 ch->blksz = sndbuf_getblksz(ch->buffer); 506 return ch->blksz; 507 } 508 509 static int 510 via8233chan_getptr(kobj_t obj, void *data) 511 { 512 struct via_chinfo *ch = data; 513 struct via_info *via = ch->parent; 514 u_int32_t v, index, count; 515 int ptr; 516 517 snd_mtxlock(via->lock); 518 v = via_rd(via, ch->rbase + VIA_RP_CURRENT_COUNT, 4); 519 snd_mtxunlock(via->lock); 520 index = v >> 24; /* Last completed buffer */ 521 count = v & 0x00ffffff; /* Bytes remaining */ 522 ptr = (index + 1) * ch->blksz - count; 523 ptr %= SEGS_PER_CHAN * ch->blksz; /* Wrap to available space */ 524 525 return ptr; 526 } 527 528 static void 529 via8233chan_reset(struct via_info *via, struct via_chinfo *ch) 530 { 531 via_wr(via, ch->rbase + VIA_RP_CONTROL, SGD_CONTROL_STOP, 1); 532 via_wr(via, ch->rbase + VIA_RP_CONTROL, 0x00, 1); 533 via_wr(via, ch->rbase + VIA_RP_STATUS, 534 SGD_STATUS_EOL | SGD_STATUS_FLAG, 1); 535 } 536 537 /* -------------------------------------------------------------------- */ 538 /* Channel initialization functions */ 539 540 static void 541 via8233chan_sgdinit(struct via_info *via, struct via_chinfo *ch, int chnum) 542 { 543 ch->sgd_table = &via->sgd_table[chnum * SEGS_PER_CHAN]; 544 ch->sgd_addr = via->sgd_addr + chnum * SEGS_PER_CHAN * sizeof(struct via_dma_op); 545 } 546 547 static void* 548 via8233wr_init(kobj_t obj, void *devinfo, struct snd_dbuf *b, 549 struct pcm_channel *c, int dir) 550 { 551 struct via_info *via = devinfo; 552 struct via_chinfo *ch = &via->rch[c->num]; 553 554 ch->parent = via; 555 ch->channel = c; 556 ch->buffer = b; 557 ch->dir = dir; 558 559 ch->rbase = VIA_WR_BASE(c->num); 560 snd_mtxlock(via->lock); 561 via_wr(via, ch->rbase + VIA_WR_RP_SGD_FORMAT, WR_FIFO_ENABLE, 1); 562 snd_mtxunlock(via->lock); 563 564 if (sndbuf_alloc(ch->buffer, via->parent_dmat, via->bufsz) != 0) 565 return NULL; 566 567 snd_mtxlock(via->lock); 568 via8233chan_sgdinit(via, ch, c->num); 569 via8233chan_reset(via, ch); 570 snd_mtxunlock(via->lock); 571 572 return ch; 573 } 574 575 static void* 576 via8233dxs_init(kobj_t obj, void *devinfo, struct snd_dbuf *b, 577 struct pcm_channel *c, int dir) 578 { 579 struct via_info *via = devinfo; 580 struct via_chinfo *ch = &via->pch[c->num]; 581 582 ch->parent = via; 583 ch->channel = c; 584 ch->buffer = b; 585 ch->dir = dir; 586 587 /* 588 * All cards apparently support DXS3, but not other DXS 589 * channels. We therefore want to align first DXS channel to 590 * DXS3. 591 */ 592 snd_mtxlock(via->lock); 593 ch->rbase = VIA_DXS_BASE(NDXSCHANS - 1 - via->n_dxs_registered); 594 via->n_dxs_registered++; 595 snd_mtxunlock(via->lock); 596 597 if (sndbuf_alloc(ch->buffer, via->parent_dmat, via->bufsz) != 0) 598 return NULL; 599 600 snd_mtxlock(via->lock); 601 via8233chan_sgdinit(via, ch, NWRCHANS + c->num); 602 via8233chan_reset(via, ch); 603 snd_mtxunlock(via->lock); 604 605 return ch; 606 } 607 608 static void* 609 via8233msgd_init(kobj_t obj, void *devinfo, struct snd_dbuf *b, 610 struct pcm_channel *c, int dir) 611 { 612 struct via_info *via = devinfo; 613 struct via_chinfo *ch = &via->pch[c->num]; 614 615 ch->parent = via; 616 ch->channel = c; 617 ch->buffer = b; 618 ch->dir = dir; 619 ch->rbase = VIA_MC_SGD_STATUS; 620 621 if (sndbuf_alloc(ch->buffer, via->parent_dmat, via->bufsz) != 0) 622 return NULL; 623 624 snd_mtxlock(via->lock); 625 via8233chan_sgdinit(via, ch, NWRCHANS + c->num); 626 via8233chan_reset(via, ch); 627 snd_mtxunlock(via->lock); 628 629 return ch; 630 } 631 632 static void 633 via8233chan_mute(struct via_info *via, struct via_chinfo *ch, int muted) 634 { 635 if (BASE_IS_VIA_DXS_REG(ch->rbase)) { 636 int r; 637 muted = (muted) ? VIA8233_DXS_MUTE : 0; 638 via_wr(via, ch->rbase + VIA8233_RP_DXS_LVOL, muted, 1); 639 via_wr(via, ch->rbase + VIA8233_RP_DXS_RVOL, muted, 1); 640 r = via_rd(via, ch->rbase + VIA8233_RP_DXS_LVOL, 1) & VIA8233_DXS_MUTE; 641 if (r != muted) { 642 kprintf("via: failed to set dxs volume " 643 "(dxs base 0x%02x).\n", ch->rbase); 644 } 645 } 646 } 647 648 static int 649 via8233chan_trigger(kobj_t obj, void* data, int go) 650 { 651 struct via_chinfo *ch = data; 652 struct via_info *via = ch->parent; 653 654 snd_mtxlock(via->lock); 655 switch(go) { 656 case PCMTRIG_START: 657 via_buildsgdt(ch); 658 via8233chan_mute(via, ch, 0); 659 via_wr(via, ch->rbase + VIA_RP_TABLE_PTR, ch->sgd_addr, 4); 660 via_wr(via, ch->rbase + VIA_RP_CONTROL, 661 SGD_CONTROL_START | SGD_CONTROL_AUTOSTART | 662 SGD_CONTROL_I_EOL | SGD_CONTROL_I_FLAG, 1); 663 break; 664 case PCMTRIG_STOP: 665 case PCMTRIG_ABORT: 666 via_wr(via, ch->rbase + VIA_RP_CONTROL, SGD_CONTROL_STOP, 1); 667 via8233chan_mute(via, ch, 1); 668 via8233chan_reset(via, ch); 669 break; 670 } 671 snd_mtxunlock(via->lock); 672 return 0; 673 } 674 675 static kobj_method_t via8233wr_methods[] = { 676 KOBJMETHOD(channel_init, via8233wr_init), 677 KOBJMETHOD(channel_setformat, via8233wr_setformat), 678 KOBJMETHOD(channel_setspeed, via8233wr_setspeed), 679 KOBJMETHOD(channel_getcaps, via8233wr_getcaps), 680 KOBJMETHOD(channel_setblocksize, via8233chan_setblocksize), 681 KOBJMETHOD(channel_trigger, via8233chan_trigger), 682 KOBJMETHOD(channel_getptr, via8233chan_getptr), 683 KOBJMETHOD_END 684 }; 685 CHANNEL_DECLARE(via8233wr); 686 687 static kobj_method_t via8233dxs_methods[] = { 688 KOBJMETHOD(channel_init, via8233dxs_init), 689 KOBJMETHOD(channel_setformat, via8233dxs_setformat), 690 KOBJMETHOD(channel_setspeed, via8233dxs_setspeed), 691 KOBJMETHOD(channel_getcaps, via8233dxs_getcaps), 692 KOBJMETHOD(channel_setblocksize, via8233chan_setblocksize), 693 KOBJMETHOD(channel_trigger, via8233chan_trigger), 694 KOBJMETHOD(channel_getptr, via8233chan_getptr), 695 KOBJMETHOD_END 696 }; 697 CHANNEL_DECLARE(via8233dxs); 698 699 static kobj_method_t via8233msgd_methods[] = { 700 KOBJMETHOD(channel_init, via8233msgd_init), 701 KOBJMETHOD(channel_setformat, via8233msgd_setformat), 702 KOBJMETHOD(channel_setspeed, via8233msgd_setspeed), 703 KOBJMETHOD(channel_getcaps, via8233msgd_getcaps), 704 KOBJMETHOD(channel_setblocksize, via8233chan_setblocksize), 705 KOBJMETHOD(channel_trigger, via8233chan_trigger), 706 KOBJMETHOD(channel_getptr, via8233chan_getptr), 707 KOBJMETHOD_END 708 }; 709 CHANNEL_DECLARE(via8233msgd); 710 711 /* -------------------------------------------------------------------- */ 712 713 static void 714 via_intr(void *p) 715 { 716 struct via_info *via = p; 717 int i, reg, stat; 718 719 /* Poll playback channels */ 720 snd_mtxlock(via->lock); 721 for (i = 0; i < NDXSCHANS + NMSGDCHANS; i++) { 722 if (via->pch[i].channel == NULL) 723 continue; 724 reg = via->pch[i].rbase + VIA_RP_STATUS; 725 stat = via_rd(via, reg, 1); 726 if (stat & SGD_STATUS_INTR) { 727 if (via->dma_eol_wake && ((stat & SGD_STATUS_EOL) || 728 !(stat & SGD_STATUS_ACTIVE))) { 729 via_wr(via, 730 via->pch[i].rbase + VIA_RP_CONTROL, 731 SGD_CONTROL_START | 732 SGD_CONTROL_AUTOSTART | 733 SGD_CONTROL_I_EOL | 734 SGD_CONTROL_I_FLAG, 1); 735 } 736 via_wr(via, reg, stat, 1); 737 snd_mtxunlock(via->lock); 738 chn_intr(via->pch[i].channel); 739 snd_mtxlock(via->lock); 740 } 741 } 742 743 /* Poll record channels */ 744 for (i = 0; i < NWRCHANS; i++) { 745 if (via->rch[i].channel == NULL) 746 continue; 747 reg = via->rch[i].rbase + VIA_RP_STATUS; 748 stat = via_rd(via, reg, 1); 749 if (stat & SGD_STATUS_INTR) { 750 if (via->dma_eol_wake && ((stat & SGD_STATUS_EOL) || 751 !(stat & SGD_STATUS_ACTIVE))) { 752 via_wr(via, 753 via->rch[i].rbase + VIA_RP_CONTROL, 754 SGD_CONTROL_START | 755 SGD_CONTROL_AUTOSTART | 756 SGD_CONTROL_I_EOL | 757 SGD_CONTROL_I_FLAG, 1); 758 } 759 via_wr(via, reg, stat, 1); 760 snd_mtxunlock(via->lock); 761 chn_intr(via->rch[i].channel); 762 snd_mtxlock(via->lock); 763 } 764 } 765 snd_mtxunlock(via->lock); 766 } 767 768 /* 769 * Probe and attach the card 770 */ 771 static int 772 via_probe(device_t dev) 773 { 774 switch(pci_get_devid(dev)) { 775 case VIA8233_PCI_ID: 776 switch(pci_get_revid(dev)) { 777 case VIA8233_REV_ID_8233PRE: 778 device_set_desc(dev, "VIA VT8233 (pre)"); 779 return BUS_PROBE_DEFAULT; 780 case VIA8233_REV_ID_8233C: 781 device_set_desc(dev, "VIA VT8233C"); 782 return BUS_PROBE_DEFAULT; 783 case VIA8233_REV_ID_8233: 784 device_set_desc(dev, "VIA VT8233"); 785 return BUS_PROBE_DEFAULT; 786 case VIA8233_REV_ID_8233A: 787 device_set_desc(dev, "VIA VT8233A"); 788 return BUS_PROBE_DEFAULT; 789 case VIA8233_REV_ID_8235: 790 device_set_desc(dev, "VIA VT8235"); 791 return BUS_PROBE_DEFAULT; 792 case VIA8233_REV_ID_8237: 793 device_set_desc(dev, "VIA VT8237"); 794 return BUS_PROBE_DEFAULT; 795 case VIA8233_REV_ID_8251: 796 device_set_desc(dev, "VIA VT8251"); 797 return BUS_PROBE_DEFAULT; 798 default: 799 device_set_desc(dev, "VIA VT8233X"); /* Unknown */ 800 return BUS_PROBE_DEFAULT; 801 } 802 } 803 return ENXIO; 804 } 805 806 static void 807 dma_cb(void *p, bus_dma_segment_t *bds, int a, int b) 808 { 809 struct via_info *via = (struct via_info *)p; 810 via->sgd_addr = bds->ds_addr; 811 } 812 813 static int 814 via_chip_init(device_t dev) 815 { 816 u_int32_t data, cnt; 817 818 /* Wake up and reset AC97 if necessary */ 819 data = pci_read_config(dev, VIA_PCI_ACLINK_STAT, 1); 820 821 if ((data & VIA_PCI_ACLINK_C00_READY) == 0) { 822 /* Cold reset per ac97r2.3 spec (page 95) */ 823 /* Assert low */ 824 pci_write_config(dev, VIA_PCI_ACLINK_CTRL, 825 VIA_PCI_ACLINK_EN, 1); 826 /* Wait T_rst_low */ 827 DELAY(100); 828 /* Assert high */ 829 pci_write_config(dev, VIA_PCI_ACLINK_CTRL, 830 VIA_PCI_ACLINK_EN | VIA_PCI_ACLINK_NRST, 1); 831 /* Wait T_rst2clk */ 832 DELAY(5); 833 /* Assert low */ 834 pci_write_config(dev, VIA_PCI_ACLINK_CTRL, 835 VIA_PCI_ACLINK_EN, 1); 836 } else { 837 /* Warm reset */ 838 /* Force no sync */ 839 pci_write_config(dev, VIA_PCI_ACLINK_CTRL, 840 VIA_PCI_ACLINK_EN, 1); 841 DELAY(100); 842 /* Sync */ 843 pci_write_config(dev, VIA_PCI_ACLINK_CTRL, 844 VIA_PCI_ACLINK_EN | VIA_PCI_ACLINK_SYNC, 1); 845 /* Wait T_sync_high */ 846 DELAY(5); 847 /* Force no sync */ 848 pci_write_config(dev, VIA_PCI_ACLINK_CTRL, 849 VIA_PCI_ACLINK_EN, 1); 850 /* Wait T_sync2clk */ 851 DELAY(5); 852 } 853 854 /* Power everything up */ 855 pci_write_config(dev, VIA_PCI_ACLINK_CTRL, VIA_PCI_ACLINK_DESIRED, 1); 856 857 /* Wait for codec to become ready (largest reported delay 310ms) */ 858 for (cnt = 0; cnt < 2000; cnt++) { 859 data = pci_read_config(dev, VIA_PCI_ACLINK_STAT, 1); 860 if (data & VIA_PCI_ACLINK_C00_READY) { 861 return 0; 862 } 863 DELAY(5000); 864 } 865 device_printf(dev, "primary codec not ready (cnt = 0x%02x)\n", cnt); 866 return ENXIO; 867 } 868 869 static int 870 via_attach(device_t dev) 871 { 872 struct via_info *via = NULL; 873 char status[SND_STATUSLEN]; 874 int i, via_dxs_disabled, via_dxs_src, via_dxs_chnum, via_sgd_chnum; 875 uint32_t revid; 876 877 via = kmalloc(sizeof *via, M_DEVBUF, M_WAITOK | M_ZERO); 878 via->lock = snd_mtxcreate(device_get_nameunit(dev), "sound softc"); 879 880 pci_set_powerstate(dev, PCI_POWERSTATE_D0); 881 pci_enable_busmaster(dev); 882 883 via->regid = PCIR_BAR(0); 884 via->reg = bus_alloc_resource_any(dev, SYS_RES_IOPORT, &via->regid, 885 RF_ACTIVE); 886 if (!via->reg) { 887 device_printf(dev, "cannot allocate bus resource."); 888 goto bad; 889 } 890 via->st = rman_get_bustag(via->reg); 891 via->sh = rman_get_bushandle(via->reg); 892 893 via->bufsz = pcm_getbuffersize(dev, 4096, VIA_DEFAULT_BUFSZ, 65536); 894 895 via->irqid = 0; 896 via->irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &via->irqid, 897 RF_ACTIVE | RF_SHAREABLE); 898 if (!via->irq || 899 snd_setup_intr(dev, via->irq, INTR_MPSAFE, via_intr, via, &via->ih)) { 900 device_printf(dev, "unable to map interrupt\n"); 901 goto bad; 902 } 903 904 /* DMA tag for buffers */ 905 if (bus_dma_tag_create(/*parent*/NULL, /*alignment*/2, /*boundary*/0, 906 /*lowaddr*/BUS_SPACE_MAXADDR_32BIT, 907 /*highaddr*/BUS_SPACE_MAXADDR, 908 /*filter*/NULL, /*filterarg*/NULL, 909 /*maxsize*/via->bufsz, /*nsegments*/1, /*maxsegz*/0x3ffff, 910 /*flags*/0, 911 &via->parent_dmat) != 0) { 912 device_printf(dev, "unable to create dma tag\n"); 913 goto bad; 914 } 915 916 /* 917 * DMA tag for SGD table. The 686 uses scatter/gather DMA and 918 * requires a list in memory of work to do. We need only 16 bytes 919 * for this list, and it is wasteful to allocate 16K. 920 */ 921 if (bus_dma_tag_create(/*parent*/NULL, /*alignment*/2, /*boundary*/0, 922 /*lowaddr*/BUS_SPACE_MAXADDR_32BIT, 923 /*highaddr*/BUS_SPACE_MAXADDR, 924 /*filter*/NULL, /*filterarg*/NULL, 925 /*maxsize*/NSEGS * sizeof(struct via_dma_op), 926 /*nsegments*/1, /*maxsegz*/0x3ffff, 927 /*flags*/0, 928 &via->sgd_dmat) != 0) { 929 device_printf(dev, "unable to create dma tag\n"); 930 goto bad; 931 } 932 933 if (bus_dmamem_alloc(via->sgd_dmat, (void **)&via->sgd_table, 934 BUS_DMA_NOWAIT, &via->sgd_dmamap) == -1) 935 goto bad; 936 if (bus_dmamap_load(via->sgd_dmat, via->sgd_dmamap, via->sgd_table, 937 NSEGS * sizeof(struct via_dma_op), dma_cb, via, 0)) 938 goto bad; 939 940 if (via_chip_init(dev)) 941 goto bad; 942 943 via->codec = AC97_CREATE(dev, via, via_ac97); 944 if (!via->codec) 945 goto bad; 946 947 mixer_init(dev, ac97_getmixerclass(), via->codec); 948 949 via->codec_caps = ac97_getextcaps(via->codec); 950 951 /* Try to set VRA without generating an error, VRM not reqrd yet */ 952 if (via->codec_caps & 953 (AC97_EXTCAP_VRA | AC97_EXTCAP_VRM | AC97_EXTCAP_DRA)) { 954 u_int16_t ext = ac97_getextmode(via->codec); 955 ext |= (via->codec_caps & 956 (AC97_EXTCAP_VRA | AC97_EXTCAP_VRM)); 957 ext &= ~AC97_EXTCAP_DRA; 958 ac97_setextmode(via->codec, ext); 959 } 960 961 ksnprintf(status, SND_STATUSLEN, "at io 0x%lx irq %ld %s", 962 rman_get_start(via->reg), rman_get_start(via->irq),PCM_KLDSTRING(snd_via8233)); 963 964 revid = pci_get_revid(dev); 965 966 /* 967 * VIA8251 lost its interrupt after DMA EOL, and need 968 * a gentle spank on its face within interrupt handler. 969 */ 970 if (revid == VIA8233_REV_ID_8251) 971 via->dma_eol_wake = 1; 972 else 973 via->dma_eol_wake = 0; 974 975 /* 976 * Decide whether DXS had to be disabled or not 977 */ 978 if (revid == VIA8233_REV_ID_8233A) { 979 /* 980 * DXS channel is disabled. Reports from multiple users 981 * that it plays at half-speed. Do not see this behaviour 982 * on available 8233C or when emulating 8233A register set 983 * on 8233C (either with or without ac97 VRA). 984 */ 985 via_dxs_disabled = 1; 986 } else if (resource_int_value(device_get_name(dev), 987 device_get_unit(dev), "via_dxs_disabled", 988 &via_dxs_disabled) == 0) 989 via_dxs_disabled = (via_dxs_disabled > 0) ? 1 : 0; 990 else 991 via_dxs_disabled = 0; 992 993 if (via_dxs_disabled) { 994 via_dxs_chnum = 0; 995 via_sgd_chnum = 1; 996 } else { 997 if (resource_int_value(device_get_name(dev), 998 device_get_unit(dev), "via_dxs_channels", 999 &via_dxs_chnum) != 0) 1000 via_dxs_chnum = NDXSCHANS; 1001 if (resource_int_value(device_get_name(dev), 1002 device_get_unit(dev), "via_sgd_channels", 1003 &via_sgd_chnum) != 0) 1004 via_sgd_chnum = NMSGDCHANS; 1005 } 1006 if (via_dxs_chnum > NDXSCHANS) 1007 via_dxs_chnum = NDXSCHANS; 1008 else if (via_dxs_chnum < 0) 1009 via_dxs_chnum = 0; 1010 if (via_sgd_chnum > NMSGDCHANS) 1011 via_sgd_chnum = NMSGDCHANS; 1012 else if (via_sgd_chnum < 0) 1013 via_sgd_chnum = 0; 1014 if (via_dxs_chnum + via_sgd_chnum < 1) { 1015 /* Minimalist ? */ 1016 via_dxs_chnum = 1; 1017 via_sgd_chnum = 0; 1018 } 1019 if (via_dxs_chnum > 0 && resource_int_value(device_get_name(dev), 1020 device_get_unit(dev), "via_dxs_src", 1021 &via_dxs_src) == 0) 1022 via->dxs_src = (via_dxs_src > 0) ? 1 : 0; 1023 else 1024 via->dxs_src = 0; 1025 /* Register */ 1026 if (pcm_register(dev, via, via_dxs_chnum + via_sgd_chnum, NWRCHANS)) 1027 goto bad; 1028 for (i = 0; i < via_dxs_chnum; i++) 1029 pcm_addchan(dev, PCMDIR_PLAY, &via8233dxs_class, via); 1030 for (i = 0; i < via_sgd_chnum; i++) 1031 pcm_addchan(dev, PCMDIR_PLAY, &via8233msgd_class, via); 1032 for (i = 0; i < NWRCHANS; i++) 1033 pcm_addchan(dev, PCMDIR_REC, &via8233wr_class, via); 1034 if (via_dxs_chnum > 0) 1035 via_init_sysctls(dev); 1036 device_printf(dev, "<VIA DXS %sabled: DXS%s %d / SGD %d / REC %d>\n", 1037 (via_dxs_chnum > 0) ? "En" : "Dis", 1038 (via->dxs_src) ? "(SRC)" : "", 1039 via_dxs_chnum, via_sgd_chnum, NWRCHANS); 1040 1041 pcm_setstatus(dev, status); 1042 1043 return 0; 1044 bad: 1045 if (via->codec) ac97_destroy(via->codec); 1046 if (via->reg) bus_release_resource(dev, SYS_RES_IOPORT, via->regid, via->reg); 1047 if (via->ih) bus_teardown_intr(dev, via->irq, via->ih); 1048 if (via->irq) bus_release_resource(dev, SYS_RES_IRQ, via->irqid, via->irq); 1049 if (via->parent_dmat) bus_dma_tag_destroy(via->parent_dmat); 1050 if (via->sgd_dmamap) bus_dmamap_unload(via->sgd_dmat, via->sgd_dmamap); 1051 if (via->sgd_table) bus_dmamem_free(via->sgd_dmat, via->sgd_table, via->sgd_dmamap); 1052 if (via->sgd_dmat) bus_dma_tag_destroy(via->sgd_dmat); 1053 if (via->lock) snd_mtxfree(via->lock); 1054 if (via) kfree(via, M_DEVBUF); 1055 return ENXIO; 1056 } 1057 1058 static int 1059 via_detach(device_t dev) 1060 { 1061 int r; 1062 struct via_info *via = NULL; 1063 1064 r = pcm_unregister(dev); 1065 if (r) return r; 1066 1067 via = pcm_getdevinfo(dev); 1068 bus_release_resource(dev, SYS_RES_IOPORT, via->regid, via->reg); 1069 bus_teardown_intr(dev, via->irq, via->ih); 1070 bus_release_resource(dev, SYS_RES_IRQ, via->irqid, via->irq); 1071 bus_dma_tag_destroy(via->parent_dmat); 1072 bus_dmamap_unload(via->sgd_dmat, via->sgd_dmamap); 1073 bus_dmamem_free(via->sgd_dmat, via->sgd_table, via->sgd_dmamap); 1074 bus_dma_tag_destroy(via->sgd_dmat); 1075 snd_mtxfree(via->lock); 1076 kfree(via, M_DEVBUF); 1077 return 0; 1078 } 1079 1080 1081 static device_method_t via_methods[] = { 1082 DEVMETHOD(device_probe, via_probe), 1083 DEVMETHOD(device_attach, via_attach), 1084 DEVMETHOD(device_detach, via_detach), 1085 DEVMETHOD_END 1086 }; 1087 1088 static driver_t via_driver = { 1089 "pcm", 1090 via_methods, 1091 PCM_SOFTC_SIZE, 1092 }; 1093 1094 DRIVER_MODULE(snd_via8233, pci, via_driver, pcm_devclass, NULL, NULL); 1095 MODULE_DEPEND(snd_via8233, sound, SOUND_MINVER, SOUND_PREFVER, SOUND_MAXVER); 1096 MODULE_VERSION(snd_via8233, 1); 1097