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