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 #define VIA8233_REV_ID_8251 0x70 58 59 #define SEGS_PER_CHAN 2 /* Segments per channel */ 60 #define NDXSCHANS 4 /* No of DXS channels */ 61 #define NMSGDCHANS 1 /* No of multichannel SGD */ 62 #define NWRCHANS 1 /* No of write channels */ 63 #define NCHANS (NWRCHANS + NDXSCHANS + NMSGDCHANS) 64 #define NSEGS NCHANS * SEGS_PER_CHAN /* Segments in SGD table */ 65 #define VIA_SEGS_MIN 2 66 #define VIA_SEGS_MAX 64 67 #define VIA_SEGS_DEFAULT 2 68 #define VIA_BLK_MIN 32 69 #define VIA_BLK_ALIGN (~(VIA_BLK_MIN - 1)) 70 71 #define VIA_DEFAULT_BUFSZ 0x1000 72 73 /* we rely on this struct being packed to 64 bits */ 74 struct via_dma_op { 75 volatile uint32_t ptr; 76 volatile uint32_t flags; 77 #define VIA_DMAOP_EOL 0x80000000 78 #define VIA_DMAOP_FLAG 0x40000000 79 #define VIA_DMAOP_STOP 0x20000000 80 #define VIA_DMAOP_COUNT(x) ((x)&0x00FFFFFF) 81 }; 82 83 struct via_info; 84 85 struct via_chinfo { 86 struct via_info *parent; 87 struct pcm_channel *channel; 88 struct snd_dbuf *buffer; 89 struct via_dma_op *sgd_table; 90 bus_addr_t sgd_addr; 91 int dir, rbase, active; 92 unsigned int blksz, blkcnt; 93 unsigned int ptr, prevptr; 94 }; 95 96 struct via_info { 97 device_t dev; 98 99 bus_space_tag_t st; 100 bus_space_handle_t sh; 101 bus_dma_tag_t parent_dmat; 102 bus_dma_tag_t sgd_dmat; 103 bus_dmamap_t sgd_dmamap; 104 bus_addr_t sgd_addr; 105 106 struct resource *reg, *irq; 107 int regid, irqid; 108 void *ih; 109 struct ac97_info *codec; 110 111 unsigned int bufsz, blkcnt; 112 int dxs_src, dma_eol_wake; 113 114 struct via_chinfo pch[NDXSCHANS + NMSGDCHANS]; 115 struct via_chinfo rch[NWRCHANS]; 116 struct via_dma_op *sgd_table; 117 uint16_t codec_caps; 118 uint16_t n_dxs_registered; 119 int play_num, rec_num; 120 struct mtx *lock; 121 struct callout poll_timer; 122 int poll_ticks, polling; 123 }; 124 125 static uint32_t via_fmt[] = { 126 AFMT_U8, 127 AFMT_STEREO | AFMT_U8, 128 AFMT_S16_LE, 129 AFMT_STEREO | AFMT_S16_LE, 130 0 131 }; 132 133 static struct pcmchan_caps via_vracaps = { 4000, 48000, via_fmt, 0 }; 134 static struct pcmchan_caps via_caps = { 48000, 48000, via_fmt, 0 }; 135 136 static __inline int 137 via_chan_active(struct via_info *via) 138 { 139 int i, ret = 0; 140 141 if (via == NULL) 142 return (0); 143 144 for (i = 0; i < NDXSCHANS + NMSGDCHANS; i++) 145 ret += via->pch[i].active; 146 147 for (i = 0; i < NWRCHANS; i++) 148 ret += via->rch[i].active; 149 150 return (ret); 151 } 152 153 #ifdef SND_DYNSYSCTL 154 static int 155 sysctl_via8233_spdif_enable(SYSCTL_HANDLER_ARGS) 156 { 157 struct via_info *via; 158 device_t dev; 159 uint32_t r; 160 int err, new_en; 161 162 dev = oidp->oid_arg1; 163 via = pcm_getdevinfo(dev); 164 snd_mtxlock(via->lock); 165 r = pci_read_config(dev, VIA_PCI_SPDIF, 1); 166 snd_mtxunlock(via->lock); 167 new_en = (r & VIA_SPDIF_EN) ? 1 : 0; 168 err = sysctl_handle_int(oidp, &new_en, 0, req); 169 170 if (err || req->newptr == NULL) 171 return (err); 172 if (new_en < 0 || new_en > 1) 173 return (EINVAL); 174 175 if (new_en) 176 r |= VIA_SPDIF_EN; 177 else 178 r &= ~VIA_SPDIF_EN; 179 snd_mtxlock(via->lock); 180 pci_write_config(dev, VIA_PCI_SPDIF, r, 1); 181 snd_mtxunlock(via->lock); 182 183 return (0); 184 } 185 186 static int 187 sysctl_via8233_dxs_src(SYSCTL_HANDLER_ARGS) 188 { 189 struct via_info *via; 190 device_t dev; 191 int err, val; 192 193 dev = oidp->oid_arg1; 194 via = pcm_getdevinfo(dev); 195 snd_mtxlock(via->lock); 196 val = via->dxs_src; 197 snd_mtxunlock(via->lock); 198 err = sysctl_handle_int(oidp, &val, 0, req); 199 200 if (err || req->newptr == NULL) 201 return (err); 202 if (val < 0 || val > 1) 203 return (EINVAL); 204 205 snd_mtxlock(via->lock); 206 via->dxs_src = val; 207 snd_mtxunlock(via->lock); 208 209 return (0); 210 } 211 212 static int 213 sysctl_via_polling(SYSCTL_HANDLER_ARGS) 214 { 215 struct via_info *via; 216 device_t dev; 217 int err, val; 218 219 dev = oidp->oid_arg1; 220 via = pcm_getdevinfo(dev); 221 if (via == NULL) 222 return (EINVAL); 223 snd_mtxlock(via->lock); 224 val = via->polling; 225 snd_mtxunlock(via->lock); 226 err = sysctl_handle_int(oidp, &val, 0, req); 227 228 if (err || req->newptr == NULL) 229 return (err); 230 if (val < 0 || val > 1) 231 return (EINVAL); 232 233 snd_mtxlock(via->lock); 234 if (val != via->polling) { 235 if (via_chan_active(via) != 0) 236 err = EBUSY; 237 else if (val == 0) 238 via->polling = 0; 239 else 240 via->polling = 1; 241 } 242 snd_mtxunlock(via->lock); 243 244 return (err); 245 } 246 #endif /* SND_DYNSYSCTL */ 247 248 static void 249 via_init_sysctls(device_t dev) 250 { 251 #ifdef SND_DYNSYSCTL 252 /* XXX: an user should be able to set this with a control tool, 253 if not done before 7.0-RELEASE, this needs to be converted to 254 a device specific sysctl "dev.pcm.X.yyy" via device_get_sysctl_*() 255 as discussed on multimedia@ in msg-id <861wujij2q.fsf@xps.des.no> */ 256 SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev), 257 SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, 258 "spdif_enabled", CTLTYPE_INT | CTLFLAG_RW, dev, sizeof(dev), 259 sysctl_via8233_spdif_enable, "I", 260 "Enable S/PDIF output on primary playback channel"); 261 SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev), 262 SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, 263 "dxs_src", CTLTYPE_INT | CTLFLAG_RW, dev, sizeof(dev), 264 sysctl_via8233_dxs_src, "I", 265 "Enable VIA DXS Sample Rate Converter"); 266 SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev), 267 SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, 268 "polling", CTLTYPE_INT | CTLFLAG_RW, dev, sizeof(dev), 269 sysctl_via_polling, "I", 270 "Enable polling mode"); 271 #endif 272 } 273 274 static __inline uint32_t 275 via_rd(struct via_info *via, int regno, int size) 276 { 277 switch (size) { 278 case 1: 279 return (bus_space_read_1(via->st, via->sh, regno)); 280 case 2: 281 return (bus_space_read_2(via->st, via->sh, regno)); 282 case 4: 283 return (bus_space_read_4(via->st, via->sh, regno)); 284 default: 285 return (0xFFFFFFFF); 286 } 287 } 288 289 static __inline void 290 via_wr(struct via_info *via, int regno, uint32_t data, int size) 291 { 292 293 switch (size) { 294 case 1: 295 bus_space_write_1(via->st, via->sh, regno, data); 296 break; 297 case 2: 298 bus_space_write_2(via->st, via->sh, regno, data); 299 break; 300 case 4: 301 bus_space_write_4(via->st, via->sh, regno, data); 302 break; 303 } 304 } 305 306 /* -------------------------------------------------------------------- */ 307 /* Codec interface */ 308 309 static int 310 via_waitready_codec(struct via_info *via) 311 { 312 int i; 313 314 /* poll until codec not busy */ 315 for (i = 0; i < 1000; i++) { 316 if ((via_rd(via, VIA_AC97_CONTROL, 4) & VIA_AC97_BUSY) == 0) 317 return (0); 318 DELAY(1); 319 } 320 device_printf(via->dev, "%s: codec busy\n", __func__); 321 return (1); 322 } 323 324 static int 325 via_waitvalid_codec(struct via_info *via) 326 { 327 int i; 328 329 /* poll until codec valid */ 330 for (i = 0; i < 1000; i++) { 331 if (via_rd(via, VIA_AC97_CONTROL, 4) & VIA_AC97_CODEC00_VALID) 332 return (0); 333 DELAY(1); 334 } 335 device_printf(via->dev, "%s: codec invalid\n", __func__); 336 return (1); 337 } 338 339 static int 340 via_write_codec(kobj_t obj, void *addr, int reg, uint32_t val) 341 { 342 struct via_info *via = addr; 343 344 if (via_waitready_codec(via)) 345 return (-1); 346 347 via_wr(via, VIA_AC97_CONTROL, 348 VIA_AC97_CODEC00_VALID | VIA_AC97_INDEX(reg) | 349 VIA_AC97_DATA(val), 4); 350 351 return (0); 352 } 353 354 static int 355 via_read_codec(kobj_t obj, void *addr, int reg) 356 { 357 struct via_info *via = addr; 358 359 if (via_waitready_codec(via)) 360 return (-1); 361 362 via_wr(via, VIA_AC97_CONTROL, VIA_AC97_CODEC00_VALID | 363 VIA_AC97_READ | VIA_AC97_INDEX(reg), 4); 364 365 if (via_waitready_codec(via)) 366 return (-1); 367 368 if (via_waitvalid_codec(via)) 369 return (-1); 370 371 return (via_rd(via, VIA_AC97_CONTROL, 2)); 372 } 373 374 static kobj_method_t via_ac97_methods[] = { 375 KOBJMETHOD(ac97_read, via_read_codec), 376 KOBJMETHOD(ac97_write, via_write_codec), 377 { 0, 0 } 378 }; 379 AC97_DECLARE(via_ac97); 380 381 /* -------------------------------------------------------------------- */ 382 383 static int 384 via_buildsgdt(struct via_chinfo *ch) 385 { 386 uint32_t phys_addr, flag; 387 int i; 388 389 phys_addr = sndbuf_getbufaddr(ch->buffer); 390 391 for (i = 0; i < ch->blkcnt; i++) { 392 flag = (i == ch->blkcnt - 1) ? VIA_DMAOP_EOL : VIA_DMAOP_FLAG; 393 ch->sgd_table[i].ptr = phys_addr + (i * ch->blksz); 394 ch->sgd_table[i].flags = flag | ch->blksz; 395 } 396 397 return (0); 398 } 399 400 /* -------------------------------------------------------------------- */ 401 /* Format setting functions */ 402 403 static int 404 via8233wr_setformat(kobj_t obj, void *data, uint32_t format) 405 { 406 struct via_chinfo *ch = data; 407 struct via_info *via = ch->parent; 408 409 uint32_t f = WR_FORMAT_STOP_INDEX; 410 411 if (format & AFMT_STEREO) 412 f |= WR_FORMAT_STEREO; 413 if (format & AFMT_S16_LE) 414 f |= WR_FORMAT_16BIT; 415 snd_mtxlock(via->lock); 416 via_wr(via, VIA_WR0_FORMAT, f, 4); 417 snd_mtxunlock(via->lock); 418 419 return (0); 420 } 421 422 static int 423 via8233dxs_setformat(kobj_t obj, void *data, uint32_t format) 424 { 425 struct via_chinfo *ch = data; 426 struct via_info *via = ch->parent; 427 uint32_t r, v; 428 429 r = ch->rbase + VIA8233_RP_DXS_RATEFMT; 430 snd_mtxlock(via->lock); 431 v = via_rd(via, r, 4); 432 433 v &= ~(VIA8233_DXS_RATEFMT_STEREO | VIA8233_DXS_RATEFMT_16BIT); 434 if (format & AFMT_STEREO) 435 v |= VIA8233_DXS_RATEFMT_STEREO; 436 if (format & AFMT_16BIT) 437 v |= VIA8233_DXS_RATEFMT_16BIT; 438 via_wr(via, r, v, 4); 439 snd_mtxunlock(via->lock); 440 441 return (0); 442 } 443 444 static int 445 via8233msgd_setformat(kobj_t obj, void *data, uint32_t format) 446 { 447 struct via_chinfo *ch = data; 448 struct via_info *via = ch->parent; 449 450 uint32_t s = 0xff000000; 451 uint8_t v = (format & AFMT_S16_LE) ? MC_SGD_16BIT : MC_SGD_8BIT; 452 453 if (format & AFMT_STEREO) { 454 v |= MC_SGD_CHANNELS(2); 455 s |= SLOT3(1) | SLOT4(2); 456 } else { 457 v |= MC_SGD_CHANNELS(1); 458 s |= SLOT3(1) | SLOT4(1); 459 } 460 461 snd_mtxlock(via->lock); 462 via_wr(via, VIA_MC_SLOT_SELECT, s, 4); 463 via_wr(via, VIA_MC_SGD_FORMAT, v, 1); 464 snd_mtxunlock(via->lock); 465 466 return (0); 467 } 468 469 /* -------------------------------------------------------------------- */ 470 /* Speed setting functions */ 471 472 static int 473 via8233wr_setspeed(kobj_t obj, void *data, uint32_t speed) 474 { 475 struct via_chinfo *ch = data; 476 struct via_info *via = ch->parent; 477 478 if (via->codec_caps & AC97_EXTCAP_VRA) 479 return (ac97_setrate(via->codec, AC97_REGEXT_LADCRATE, speed)); 480 481 return (48000); 482 } 483 484 static int 485 via8233dxs_setspeed(kobj_t obj, void *data, uint32_t speed) 486 { 487 struct via_chinfo *ch = data; 488 struct via_info *via = ch->parent; 489 uint32_t r, v; 490 491 r = ch->rbase + VIA8233_RP_DXS_RATEFMT; 492 snd_mtxlock(via->lock); 493 v = via_rd(via, r, 4) & ~VIA8233_DXS_RATEFMT_48K; 494 495 /* Careful to avoid overflow (divide by 48 per vt8233c docs) */ 496 497 v |= VIA8233_DXS_RATEFMT_48K * (speed / 48) / (48000 / 48); 498 via_wr(via, r, v, 4); 499 snd_mtxunlock(via->lock); 500 501 return (speed); 502 } 503 504 static int 505 via8233msgd_setspeed(kobj_t obj, void *data, uint32_t speed) 506 { 507 struct via_chinfo *ch = data; 508 struct via_info *via = ch->parent; 509 510 if (via->codec_caps & AC97_EXTCAP_VRA) 511 return (ac97_setrate(via->codec, AC97_REGEXT_FDACRATE, speed)); 512 513 return (48000); 514 } 515 516 /* -------------------------------------------------------------------- */ 517 /* Format probing functions */ 518 519 static struct pcmchan_caps * 520 via8233wr_getcaps(kobj_t obj, void *data) 521 { 522 struct via_chinfo *ch = data; 523 struct via_info *via = ch->parent; 524 525 /* Controlled by ac97 registers */ 526 if (via->codec_caps & AC97_EXTCAP_VRA) 527 return (&via_vracaps); 528 return (&via_caps); 529 } 530 531 static struct pcmchan_caps * 532 via8233dxs_getcaps(kobj_t obj, void *data) 533 { 534 struct via_chinfo *ch = data; 535 struct via_info *via = ch->parent; 536 537 /* 538 * Controlled by onboard registers 539 * 540 * Apparently, few boards can do DXS sample rate 541 * conversion. 542 */ 543 if (via->dxs_src) 544 return (&via_vracaps); 545 return (&via_caps); 546 } 547 548 static struct pcmchan_caps * 549 via8233msgd_getcaps(kobj_t obj, void *data) 550 { 551 struct via_chinfo *ch = data; 552 struct via_info *via = ch->parent; 553 554 /* Controlled by ac97 registers */ 555 if (via->codec_caps & AC97_EXTCAP_VRA) 556 return (&via_vracaps); 557 return (&via_caps); 558 } 559 560 /* -------------------------------------------------------------------- */ 561 /* Common functions */ 562 563 static int 564 via8233chan_setfragments(kobj_t obj, void *data, 565 uint32_t blksz, uint32_t blkcnt) 566 { 567 struct via_chinfo *ch = data; 568 struct via_info *via = ch->parent; 569 570 blksz &= VIA_BLK_ALIGN; 571 572 if (blksz > (sndbuf_getmaxsize(ch->buffer) / VIA_SEGS_MIN)) 573 blksz = sndbuf_getmaxsize(ch->buffer) / VIA_SEGS_MIN; 574 if (blksz < VIA_BLK_MIN) 575 blksz = VIA_BLK_MIN; 576 if (blkcnt > VIA_SEGS_MAX) 577 blkcnt = VIA_SEGS_MAX; 578 if (blkcnt < VIA_SEGS_MIN) 579 blkcnt = VIA_SEGS_MIN; 580 581 while ((blksz * blkcnt) > sndbuf_getmaxsize(ch->buffer)) { 582 if ((blkcnt >> 1) >= VIA_SEGS_MIN) 583 blkcnt >>= 1; 584 else if ((blksz >> 1) >= VIA_BLK_MIN) 585 blksz >>= 1; 586 else 587 break; 588 } 589 590 if ((sndbuf_getblksz(ch->buffer) != blksz || 591 sndbuf_getblkcnt(ch->buffer) != blkcnt) && 592 sndbuf_resize(ch->buffer, blkcnt, blksz) != 0) 593 device_printf(via->dev, "%s: failed blksz=%u blkcnt=%u\n", 594 __func__, blksz, blkcnt); 595 596 ch->blksz = sndbuf_getblksz(ch->buffer); 597 ch->blkcnt = sndbuf_getblkcnt(ch->buffer); 598 599 return (1); 600 } 601 602 static int 603 via8233chan_setblocksize(kobj_t obj, void *data, uint32_t blksz) 604 { 605 struct via_chinfo *ch = data; 606 struct via_info *via = ch->parent; 607 608 via8233chan_setfragments(obj, data, blksz, via->blkcnt); 609 610 return (ch->blksz); 611 } 612 613 static int 614 via8233chan_getptr(kobj_t obj, void *data) 615 { 616 struct via_chinfo *ch = data; 617 struct via_info *via = ch->parent; 618 uint32_t v, index, count; 619 int ptr; 620 621 snd_mtxlock(via->lock); 622 if (via->polling != 0) { 623 ptr = ch->ptr; 624 snd_mtxunlock(via->lock); 625 } else { 626 v = via_rd(via, ch->rbase + VIA_RP_CURRENT_COUNT, 4); 627 snd_mtxunlock(via->lock); 628 index = v >> 24; /* Last completed buffer */ 629 count = v & 0x00ffffff; /* Bytes remaining */ 630 ptr = (index + 1) * ch->blksz - count; 631 ptr %= ch->blkcnt * ch->blksz; /* Wrap to available space */ 632 } 633 634 return (ptr); 635 } 636 637 static void 638 via8233chan_reset(struct via_info *via, struct via_chinfo *ch) 639 { 640 via_wr(via, ch->rbase + VIA_RP_CONTROL, SGD_CONTROL_STOP, 1); 641 via_wr(via, ch->rbase + VIA_RP_CONTROL, 0x00, 1); 642 via_wr(via, ch->rbase + VIA_RP_STATUS, 643 SGD_STATUS_EOL | SGD_STATUS_FLAG, 1); 644 } 645 646 /* -------------------------------------------------------------------- */ 647 /* Channel initialization functions */ 648 649 static void 650 via8233chan_sgdinit(struct via_info *via, struct via_chinfo *ch, int chnum) 651 { 652 ch->sgd_table = &via->sgd_table[chnum * VIA_SEGS_MAX]; 653 ch->sgd_addr = via->sgd_addr + chnum * VIA_SEGS_MAX * 654 sizeof(struct via_dma_op); 655 } 656 657 static void* 658 via8233wr_init(kobj_t obj, void *devinfo, struct snd_dbuf *b, 659 struct pcm_channel *c, int dir) 660 { 661 struct via_info *via = devinfo; 662 struct via_chinfo *ch; 663 int num; 664 665 snd_mtxlock(via->lock); 666 num = via->rec_num++; 667 ch = &via->rch[num]; 668 ch->parent = via; 669 ch->channel = c; 670 ch->buffer = b; 671 ch->dir = dir; 672 ch->blkcnt = via->blkcnt; 673 ch->rbase = VIA_WR_BASE(num); 674 via_wr(via, ch->rbase + VIA_WR_RP_SGD_FORMAT, WR_FIFO_ENABLE, 1); 675 snd_mtxunlock(via->lock); 676 677 if (sndbuf_alloc(ch->buffer, via->parent_dmat, 0, via->bufsz) != 0) 678 return (NULL); 679 680 snd_mtxlock(via->lock); 681 via8233chan_sgdinit(via, ch, num); 682 via8233chan_reset(via, ch); 683 snd_mtxunlock(via->lock); 684 685 return (ch); 686 } 687 688 static void* 689 via8233dxs_init(kobj_t obj, void *devinfo, struct snd_dbuf *b, 690 struct pcm_channel *c, int dir) 691 { 692 struct via_info *via = devinfo; 693 struct via_chinfo *ch; 694 int num; 695 696 snd_mtxlock(via->lock); 697 num = via->play_num++; 698 ch = &via->pch[num]; 699 ch->parent = via; 700 ch->channel = c; 701 ch->buffer = b; 702 ch->dir = dir; 703 ch->blkcnt = via->blkcnt; 704 705 /* 706 * All cards apparently support DXS3, but not other DXS 707 * channels. We therefore want to align first DXS channel to 708 * DXS3. 709 */ 710 ch->rbase = VIA_DXS_BASE(NDXSCHANS - 1 - via->n_dxs_registered); 711 via->n_dxs_registered++; 712 snd_mtxunlock(via->lock); 713 714 if (sndbuf_alloc(ch->buffer, via->parent_dmat, 0, via->bufsz) != 0) 715 return (NULL); 716 717 snd_mtxlock(via->lock); 718 via8233chan_sgdinit(via, ch, NWRCHANS + num); 719 via8233chan_reset(via, ch); 720 snd_mtxunlock(via->lock); 721 722 return (ch); 723 } 724 725 static void* 726 via8233msgd_init(kobj_t obj, void *devinfo, struct snd_dbuf *b, 727 struct pcm_channel *c, int dir) 728 { 729 struct via_info *via = devinfo; 730 struct via_chinfo *ch; 731 int num; 732 733 snd_mtxlock(via->lock); 734 num = via->play_num++; 735 ch = &via->pch[num]; 736 ch->parent = via; 737 ch->channel = c; 738 ch->buffer = b; 739 ch->dir = dir; 740 ch->rbase = VIA_MC_SGD_STATUS; 741 ch->blkcnt = via->blkcnt; 742 snd_mtxunlock(via->lock); 743 744 if (sndbuf_alloc(ch->buffer, via->parent_dmat, 0, via->bufsz) != 0) 745 return (NULL); 746 747 snd_mtxlock(via->lock); 748 via8233chan_sgdinit(via, ch, NWRCHANS + num); 749 via8233chan_reset(via, ch); 750 snd_mtxunlock(via->lock); 751 752 return (ch); 753 } 754 755 static void 756 via8233chan_mute(struct via_info *via, struct via_chinfo *ch, int muted) 757 { 758 if (BASE_IS_VIA_DXS_REG(ch->rbase)) { 759 int r; 760 muted = (muted) ? VIA8233_DXS_MUTE : 0; 761 via_wr(via, ch->rbase + VIA8233_RP_DXS_LVOL, muted, 1); 762 via_wr(via, ch->rbase + VIA8233_RP_DXS_RVOL, muted, 1); 763 r = via_rd(via, ch->rbase + VIA8233_RP_DXS_LVOL, 1) & 764 VIA8233_DXS_MUTE; 765 if (r != muted) 766 device_printf(via->dev, 767 "%s: failed to set dxs volume " 768 "(dxs base 0x%02x).\n", __func__, ch->rbase); 769 } 770 } 771 772 static __inline int 773 via_poll_channel(struct via_chinfo *ch) 774 { 775 struct via_info *via; 776 uint32_t sz, delta; 777 uint32_t v, index, count; 778 int ptr; 779 780 if (ch == NULL || ch->channel == NULL || ch->active == 0) 781 return (0); 782 783 via = ch->parent; 784 sz = ch->blksz * ch->blkcnt; 785 v = via_rd(via, ch->rbase + VIA_RP_CURRENT_COUNT, 4); 786 index = v >> 24; 787 count = v & 0x00ffffff; 788 ptr = ((index + 1) * ch->blksz) - count; 789 ptr %= sz; 790 ptr &= ~(ch->blksz - 1); 791 ch->ptr = ptr; 792 delta = (sz + ptr - ch->prevptr) % sz; 793 794 if (delta < ch->blksz) 795 return (0); 796 797 ch->prevptr = ptr; 798 799 return (1); 800 } 801 802 static void 803 via_poll_callback(void *arg) 804 { 805 struct via_info *via = arg; 806 uint32_t ptrigger = 0, rtrigger = 0; 807 int i; 808 809 if (via == NULL) 810 return; 811 812 snd_mtxlock(via->lock); 813 if (via->polling == 0 || via_chan_active(via) == 0) { 814 snd_mtxunlock(via->lock); 815 return; 816 } 817 818 for (i = 0; i < NDXSCHANS + NMSGDCHANS; i++) 819 ptrigger |= (via_poll_channel(&via->pch[i]) != 0) ? 820 (1 << i) : 0; 821 822 for (i = 0; i < NWRCHANS; i++) 823 rtrigger |= (via_poll_channel(&via->rch[i]) != 0) ? 824 (1 << i) : 0; 825 826 /* XXX */ 827 callout_reset(&via->poll_timer, 1/*via->poll_ticks*/, 828 via_poll_callback, via); 829 830 snd_mtxunlock(via->lock); 831 832 for (i = 0; i < NDXSCHANS + NMSGDCHANS; i++) { 833 if (ptrigger & (1 << i)) 834 chn_intr(via->pch[i].channel); 835 } 836 for (i = 0; i < NWRCHANS; i++) { 837 if (rtrigger & (1 << i)) 838 chn_intr(via->rch[i].channel); 839 } 840 } 841 842 static int 843 via_poll_ticks(struct via_info *via) 844 { 845 struct via_chinfo *ch; 846 int i; 847 int ret = hz; 848 int pollticks; 849 850 for (i = 0; i < NDXSCHANS + NMSGDCHANS; i++) { 851 ch = &via->pch[i]; 852 if (ch->channel == NULL || ch->active == 0) 853 continue; 854 pollticks = ((uint64_t)hz * ch->blksz) / 855 ((uint64_t)sndbuf_getbps(ch->buffer) * 856 sndbuf_getspd(ch->buffer)); 857 pollticks >>= 2; 858 if (pollticks > hz) 859 pollticks = hz; 860 if (pollticks < 1) 861 pollticks = 1; 862 if (pollticks < ret) 863 ret = pollticks; 864 } 865 866 for (i = 0; i < NWRCHANS; i++) { 867 ch = &via->rch[i]; 868 if (ch->channel == NULL || ch->active == 0) 869 continue; 870 pollticks = ((uint64_t)hz * ch->blksz) / 871 ((uint64_t)sndbuf_getbps(ch->buffer) * 872 sndbuf_getspd(ch->buffer)); 873 pollticks >>= 2; 874 if (pollticks > hz) 875 pollticks = hz; 876 if (pollticks < 1) 877 pollticks = 1; 878 if (pollticks < ret) 879 ret = pollticks; 880 } 881 882 return (ret); 883 } 884 885 static int 886 via8233chan_trigger(kobj_t obj, void* data, int go) 887 { 888 struct via_chinfo *ch = data; 889 struct via_info *via = ch->parent; 890 int pollticks; 891 892 if (!PCMTRIG_COMMON(go)) 893 return (0); 894 895 snd_mtxlock(via->lock); 896 switch(go) { 897 case PCMTRIG_START: 898 via_buildsgdt(ch); 899 via8233chan_mute(via, ch, 0); 900 via_wr(via, ch->rbase + VIA_RP_TABLE_PTR, ch->sgd_addr, 4); 901 if (via->polling != 0) { 902 ch->ptr = 0; 903 ch->prevptr = 0; 904 pollticks = ((uint64_t)hz * ch->blksz) / 905 ((uint64_t)sndbuf_getbps(ch->buffer) * 906 sndbuf_getspd(ch->buffer)); 907 pollticks >>= 2; 908 if (pollticks > hz) 909 pollticks = hz; 910 if (pollticks < 1) 911 pollticks = 1; 912 if (via_chan_active(via) == 0 || 913 pollticks < via->poll_ticks) { 914 if (bootverbose) { 915 if (via_chan_active(via) == 0) 916 printf("%s: pollticks=%d\n", 917 __func__, pollticks); 918 else 919 printf("%s: " 920 "pollticks %d -> %d\n", 921 __func__, via->poll_ticks, 922 pollticks); 923 } 924 via->poll_ticks = pollticks; 925 callout_reset(&via->poll_timer, 1, 926 via_poll_callback, via); 927 } 928 } 929 via_wr(via, ch->rbase + VIA_RP_CONTROL, 930 SGD_CONTROL_START | SGD_CONTROL_AUTOSTART | 931 ((via->polling == 0) ? 932 (SGD_CONTROL_I_EOL | SGD_CONTROL_I_FLAG) : 0), 1); 933 ch->active = 1; 934 break; 935 case PCMTRIG_STOP: 936 case PCMTRIG_ABORT: 937 via_wr(via, ch->rbase + VIA_RP_CONTROL, SGD_CONTROL_STOP, 1); 938 via8233chan_mute(via, ch, 1); 939 via8233chan_reset(via, ch); 940 ch->active = 0; 941 if (via->polling != 0) { 942 if (via_chan_active(via) == 0) { 943 callout_stop(&via->poll_timer); 944 via->poll_ticks = 1; 945 } else { 946 pollticks = via_poll_ticks(via); 947 if (pollticks > via->poll_ticks) { 948 if (bootverbose) 949 printf("%s: pollticks " 950 "%d -> %d\n", 951 __func__, via->poll_ticks, 952 pollticks); 953 via->poll_ticks = pollticks; 954 callout_reset(&via->poll_timer, 955 1, via_poll_callback, 956 via); 957 } 958 } 959 } 960 break; 961 default: 962 break; 963 } 964 snd_mtxunlock(via->lock); 965 return (0); 966 } 967 968 static kobj_method_t via8233wr_methods[] = { 969 KOBJMETHOD(channel_init, via8233wr_init), 970 KOBJMETHOD(channel_setformat, via8233wr_setformat), 971 KOBJMETHOD(channel_setspeed, via8233wr_setspeed), 972 KOBJMETHOD(channel_getcaps, via8233wr_getcaps), 973 KOBJMETHOD(channel_setblocksize, via8233chan_setblocksize), 974 KOBJMETHOD(channel_setfragments, via8233chan_setfragments), 975 KOBJMETHOD(channel_trigger, via8233chan_trigger), 976 KOBJMETHOD(channel_getptr, via8233chan_getptr), 977 { 0, 0 } 978 }; 979 CHANNEL_DECLARE(via8233wr); 980 981 static kobj_method_t via8233dxs_methods[] = { 982 KOBJMETHOD(channel_init, via8233dxs_init), 983 KOBJMETHOD(channel_setformat, via8233dxs_setformat), 984 KOBJMETHOD(channel_setspeed, via8233dxs_setspeed), 985 KOBJMETHOD(channel_getcaps, via8233dxs_getcaps), 986 KOBJMETHOD(channel_setblocksize, via8233chan_setblocksize), 987 KOBJMETHOD(channel_setfragments, via8233chan_setfragments), 988 KOBJMETHOD(channel_trigger, via8233chan_trigger), 989 KOBJMETHOD(channel_getptr, via8233chan_getptr), 990 { 0, 0 } 991 }; 992 CHANNEL_DECLARE(via8233dxs); 993 994 static kobj_method_t via8233msgd_methods[] = { 995 KOBJMETHOD(channel_init, via8233msgd_init), 996 KOBJMETHOD(channel_setformat, via8233msgd_setformat), 997 KOBJMETHOD(channel_setspeed, via8233msgd_setspeed), 998 KOBJMETHOD(channel_getcaps, via8233msgd_getcaps), 999 KOBJMETHOD(channel_setblocksize, via8233chan_setblocksize), 1000 KOBJMETHOD(channel_setfragments, via8233chan_setfragments), 1001 KOBJMETHOD(channel_trigger, via8233chan_trigger), 1002 KOBJMETHOD(channel_getptr, via8233chan_getptr), 1003 { 0, 0 } 1004 }; 1005 CHANNEL_DECLARE(via8233msgd); 1006 1007 /* -------------------------------------------------------------------- */ 1008 1009 static void 1010 via_intr(void *p) 1011 { 1012 struct via_info *via = p; 1013 uint32_t ptrigger = 0, rtrigger = 0; 1014 int i, reg, stat; 1015 1016 snd_mtxlock(via->lock); 1017 if (via->polling != 0) { 1018 snd_mtxunlock(via->lock); 1019 return; 1020 } 1021 /* Poll playback channels */ 1022 for (i = 0; i < NDXSCHANS + NMSGDCHANS; i++) { 1023 if (via->pch[i].channel == NULL || via->pch[i].active == 0) 1024 continue; 1025 reg = via->pch[i].rbase + VIA_RP_STATUS; 1026 stat = via_rd(via, reg, 1); 1027 if (stat & SGD_STATUS_INTR) { 1028 if (via->dma_eol_wake && ((stat & SGD_STATUS_EOL) || 1029 !(stat & SGD_STATUS_ACTIVE))) 1030 via_wr(via, via->pch[i].rbase + VIA_RP_CONTROL, 1031 SGD_CONTROL_START | SGD_CONTROL_AUTOSTART | 1032 SGD_CONTROL_I_EOL | SGD_CONTROL_I_FLAG, 1); 1033 via_wr(via, reg, stat, 1); 1034 ptrigger |= 1 << i; 1035 } 1036 } 1037 /* Poll record channels */ 1038 for (i = 0; i < NWRCHANS; i++) { 1039 if (via->rch[i].channel == NULL || via->rch[i].active == 0) 1040 continue; 1041 reg = via->rch[i].rbase + VIA_RP_STATUS; 1042 stat = via_rd(via, reg, 1); 1043 if (stat & SGD_STATUS_INTR) { 1044 if (via->dma_eol_wake && ((stat & SGD_STATUS_EOL) || 1045 !(stat & SGD_STATUS_ACTIVE))) 1046 via_wr(via, via->rch[i].rbase + VIA_RP_CONTROL, 1047 SGD_CONTROL_START | SGD_CONTROL_AUTOSTART | 1048 SGD_CONTROL_I_EOL | SGD_CONTROL_I_FLAG, 1); 1049 via_wr(via, reg, stat, 1); 1050 rtrigger |= 1 << i; 1051 } 1052 } 1053 snd_mtxunlock(via->lock); 1054 1055 for (i = 0; i < NDXSCHANS + NMSGDCHANS; i++) { 1056 if (ptrigger & (1 << i)) 1057 chn_intr(via->pch[i].channel); 1058 } 1059 for (i = 0; i < NWRCHANS; i++) { 1060 if (rtrigger & (1 << i)) 1061 chn_intr(via->rch[i].channel); 1062 } 1063 } 1064 1065 /* 1066 * Probe and attach the card 1067 */ 1068 static int 1069 via_probe(device_t dev) 1070 { 1071 switch(pci_get_devid(dev)) { 1072 case VIA8233_PCI_ID: 1073 switch(pci_get_revid(dev)) { 1074 case VIA8233_REV_ID_8233PRE: 1075 device_set_desc(dev, "VIA VT8233 (pre)"); 1076 return (BUS_PROBE_DEFAULT); 1077 case VIA8233_REV_ID_8233C: 1078 device_set_desc(dev, "VIA VT8233C"); 1079 return (BUS_PROBE_DEFAULT); 1080 case VIA8233_REV_ID_8233: 1081 device_set_desc(dev, "VIA VT8233"); 1082 return (BUS_PROBE_DEFAULT); 1083 case VIA8233_REV_ID_8233A: 1084 device_set_desc(dev, "VIA VT8233A"); 1085 return (BUS_PROBE_DEFAULT); 1086 case VIA8233_REV_ID_8235: 1087 device_set_desc(dev, "VIA VT8235"); 1088 return (BUS_PROBE_DEFAULT); 1089 case VIA8233_REV_ID_8237: 1090 device_set_desc(dev, "VIA VT8237"); 1091 return (BUS_PROBE_DEFAULT); 1092 case VIA8233_REV_ID_8251: 1093 device_set_desc(dev, "VIA VT8251"); 1094 return (BUS_PROBE_DEFAULT); 1095 default: 1096 device_set_desc(dev, "VIA VT8233X"); /* Unknown */ 1097 return (BUS_PROBE_DEFAULT); 1098 } 1099 } 1100 return (ENXIO); 1101 } 1102 1103 static void 1104 dma_cb(void *p, bus_dma_segment_t *bds, int a, int b) 1105 { 1106 struct via_info *via = (struct via_info *)p; 1107 via->sgd_addr = bds->ds_addr; 1108 } 1109 1110 static int 1111 via_chip_init(device_t dev) 1112 { 1113 uint32_t data, cnt; 1114 1115 /* Wake up and reset AC97 if necessary */ 1116 data = pci_read_config(dev, VIA_PCI_ACLINK_STAT, 1); 1117 1118 if ((data & VIA_PCI_ACLINK_C00_READY) == 0) { 1119 /* Cold reset per ac97r2.3 spec (page 95) */ 1120 /* Assert low */ 1121 pci_write_config(dev, VIA_PCI_ACLINK_CTRL, 1122 VIA_PCI_ACLINK_EN, 1); 1123 /* Wait T_rst_low */ 1124 DELAY(100); 1125 /* Assert high */ 1126 pci_write_config(dev, VIA_PCI_ACLINK_CTRL, 1127 VIA_PCI_ACLINK_EN | VIA_PCI_ACLINK_NRST, 1); 1128 /* Wait T_rst2clk */ 1129 DELAY(5); 1130 /* Assert low */ 1131 pci_write_config(dev, VIA_PCI_ACLINK_CTRL, 1132 VIA_PCI_ACLINK_EN, 1); 1133 } else { 1134 /* Warm reset */ 1135 /* Force no sync */ 1136 pci_write_config(dev, VIA_PCI_ACLINK_CTRL, 1137 VIA_PCI_ACLINK_EN, 1); 1138 DELAY(100); 1139 /* Sync */ 1140 pci_write_config(dev, VIA_PCI_ACLINK_CTRL, 1141 VIA_PCI_ACLINK_EN | VIA_PCI_ACLINK_SYNC, 1); 1142 /* Wait T_sync_high */ 1143 DELAY(5); 1144 /* Force no sync */ 1145 pci_write_config(dev, VIA_PCI_ACLINK_CTRL, 1146 VIA_PCI_ACLINK_EN, 1); 1147 /* Wait T_sync2clk */ 1148 DELAY(5); 1149 } 1150 1151 /* Power everything up */ 1152 pci_write_config(dev, VIA_PCI_ACLINK_CTRL, VIA_PCI_ACLINK_DESIRED, 1); 1153 1154 /* Wait for codec to become ready (largest reported delay 310ms) */ 1155 for (cnt = 0; cnt < 2000; cnt++) { 1156 data = pci_read_config(dev, VIA_PCI_ACLINK_STAT, 1); 1157 if (data & VIA_PCI_ACLINK_C00_READY) 1158 return (0); 1159 DELAY(5000); 1160 } 1161 device_printf(dev, "primary codec not ready (cnt = 0x%02x)\n", cnt); 1162 return (ENXIO); 1163 } 1164 1165 static int 1166 via_attach(device_t dev) 1167 { 1168 struct via_info *via = 0; 1169 char status[SND_STATUSLEN]; 1170 int i, via_dxs_disabled, via_dxs_src, via_dxs_chnum, via_sgd_chnum; 1171 int nsegs; 1172 uint32_t revid; 1173 1174 via = malloc(sizeof *via, M_DEVBUF, M_WAITOK | M_ZERO); 1175 via->lock = snd_mtxcreate(device_get_nameunit(dev), 1176 "snd_via8233 softc"); 1177 via->dev = dev; 1178 1179 callout_init(&via->poll_timer, CALLOUT_MPSAFE); 1180 via->poll_ticks = 1; 1181 1182 if (resource_int_value(device_get_name(dev), 1183 device_get_unit(dev), "polling", &i) == 0 && i != 0) 1184 via->polling = 1; 1185 else 1186 via->polling = 0; 1187 1188 pci_set_powerstate(dev, PCI_POWERSTATE_D0); 1189 pci_enable_busmaster(dev); 1190 1191 via->regid = PCIR_BAR(0); 1192 via->reg = bus_alloc_resource_any(dev, SYS_RES_IOPORT, &via->regid, 1193 RF_ACTIVE); 1194 if (!via->reg) { 1195 device_printf(dev, "cannot allocate bus resource."); 1196 goto bad; 1197 } 1198 via->st = rman_get_bustag(via->reg); 1199 via->sh = rman_get_bushandle(via->reg); 1200 1201 via->irqid = 0; 1202 via->irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &via->irqid, 1203 RF_ACTIVE | RF_SHAREABLE); 1204 if (!via->irq || 1205 snd_setup_intr(dev, via->irq, INTR_MPSAFE, 1206 via_intr, via, &via->ih)) { 1207 device_printf(dev, "unable to map interrupt\n"); 1208 goto bad; 1209 } 1210 1211 via->bufsz = pcm_getbuffersize(dev, 4096, VIA_DEFAULT_BUFSZ, 65536); 1212 if (resource_int_value(device_get_name(dev), 1213 device_get_unit(dev), "blocksize", &i) == 0 && i > 0) { 1214 i &= VIA_BLK_ALIGN; 1215 if (i < VIA_BLK_MIN) 1216 i = VIA_BLK_MIN; 1217 via->blkcnt = via->bufsz / i; 1218 i = 0; 1219 while (via->blkcnt >> i) 1220 i++; 1221 via->blkcnt = 1 << (i - 1); 1222 if (via->blkcnt < VIA_SEGS_MIN) 1223 via->blkcnt = VIA_SEGS_MIN; 1224 else if (via->blkcnt > VIA_SEGS_MAX) 1225 via->blkcnt = VIA_SEGS_MAX; 1226 1227 } else 1228 via->blkcnt = VIA_SEGS_DEFAULT; 1229 1230 revid = pci_get_revid(dev); 1231 1232 /* 1233 * VIA8251 lost its interrupt after DMA EOL, and need 1234 * a gentle spank on its face within interrupt handler. 1235 */ 1236 if (revid == VIA8233_REV_ID_8251) 1237 via->dma_eol_wake = 1; 1238 else 1239 via->dma_eol_wake = 0; 1240 1241 /* 1242 * Decide whether DXS had to be disabled or not 1243 */ 1244 if (revid == VIA8233_REV_ID_8233A) { 1245 /* 1246 * DXS channel is disabled. Reports from multiple users 1247 * that it plays at half-speed. Do not see this behaviour 1248 * on available 8233C or when emulating 8233A register set 1249 * on 8233C (either with or without ac97 VRA). 1250 */ 1251 via_dxs_disabled = 1; 1252 } else if (resource_int_value(device_get_name(dev), 1253 device_get_unit(dev), "via_dxs_disabled", 1254 &via_dxs_disabled) == 0) 1255 via_dxs_disabled = (via_dxs_disabled > 0) ? 1 : 0; 1256 else 1257 via_dxs_disabled = 0; 1258 1259 if (via_dxs_disabled) { 1260 via_dxs_chnum = 0; 1261 via_sgd_chnum = 1; 1262 } else { 1263 if (resource_int_value(device_get_name(dev), 1264 device_get_unit(dev), "via_dxs_channels", 1265 &via_dxs_chnum) != 0) 1266 via_dxs_chnum = NDXSCHANS; 1267 if (resource_int_value(device_get_name(dev), 1268 device_get_unit(dev), "via_sgd_channels", 1269 &via_sgd_chnum) != 0) 1270 via_sgd_chnum = NMSGDCHANS; 1271 } 1272 if (via_dxs_chnum > NDXSCHANS) 1273 via_dxs_chnum = NDXSCHANS; 1274 else if (via_dxs_chnum < 0) 1275 via_dxs_chnum = 0; 1276 if (via_sgd_chnum > NMSGDCHANS) 1277 via_sgd_chnum = NMSGDCHANS; 1278 else if (via_sgd_chnum < 0) 1279 via_sgd_chnum = 0; 1280 if (via_dxs_chnum + via_sgd_chnum < 1) { 1281 /* Minimalist ? */ 1282 via_dxs_chnum = 1; 1283 via_sgd_chnum = 0; 1284 } 1285 if (via_dxs_chnum > 0 && resource_int_value(device_get_name(dev), 1286 device_get_unit(dev), "via_dxs_src", &via_dxs_src) == 0) 1287 via->dxs_src = (via_dxs_src > 0) ? 1 : 0; 1288 else 1289 via->dxs_src = 0; 1290 1291 nsegs = (via_dxs_chnum + via_sgd_chnum + NWRCHANS) * VIA_SEGS_MAX; 1292 1293 /* DMA tag for buffers */ 1294 if (bus_dma_tag_create(/*parent*/bus_get_dma_tag(dev), /*alignment*/2, 1295 /*boundary*/0, 1296 /*lowaddr*/BUS_SPACE_MAXADDR_32BIT, 1297 /*highaddr*/BUS_SPACE_MAXADDR, 1298 /*filter*/NULL, /*filterarg*/NULL, 1299 /*maxsize*/via->bufsz, /*nsegments*/1, /*maxsegz*/0x3ffff, 1300 /*flags*/0, /*lockfunc*/NULL, 1301 /*lockarg*/NULL, &via->parent_dmat) != 0) { 1302 device_printf(dev, "unable to create dma tag\n"); 1303 goto bad; 1304 } 1305 1306 /* 1307 * DMA tag for SGD table. The 686 uses scatter/gather DMA and 1308 * requires a list in memory of work to do. We need only 16 bytes 1309 * for this list, and it is wasteful to allocate 16K. 1310 */ 1311 if (bus_dma_tag_create(/*parent*/bus_get_dma_tag(dev), /*alignment*/2, 1312 /*boundary*/0, 1313 /*lowaddr*/BUS_SPACE_MAXADDR_32BIT, 1314 /*highaddr*/BUS_SPACE_MAXADDR, 1315 /*filter*/NULL, /*filterarg*/NULL, 1316 /*maxsize*/nsegs * sizeof(struct via_dma_op), 1317 /*nsegments*/1, /*maxsegz*/0x3ffff, 1318 /*flags*/0, /*lockfunc*/NULL, 1319 /*lockarg*/NULL, &via->sgd_dmat) != 0) { 1320 device_printf(dev, "unable to create dma tag\n"); 1321 goto bad; 1322 } 1323 1324 if (bus_dmamem_alloc(via->sgd_dmat, (void **)&via->sgd_table, 1325 BUS_DMA_NOWAIT, &via->sgd_dmamap) == -1) 1326 goto bad; 1327 if (bus_dmamap_load(via->sgd_dmat, via->sgd_dmamap, via->sgd_table, 1328 nsegs * sizeof(struct via_dma_op), dma_cb, via, 0)) 1329 goto bad; 1330 1331 if (via_chip_init(dev)) 1332 goto bad; 1333 1334 via->codec = AC97_CREATE(dev, via, via_ac97); 1335 if (!via->codec) 1336 goto bad; 1337 1338 mixer_init(dev, ac97_getmixerclass(), via->codec); 1339 1340 via->codec_caps = ac97_getextcaps(via->codec); 1341 1342 /* Try to set VRA without generating an error, VRM not reqrd yet */ 1343 if (via->codec_caps & 1344 (AC97_EXTCAP_VRA | AC97_EXTCAP_VRM | AC97_EXTCAP_DRA)) { 1345 uint16_t ext = ac97_getextmode(via->codec); 1346 ext |= (via->codec_caps & 1347 (AC97_EXTCAP_VRA | AC97_EXTCAP_VRM)); 1348 ext &= ~AC97_EXTCAP_DRA; 1349 ac97_setextmode(via->codec, ext); 1350 } 1351 1352 snprintf(status, SND_STATUSLEN, "at io 0x%lx irq %ld %s", 1353 rman_get_start(via->reg), rman_get_start(via->irq), 1354 PCM_KLDSTRING(snd_via8233)); 1355 1356 /* Register */ 1357 if (pcm_register(dev, via, via_dxs_chnum + via_sgd_chnum, NWRCHANS)) 1358 goto bad; 1359 for (i = 0; i < via_dxs_chnum; i++) 1360 pcm_addchan(dev, PCMDIR_PLAY, &via8233dxs_class, via); 1361 for (i = 0; i < via_sgd_chnum; i++) 1362 pcm_addchan(dev, PCMDIR_PLAY, &via8233msgd_class, via); 1363 for (i = 0; i < NWRCHANS; i++) 1364 pcm_addchan(dev, PCMDIR_REC, &via8233wr_class, via); 1365 if (via_dxs_chnum > 0) 1366 via_init_sysctls(dev); 1367 device_printf(dev, "<VIA DXS %sabled: DXS%s %d / SGD %d / REC %d>\n", 1368 (via_dxs_chnum > 0) ? "En" : "Dis", (via->dxs_src) ? "(SRC)" : "", 1369 via_dxs_chnum, via_sgd_chnum, NWRCHANS); 1370 1371 pcm_setstatus(dev, status); 1372 1373 return (0); 1374 bad: 1375 if (via->codec) 1376 ac97_destroy(via->codec); 1377 if (via->reg) 1378 bus_release_resource(dev, SYS_RES_IOPORT, via->regid, via->reg); 1379 if (via->ih) 1380 bus_teardown_intr(dev, via->irq, via->ih); 1381 if (via->irq) 1382 bus_release_resource(dev, SYS_RES_IRQ, via->irqid, via->irq); 1383 if (via->parent_dmat) 1384 bus_dma_tag_destroy(via->parent_dmat); 1385 if (via->sgd_dmamap) 1386 bus_dmamap_unload(via->sgd_dmat, via->sgd_dmamap); 1387 if (via->sgd_table) 1388 bus_dmamem_free(via->sgd_dmat, via->sgd_table, via->sgd_dmamap); 1389 if (via->sgd_dmat) 1390 bus_dma_tag_destroy(via->sgd_dmat); 1391 if (via->lock) 1392 snd_mtxfree(via->lock); 1393 if (via) 1394 free(via, M_DEVBUF); 1395 return (ENXIO); 1396 } 1397 1398 static int 1399 via_detach(device_t dev) 1400 { 1401 int r; 1402 struct via_info *via; 1403 1404 r = pcm_unregister(dev); 1405 if (r) 1406 return (r); 1407 1408 via = pcm_getdevinfo(dev); 1409 1410 if (via != NULL && (via->play_num != 0 || via->rec_num != 0)) { 1411 snd_mtxlock(via->lock); 1412 via->polling = 0; 1413 callout_stop(&via->poll_timer); 1414 snd_mtxunlock(via->lock); 1415 callout_drain(&via->poll_timer); 1416 } 1417 1418 bus_release_resource(dev, SYS_RES_IOPORT, via->regid, via->reg); 1419 bus_teardown_intr(dev, via->irq, via->ih); 1420 bus_release_resource(dev, SYS_RES_IRQ, via->irqid, via->irq); 1421 bus_dma_tag_destroy(via->parent_dmat); 1422 bus_dmamap_unload(via->sgd_dmat, via->sgd_dmamap); 1423 bus_dmamem_free(via->sgd_dmat, via->sgd_table, via->sgd_dmamap); 1424 bus_dma_tag_destroy(via->sgd_dmat); 1425 snd_mtxfree(via->lock); 1426 free(via, M_DEVBUF); 1427 return (0); 1428 } 1429 1430 1431 static device_method_t via_methods[] = { 1432 DEVMETHOD(device_probe, via_probe), 1433 DEVMETHOD(device_attach, via_attach), 1434 DEVMETHOD(device_detach, via_detach), 1435 { 0, 0} 1436 }; 1437 1438 static driver_t via_driver = { 1439 "pcm", 1440 via_methods, 1441 PCM_SOFTC_SIZE, 1442 }; 1443 1444 DRIVER_MODULE(snd_via8233, pci, via_driver, pcm_devclass, 0, 0); 1445 MODULE_DEPEND(snd_via8233, sound, SOUND_MINVER, SOUND_PREFVER, SOUND_MAXVER); 1446 MODULE_VERSION(snd_via8233, 1); 1447