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