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 #ifdef HAVE_KERNEL_OPTION_HEADERS 39 #include "opt_snd.h" 40 #endif 41 42 #include <dev/sound/pcm/sound.h> 43 #include <dev/sound/pcm/ac97.h> 44 45 #include <dev/pci/pcireg.h> 46 #include <dev/pci/pcivar.h> 47 #include <sys/sysctl.h> 48 49 #include <dev/sound/pci/via8233.h> 50 51 SND_DECLARE_FILE("$FreeBSD$"); 52 53 #define VIA8233_PCI_ID 0x30591106 54 55 #define VIA8233_REV_ID_8233PRE 0x10 56 #define VIA8233_REV_ID_8233C 0x20 57 #define VIA8233_REV_ID_8233 0x30 58 #define VIA8233_REV_ID_8233A 0x40 59 #define VIA8233_REV_ID_8235 0x50 60 #define VIA8233_REV_ID_8237 0x60 61 #define VIA8233_REV_ID_8251 0x70 62 63 #define SEGS_PER_CHAN 2 /* Segments per channel */ 64 #define NDXSCHANS 4 /* No of DXS channels */ 65 #define NMSGDCHANS 1 /* No of multichannel SGD */ 66 #define NWRCHANS 1 /* No of write channels */ 67 #define NCHANS (NWRCHANS + NDXSCHANS + NMSGDCHANS) 68 #define NSEGS NCHANS * SEGS_PER_CHAN /* Segments in SGD table */ 69 #define VIA_SEGS_MIN 2 70 #define VIA_SEGS_MAX 64 71 #define VIA_SEGS_DEFAULT 2 72 #define VIA_BLK_MIN 32 73 #define VIA_BLK_ALIGN (~(VIA_BLK_MIN - 1)) 74 75 #define VIA_DEFAULT_BUFSZ 0x1000 76 77 /* we rely on this struct being packed to 64 bits */ 78 struct via_dma_op { 79 volatile uint32_t ptr; 80 volatile uint32_t flags; 81 #define VIA_DMAOP_EOL 0x80000000 82 #define VIA_DMAOP_FLAG 0x40000000 83 #define VIA_DMAOP_STOP 0x20000000 84 #define VIA_DMAOP_COUNT(x) ((x)&0x00FFFFFF) 85 }; 86 87 struct via_info; 88 89 struct via_chinfo { 90 struct via_info *parent; 91 struct pcm_channel *channel; 92 struct snd_dbuf *buffer; 93 struct via_dma_op *sgd_table; 94 bus_addr_t sgd_addr; 95 int dir, rbase, active; 96 unsigned int blksz, blkcnt; 97 unsigned int ptr, prevptr; 98 }; 99 100 struct via_info { 101 device_t dev; 102 103 bus_space_tag_t st; 104 bus_space_handle_t sh; 105 bus_dma_tag_t parent_dmat; 106 bus_dma_tag_t sgd_dmat; 107 bus_dmamap_t sgd_dmamap; 108 bus_addr_t sgd_addr; 109 110 struct resource *reg, *irq; 111 int regid, irqid; 112 void *ih; 113 struct ac97_info *codec; 114 115 unsigned int bufsz, blkcnt; 116 int dxs_src, dma_eol_wake; 117 118 struct via_chinfo pch[NDXSCHANS + NMSGDCHANS]; 119 struct via_chinfo rch[NWRCHANS]; 120 struct via_dma_op *sgd_table; 121 uint16_t codec_caps; 122 uint16_t n_dxs_registered; 123 int play_num, rec_num; 124 struct mtx *lock; 125 struct callout poll_timer; 126 int poll_ticks, polling; 127 }; 128 129 static uint32_t via_fmt[] = { 130 SND_FORMAT(AFMT_U8, 1, 0), 131 SND_FORMAT(AFMT_U8, 2, 0), 132 SND_FORMAT(AFMT_S16_LE, 1, 0), 133 SND_FORMAT(AFMT_S16_LE, 2, 0), 134 0 135 }; 136 137 static struct pcmchan_caps via_vracaps = { 4000, 48000, via_fmt, 0 }; 138 static struct pcmchan_caps via_caps = { 48000, 48000, via_fmt, 0 }; 139 140 static __inline int 141 via_chan_active(struct via_info *via) 142 { 143 int i, ret = 0; 144 145 if (via == NULL) 146 return (0); 147 148 for (i = 0; i < NDXSCHANS + NMSGDCHANS; i++) 149 ret += via->pch[i].active; 150 151 for (i = 0; i < NWRCHANS; i++) 152 ret += via->rch[i].active; 153 154 return (ret); 155 } 156 157 static int 158 sysctl_via8233_spdif_enable(SYSCTL_HANDLER_ARGS) 159 { 160 struct via_info *via; 161 device_t dev; 162 uint32_t r; 163 int err, new_en; 164 165 dev = oidp->oid_arg1; 166 via = pcm_getdevinfo(dev); 167 snd_mtxlock(via->lock); 168 r = pci_read_config(dev, VIA_PCI_SPDIF, 1); 169 snd_mtxunlock(via->lock); 170 new_en = (r & VIA_SPDIF_EN) ? 1 : 0; 171 err = sysctl_handle_int(oidp, &new_en, 0, req); 172 173 if (err || req->newptr == NULL) 174 return (err); 175 if (new_en < 0 || new_en > 1) 176 return (EINVAL); 177 178 if (new_en) 179 r |= VIA_SPDIF_EN; 180 else 181 r &= ~VIA_SPDIF_EN; 182 snd_mtxlock(via->lock); 183 pci_write_config(dev, VIA_PCI_SPDIF, r, 1); 184 snd_mtxunlock(via->lock); 185 186 return (0); 187 } 188 189 static int 190 sysctl_via8233_dxs_src(SYSCTL_HANDLER_ARGS) 191 { 192 struct via_info *via; 193 device_t dev; 194 int err, val; 195 196 dev = oidp->oid_arg1; 197 via = pcm_getdevinfo(dev); 198 snd_mtxlock(via->lock); 199 val = via->dxs_src; 200 snd_mtxunlock(via->lock); 201 err = sysctl_handle_int(oidp, &val, 0, req); 202 203 if (err || req->newptr == NULL) 204 return (err); 205 if (val < 0 || val > 1) 206 return (EINVAL); 207 208 snd_mtxlock(via->lock); 209 via->dxs_src = val; 210 snd_mtxunlock(via->lock); 211 212 return (0); 213 } 214 215 static int 216 sysctl_via_polling(SYSCTL_HANDLER_ARGS) 217 { 218 struct via_info *via; 219 device_t dev; 220 int err, val; 221 222 dev = oidp->oid_arg1; 223 via = pcm_getdevinfo(dev); 224 if (via == NULL) 225 return (EINVAL); 226 snd_mtxlock(via->lock); 227 val = via->polling; 228 snd_mtxunlock(via->lock); 229 err = sysctl_handle_int(oidp, &val, 0, req); 230 231 if (err || req->newptr == NULL) 232 return (err); 233 if (val < 0 || val > 1) 234 return (EINVAL); 235 236 snd_mtxlock(via->lock); 237 if (val != via->polling) { 238 if (via_chan_active(via) != 0) 239 err = EBUSY; 240 else if (val == 0) 241 via->polling = 0; 242 else 243 via->polling = 1; 244 } 245 snd_mtxunlock(via->lock); 246 247 return (err); 248 } 249 250 static void 251 via_init_sysctls(device_t dev) 252 { 253 /* XXX: an user should be able to set this with a control tool, 254 if not done before 7.0-RELEASE, this needs to be converted to 255 a device specific sysctl "dev.pcm.X.yyy" via device_get_sysctl_*() 256 as discussed on multimedia@ in msg-id <861wujij2q.fsf@xps.des.no> */ 257 SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev), 258 SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, 259 "spdif_enabled", CTLTYPE_INT | CTLFLAG_RW, dev, sizeof(dev), 260 sysctl_via8233_spdif_enable, "I", 261 "Enable S/PDIF output on primary playback channel"); 262 SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev), 263 SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, 264 "dxs_src", CTLTYPE_INT | CTLFLAG_RW, dev, sizeof(dev), 265 sysctl_via8233_dxs_src, "I", 266 "Enable VIA DXS Sample Rate Converter"); 267 SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev), 268 SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, 269 "polling", CTLTYPE_INT | CTLFLAG_RW, dev, sizeof(dev), 270 sysctl_via_polling, "I", 271 "Enable polling mode"); 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 KOBJMETHOD_END 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 (AFMT_CHANNEL(format) > 1) 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 (AFMT_CHANNEL(format) > 1) 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 (AFMT_CHANNEL(format) > 1) { 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 uint32_t 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 uint32_t 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 uint32_t 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 (0); 600 } 601 602 static uint32_t 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 uint32_t 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, ptr; 619 620 snd_mtxlock(via->lock); 621 if (via->polling != 0) { 622 ptr = ch->ptr; 623 snd_mtxunlock(via->lock); 624 } else { 625 v = via_rd(via, ch->rbase + VIA_RP_CURRENT_COUNT, 4); 626 snd_mtxunlock(via->lock); 627 index = v >> 24; /* Last completed buffer */ 628 count = v & 0x00ffffff; /* Bytes remaining */ 629 ptr = (index + 1) * ch->blksz - count; 630 ptr %= ch->blkcnt * ch->blksz; /* Wrap to available space */ 631 } 632 633 return (ptr); 634 } 635 636 static void 637 via8233chan_reset(struct via_info *via, struct via_chinfo *ch) 638 { 639 via_wr(via, ch->rbase + VIA_RP_CONTROL, SGD_CONTROL_STOP, 1); 640 via_wr(via, ch->rbase + VIA_RP_CONTROL, 0x00, 1); 641 via_wr(via, ch->rbase + VIA_RP_STATUS, 642 SGD_STATUS_EOL | SGD_STATUS_FLAG, 1); 643 } 644 645 /* -------------------------------------------------------------------- */ 646 /* Channel initialization functions */ 647 648 static void 649 via8233chan_sgdinit(struct via_info *via, struct via_chinfo *ch, int chnum) 650 { 651 ch->sgd_table = &via->sgd_table[chnum * VIA_SEGS_MAX]; 652 ch->sgd_addr = via->sgd_addr + chnum * VIA_SEGS_MAX * 653 sizeof(struct via_dma_op); 654 } 655 656 static void* 657 via8233wr_init(kobj_t obj, void *devinfo, struct snd_dbuf *b, 658 struct pcm_channel *c, int dir) 659 { 660 struct via_info *via = devinfo; 661 struct via_chinfo *ch; 662 int num; 663 664 snd_mtxlock(via->lock); 665 num = via->rec_num++; 666 ch = &via->rch[num]; 667 ch->parent = via; 668 ch->channel = c; 669 ch->buffer = b; 670 ch->dir = dir; 671 ch->blkcnt = via->blkcnt; 672 ch->rbase = VIA_WR_BASE(num); 673 via_wr(via, ch->rbase + VIA_WR_RP_SGD_FORMAT, WR_FIFO_ENABLE, 1); 674 snd_mtxunlock(via->lock); 675 676 if (sndbuf_alloc(ch->buffer, via->parent_dmat, 0, via->bufsz) != 0) 677 return (NULL); 678 679 snd_mtxlock(via->lock); 680 via8233chan_sgdinit(via, ch, num); 681 via8233chan_reset(via, ch); 682 snd_mtxunlock(via->lock); 683 684 return (ch); 685 } 686 687 static void* 688 via8233dxs_init(kobj_t obj, void *devinfo, struct snd_dbuf *b, 689 struct pcm_channel *c, int dir) 690 { 691 struct via_info *via = devinfo; 692 struct via_chinfo *ch; 693 int num; 694 695 snd_mtxlock(via->lock); 696 num = via->play_num++; 697 ch = &via->pch[num]; 698 ch->parent = via; 699 ch->channel = c; 700 ch->buffer = b; 701 ch->dir = dir; 702 ch->blkcnt = via->blkcnt; 703 704 /* 705 * All cards apparently support DXS3, but not other DXS 706 * channels. We therefore want to align first DXS channel to 707 * DXS3. 708 */ 709 ch->rbase = VIA_DXS_BASE(NDXSCHANS - 1 - via->n_dxs_registered); 710 via->n_dxs_registered++; 711 snd_mtxunlock(via->lock); 712 713 if (sndbuf_alloc(ch->buffer, via->parent_dmat, 0, via->bufsz) != 0) 714 return (NULL); 715 716 snd_mtxlock(via->lock); 717 via8233chan_sgdinit(via, ch, NWRCHANS + num); 718 via8233chan_reset(via, ch); 719 snd_mtxunlock(via->lock); 720 721 return (ch); 722 } 723 724 static void* 725 via8233msgd_init(kobj_t obj, void *devinfo, struct snd_dbuf *b, 726 struct pcm_channel *c, int dir) 727 { 728 struct via_info *via = devinfo; 729 struct via_chinfo *ch; 730 int num; 731 732 snd_mtxlock(via->lock); 733 num = via->play_num++; 734 ch = &via->pch[num]; 735 ch->parent = via; 736 ch->channel = c; 737 ch->buffer = b; 738 ch->dir = dir; 739 ch->rbase = VIA_MC_SGD_STATUS; 740 ch->blkcnt = via->blkcnt; 741 snd_mtxunlock(via->lock); 742 743 if (sndbuf_alloc(ch->buffer, via->parent_dmat, 0, via->bufsz) != 0) 744 return (NULL); 745 746 snd_mtxlock(via->lock); 747 via8233chan_sgdinit(via, ch, NWRCHANS + num); 748 via8233chan_reset(via, ch); 749 snd_mtxunlock(via->lock); 750 751 return (ch); 752 } 753 754 static void 755 via8233chan_mute(struct via_info *via, struct via_chinfo *ch, int muted) 756 { 757 if (BASE_IS_VIA_DXS_REG(ch->rbase)) { 758 int r; 759 muted = (muted) ? VIA8233_DXS_MUTE : 0; 760 via_wr(via, ch->rbase + VIA8233_RP_DXS_LVOL, muted, 1); 761 via_wr(via, ch->rbase + VIA8233_RP_DXS_RVOL, muted, 1); 762 r = via_rd(via, ch->rbase + VIA8233_RP_DXS_LVOL, 1) & 763 VIA8233_DXS_MUTE; 764 if (r != muted) 765 device_printf(via->dev, 766 "%s: failed to set dxs volume " 767 "(dxs base 0x%02x).\n", __func__, ch->rbase); 768 } 769 } 770 771 static __inline int 772 via_poll_channel(struct via_chinfo *ch) 773 { 774 struct via_info *via; 775 uint32_t sz, delta; 776 uint32_t v, index, count; 777 int ptr; 778 779 if (ch == NULL || ch->channel == NULL || ch->active == 0) 780 return (0); 781 782 via = ch->parent; 783 sz = ch->blksz * ch->blkcnt; 784 v = via_rd(via, ch->rbase + VIA_RP_CURRENT_COUNT, 4); 785 index = v >> 24; 786 count = v & 0x00ffffff; 787 ptr = ((index + 1) * ch->blksz) - count; 788 ptr %= sz; 789 ptr &= ~(ch->blksz - 1); 790 ch->ptr = ptr; 791 delta = (sz + ptr - ch->prevptr) % sz; 792 793 if (delta < ch->blksz) 794 return (0); 795 796 ch->prevptr = ptr; 797 798 return (1); 799 } 800 801 static void 802 via_poll_callback(void *arg) 803 { 804 struct via_info *via = arg; 805 uint32_t ptrigger = 0, rtrigger = 0; 806 int i; 807 808 if (via == NULL) 809 return; 810 811 snd_mtxlock(via->lock); 812 if (via->polling == 0 || via_chan_active(via) == 0) { 813 snd_mtxunlock(via->lock); 814 return; 815 } 816 817 for (i = 0; i < NDXSCHANS + NMSGDCHANS; i++) 818 ptrigger |= (via_poll_channel(&via->pch[i]) != 0) ? 819 (1 << i) : 0; 820 821 for (i = 0; i < NWRCHANS; i++) 822 rtrigger |= (via_poll_channel(&via->rch[i]) != 0) ? 823 (1 << i) : 0; 824 825 /* XXX */ 826 callout_reset(&via->poll_timer, 1/*via->poll_ticks*/, 827 via_poll_callback, via); 828 829 snd_mtxunlock(via->lock); 830 831 for (i = 0; i < NDXSCHANS + NMSGDCHANS; i++) { 832 if (ptrigger & (1 << i)) 833 chn_intr(via->pch[i].channel); 834 } 835 for (i = 0; i < NWRCHANS; i++) { 836 if (rtrigger & (1 << i)) 837 chn_intr(via->rch[i].channel); 838 } 839 } 840 841 static int 842 via_poll_ticks(struct via_info *via) 843 { 844 struct via_chinfo *ch; 845 int i; 846 int ret = hz; 847 int pollticks; 848 849 for (i = 0; i < NDXSCHANS + NMSGDCHANS; i++) { 850 ch = &via->pch[i]; 851 if (ch->channel == NULL || ch->active == 0) 852 continue; 853 pollticks = ((uint64_t)hz * ch->blksz) / 854 ((uint64_t)sndbuf_getalign(ch->buffer) * 855 sndbuf_getspd(ch->buffer)); 856 pollticks >>= 2; 857 if (pollticks > hz) 858 pollticks = hz; 859 if (pollticks < 1) 860 pollticks = 1; 861 if (pollticks < ret) 862 ret = pollticks; 863 } 864 865 for (i = 0; i < NWRCHANS; i++) { 866 ch = &via->rch[i]; 867 if (ch->channel == NULL || ch->active == 0) 868 continue; 869 pollticks = ((uint64_t)hz * ch->blksz) / 870 ((uint64_t)sndbuf_getalign(ch->buffer) * 871 sndbuf_getspd(ch->buffer)); 872 pollticks >>= 2; 873 if (pollticks > hz) 874 pollticks = hz; 875 if (pollticks < 1) 876 pollticks = 1; 877 if (pollticks < ret) 878 ret = pollticks; 879 } 880 881 return (ret); 882 } 883 884 static int 885 via8233chan_trigger(kobj_t obj, void* data, int go) 886 { 887 struct via_chinfo *ch = data; 888 struct via_info *via = ch->parent; 889 int pollticks; 890 891 if (!PCMTRIG_COMMON(go)) 892 return (0); 893 894 snd_mtxlock(via->lock); 895 switch(go) { 896 case PCMTRIG_START: 897 via_buildsgdt(ch); 898 via8233chan_mute(via, ch, 0); 899 via_wr(via, ch->rbase + VIA_RP_TABLE_PTR, ch->sgd_addr, 4); 900 if (via->polling != 0) { 901 ch->ptr = 0; 902 ch->prevptr = 0; 903 pollticks = ((uint64_t)hz * ch->blksz) / 904 ((uint64_t)sndbuf_getalign(ch->buffer) * 905 sndbuf_getspd(ch->buffer)); 906 pollticks >>= 2; 907 if (pollticks > hz) 908 pollticks = hz; 909 if (pollticks < 1) 910 pollticks = 1; 911 if (via_chan_active(via) == 0 || 912 pollticks < via->poll_ticks) { 913 if (bootverbose) { 914 if (via_chan_active(via) == 0) 915 printf("%s: pollticks=%d\n", 916 __func__, pollticks); 917 else 918 printf("%s: " 919 "pollticks %d -> %d\n", 920 __func__, via->poll_ticks, 921 pollticks); 922 } 923 via->poll_ticks = pollticks; 924 callout_reset(&via->poll_timer, 1, 925 via_poll_callback, via); 926 } 927 } 928 via_wr(via, ch->rbase + VIA_RP_CONTROL, 929 SGD_CONTROL_START | SGD_CONTROL_AUTOSTART | 930 ((via->polling == 0) ? 931 (SGD_CONTROL_I_EOL | SGD_CONTROL_I_FLAG) : 0), 1); 932 ch->active = 1; 933 break; 934 case PCMTRIG_STOP: 935 case PCMTRIG_ABORT: 936 via_wr(via, ch->rbase + VIA_RP_CONTROL, SGD_CONTROL_STOP, 1); 937 via8233chan_mute(via, ch, 1); 938 via8233chan_reset(via, ch); 939 ch->active = 0; 940 if (via->polling != 0) { 941 if (via_chan_active(via) == 0) { 942 callout_stop(&via->poll_timer); 943 via->poll_ticks = 1; 944 } else { 945 pollticks = via_poll_ticks(via); 946 if (pollticks > via->poll_ticks) { 947 if (bootverbose) 948 printf("%s: pollticks " 949 "%d -> %d\n", 950 __func__, via->poll_ticks, 951 pollticks); 952 via->poll_ticks = pollticks; 953 callout_reset(&via->poll_timer, 954 1, via_poll_callback, 955 via); 956 } 957 } 958 } 959 break; 960 default: 961 break; 962 } 963 snd_mtxunlock(via->lock); 964 return (0); 965 } 966 967 static kobj_method_t via8233wr_methods[] = { 968 KOBJMETHOD(channel_init, via8233wr_init), 969 KOBJMETHOD(channel_setformat, via8233wr_setformat), 970 KOBJMETHOD(channel_setspeed, via8233wr_setspeed), 971 KOBJMETHOD(channel_getcaps, via8233wr_getcaps), 972 KOBJMETHOD(channel_setblocksize, via8233chan_setblocksize), 973 KOBJMETHOD(channel_setfragments, via8233chan_setfragments), 974 KOBJMETHOD(channel_trigger, via8233chan_trigger), 975 KOBJMETHOD(channel_getptr, via8233chan_getptr), 976 KOBJMETHOD_END 977 }; 978 CHANNEL_DECLARE(via8233wr); 979 980 static kobj_method_t via8233dxs_methods[] = { 981 KOBJMETHOD(channel_init, via8233dxs_init), 982 KOBJMETHOD(channel_setformat, via8233dxs_setformat), 983 KOBJMETHOD(channel_setspeed, via8233dxs_setspeed), 984 KOBJMETHOD(channel_getcaps, via8233dxs_getcaps), 985 KOBJMETHOD(channel_setblocksize, via8233chan_setblocksize), 986 KOBJMETHOD(channel_setfragments, via8233chan_setfragments), 987 KOBJMETHOD(channel_trigger, via8233chan_trigger), 988 KOBJMETHOD(channel_getptr, via8233chan_getptr), 989 KOBJMETHOD_END 990 }; 991 CHANNEL_DECLARE(via8233dxs); 992 993 static kobj_method_t via8233msgd_methods[] = { 994 KOBJMETHOD(channel_init, via8233msgd_init), 995 KOBJMETHOD(channel_setformat, via8233msgd_setformat), 996 KOBJMETHOD(channel_setspeed, via8233msgd_setspeed), 997 KOBJMETHOD(channel_getcaps, via8233msgd_getcaps), 998 KOBJMETHOD(channel_setblocksize, via8233chan_setblocksize), 999 KOBJMETHOD(channel_setfragments, via8233chan_setfragments), 1000 KOBJMETHOD(channel_trigger, via8233chan_trigger), 1001 KOBJMETHOD(channel_getptr, via8233chan_getptr), 1002 KOBJMETHOD_END 1003 }; 1004 CHANNEL_DECLARE(via8233msgd); 1005 1006 /* -------------------------------------------------------------------- */ 1007 1008 static void 1009 via_intr(void *p) 1010 { 1011 struct via_info *via = p; 1012 uint32_t ptrigger = 0, rtrigger = 0; 1013 int i, reg, stat; 1014 1015 snd_mtxlock(via->lock); 1016 if (via->polling != 0) { 1017 snd_mtxunlock(via->lock); 1018 return; 1019 } 1020 /* Poll playback channels */ 1021 for (i = 0; i < NDXSCHANS + NMSGDCHANS; i++) { 1022 if (via->pch[i].channel == NULL || via->pch[i].active == 0) 1023 continue; 1024 reg = via->pch[i].rbase + VIA_RP_STATUS; 1025 stat = via_rd(via, reg, 1); 1026 if (stat & SGD_STATUS_INTR) { 1027 if (via->dma_eol_wake && ((stat & SGD_STATUS_EOL) || 1028 !(stat & SGD_STATUS_ACTIVE))) 1029 via_wr(via, via->pch[i].rbase + VIA_RP_CONTROL, 1030 SGD_CONTROL_START | SGD_CONTROL_AUTOSTART | 1031 SGD_CONTROL_I_EOL | SGD_CONTROL_I_FLAG, 1); 1032 via_wr(via, reg, stat, 1); 1033 ptrigger |= 1 << i; 1034 } 1035 } 1036 /* Poll record channels */ 1037 for (i = 0; i < NWRCHANS; i++) { 1038 if (via->rch[i].channel == NULL || via->rch[i].active == 0) 1039 continue; 1040 reg = via->rch[i].rbase + VIA_RP_STATUS; 1041 stat = via_rd(via, reg, 1); 1042 if (stat & SGD_STATUS_INTR) { 1043 if (via->dma_eol_wake && ((stat & SGD_STATUS_EOL) || 1044 !(stat & SGD_STATUS_ACTIVE))) 1045 via_wr(via, via->rch[i].rbase + VIA_RP_CONTROL, 1046 SGD_CONTROL_START | SGD_CONTROL_AUTOSTART | 1047 SGD_CONTROL_I_EOL | SGD_CONTROL_I_FLAG, 1); 1048 via_wr(via, reg, stat, 1); 1049 rtrigger |= 1 << i; 1050 } 1051 } 1052 snd_mtxunlock(via->lock); 1053 1054 for (i = 0; i < NDXSCHANS + NMSGDCHANS; i++) { 1055 if (ptrigger & (1 << i)) 1056 chn_intr(via->pch[i].channel); 1057 } 1058 for (i = 0; i < NWRCHANS; i++) { 1059 if (rtrigger & (1 << i)) 1060 chn_intr(via->rch[i].channel); 1061 } 1062 } 1063 1064 /* 1065 * Probe and attach the card 1066 */ 1067 static int 1068 via_probe(device_t dev) 1069 { 1070 switch(pci_get_devid(dev)) { 1071 case VIA8233_PCI_ID: 1072 switch(pci_get_revid(dev)) { 1073 case VIA8233_REV_ID_8233PRE: 1074 device_set_desc(dev, "VIA VT8233 (pre)"); 1075 return (BUS_PROBE_DEFAULT); 1076 case VIA8233_REV_ID_8233C: 1077 device_set_desc(dev, "VIA VT8233C"); 1078 return (BUS_PROBE_DEFAULT); 1079 case VIA8233_REV_ID_8233: 1080 device_set_desc(dev, "VIA VT8233"); 1081 return (BUS_PROBE_DEFAULT); 1082 case VIA8233_REV_ID_8233A: 1083 device_set_desc(dev, "VIA VT8233A"); 1084 return (BUS_PROBE_DEFAULT); 1085 case VIA8233_REV_ID_8235: 1086 device_set_desc(dev, "VIA VT8235"); 1087 return (BUS_PROBE_DEFAULT); 1088 case VIA8233_REV_ID_8237: 1089 device_set_desc(dev, "VIA VT8237"); 1090 return (BUS_PROBE_DEFAULT); 1091 case VIA8233_REV_ID_8251: 1092 device_set_desc(dev, "VIA VT8251"); 1093 return (BUS_PROBE_DEFAULT); 1094 default: 1095 device_set_desc(dev, "VIA VT8233X"); /* Unknown */ 1096 return (BUS_PROBE_DEFAULT); 1097 } 1098 } 1099 return (ENXIO); 1100 } 1101 1102 static void 1103 dma_cb(void *p, bus_dma_segment_t *bds, int a, int b) 1104 { 1105 struct via_info *via = (struct via_info *)p; 1106 via->sgd_addr = bds->ds_addr; 1107 } 1108 1109 static int 1110 via_chip_init(device_t dev) 1111 { 1112 uint32_t data, cnt; 1113 1114 /* Wake up and reset AC97 if necessary */ 1115 data = pci_read_config(dev, VIA_PCI_ACLINK_STAT, 1); 1116 1117 if ((data & VIA_PCI_ACLINK_C00_READY) == 0) { 1118 /* Cold reset per ac97r2.3 spec (page 95) */ 1119 /* Assert low */ 1120 pci_write_config(dev, VIA_PCI_ACLINK_CTRL, 1121 VIA_PCI_ACLINK_EN, 1); 1122 /* Wait T_rst_low */ 1123 DELAY(100); 1124 /* Assert high */ 1125 pci_write_config(dev, VIA_PCI_ACLINK_CTRL, 1126 VIA_PCI_ACLINK_EN | VIA_PCI_ACLINK_NRST, 1); 1127 /* Wait T_rst2clk */ 1128 DELAY(5); 1129 /* Assert low */ 1130 pci_write_config(dev, VIA_PCI_ACLINK_CTRL, 1131 VIA_PCI_ACLINK_EN, 1); 1132 } else { 1133 /* Warm reset */ 1134 /* Force no sync */ 1135 pci_write_config(dev, VIA_PCI_ACLINK_CTRL, 1136 VIA_PCI_ACLINK_EN, 1); 1137 DELAY(100); 1138 /* Sync */ 1139 pci_write_config(dev, VIA_PCI_ACLINK_CTRL, 1140 VIA_PCI_ACLINK_EN | VIA_PCI_ACLINK_SYNC, 1); 1141 /* Wait T_sync_high */ 1142 DELAY(5); 1143 /* Force no sync */ 1144 pci_write_config(dev, VIA_PCI_ACLINK_CTRL, 1145 VIA_PCI_ACLINK_EN, 1); 1146 /* Wait T_sync2clk */ 1147 DELAY(5); 1148 } 1149 1150 /* Power everything up */ 1151 pci_write_config(dev, VIA_PCI_ACLINK_CTRL, VIA_PCI_ACLINK_DESIRED, 1); 1152 1153 /* Wait for codec to become ready (largest reported delay 310ms) */ 1154 for (cnt = 0; cnt < 2000; cnt++) { 1155 data = pci_read_config(dev, VIA_PCI_ACLINK_STAT, 1); 1156 if (data & VIA_PCI_ACLINK_C00_READY) 1157 return (0); 1158 DELAY(5000); 1159 } 1160 device_printf(dev, "primary codec not ready (cnt = 0x%02x)\n", cnt); 1161 return (ENXIO); 1162 } 1163 1164 static int 1165 via_attach(device_t dev) 1166 { 1167 struct via_info *via = NULL; 1168 char status[SND_STATUSLEN]; 1169 int i, via_dxs_disabled, via_dxs_src, via_dxs_chnum, via_sgd_chnum; 1170 int nsegs; 1171 uint32_t revid; 1172 1173 via = malloc(sizeof *via, M_DEVBUF, M_WAITOK | M_ZERO); 1174 via->lock = snd_mtxcreate(device_get_nameunit(dev), 1175 "snd_via8233 softc"); 1176 via->dev = dev; 1177 1178 callout_init(&via->poll_timer, 1); 1179 via->poll_ticks = 1; 1180 1181 if (resource_int_value(device_get_name(dev), 1182 device_get_unit(dev), "polling", &i) == 0 && i != 0) 1183 via->polling = 1; 1184 else 1185 via->polling = 0; 1186 1187 pci_set_powerstate(dev, PCI_POWERSTATE_D0); 1188 pci_enable_busmaster(dev); 1189 1190 via->regid = PCIR_BAR(0); 1191 via->reg = bus_alloc_resource_any(dev, SYS_RES_IOPORT, &via->regid, 1192 RF_ACTIVE); 1193 if (!via->reg) { 1194 device_printf(dev, "cannot allocate bus resource."); 1195 goto bad; 1196 } 1197 via->st = rman_get_bustag(via->reg); 1198 via->sh = rman_get_bushandle(via->reg); 1199 1200 via->irqid = 0; 1201 via->irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &via->irqid, 1202 RF_ACTIVE | RF_SHAREABLE); 1203 if (!via->irq || 1204 snd_setup_intr(dev, via->irq, INTR_MPSAFE, 1205 via_intr, via, &via->ih)) { 1206 device_printf(dev, "unable to map interrupt\n"); 1207 goto bad; 1208 } 1209 1210 via->bufsz = pcm_getbuffersize(dev, 4096, VIA_DEFAULT_BUFSZ, 65536); 1211 if (resource_int_value(device_get_name(dev), 1212 device_get_unit(dev), "blocksize", &i) == 0 && i > 0) { 1213 i &= VIA_BLK_ALIGN; 1214 if (i < VIA_BLK_MIN) 1215 i = VIA_BLK_MIN; 1216 via->blkcnt = via->bufsz / i; 1217 i = 0; 1218 while (via->blkcnt >> i) 1219 i++; 1220 via->blkcnt = 1 << (i - 1); 1221 if (via->blkcnt < VIA_SEGS_MIN) 1222 via->blkcnt = VIA_SEGS_MIN; 1223 else if (via->blkcnt > VIA_SEGS_MAX) 1224 via->blkcnt = VIA_SEGS_MAX; 1225 1226 } else 1227 via->blkcnt = VIA_SEGS_DEFAULT; 1228 1229 revid = pci_get_revid(dev); 1230 1231 /* 1232 * VIA8251 lost its interrupt after DMA EOL, and need 1233 * a gentle spank on its face within interrupt handler. 1234 */ 1235 if (revid == VIA8233_REV_ID_8251) 1236 via->dma_eol_wake = 1; 1237 else 1238 via->dma_eol_wake = 0; 1239 1240 /* 1241 * Decide whether DXS had to be disabled or not 1242 */ 1243 if (revid == VIA8233_REV_ID_8233A) { 1244 /* 1245 * DXS channel is disabled. Reports from multiple users 1246 * that it plays at half-speed. Do not see this behaviour 1247 * on available 8233C or when emulating 8233A register set 1248 * on 8233C (either with or without ac97 VRA). 1249 */ 1250 via_dxs_disabled = 1; 1251 } else if (resource_int_value(device_get_name(dev), 1252 device_get_unit(dev), "via_dxs_disabled", 1253 &via_dxs_disabled) == 0) 1254 via_dxs_disabled = (via_dxs_disabled > 0) ? 1 : 0; 1255 else 1256 via_dxs_disabled = 0; 1257 1258 if (via_dxs_disabled) { 1259 via_dxs_chnum = 0; 1260 via_sgd_chnum = 1; 1261 } else { 1262 if (resource_int_value(device_get_name(dev), 1263 device_get_unit(dev), "via_dxs_channels", 1264 &via_dxs_chnum) != 0) 1265 via_dxs_chnum = NDXSCHANS; 1266 if (resource_int_value(device_get_name(dev), 1267 device_get_unit(dev), "via_sgd_channels", 1268 &via_sgd_chnum) != 0) 1269 via_sgd_chnum = NMSGDCHANS; 1270 } 1271 if (via_dxs_chnum > NDXSCHANS) 1272 via_dxs_chnum = NDXSCHANS; 1273 else if (via_dxs_chnum < 0) 1274 via_dxs_chnum = 0; 1275 if (via_sgd_chnum > NMSGDCHANS) 1276 via_sgd_chnum = NMSGDCHANS; 1277 else if (via_sgd_chnum < 0) 1278 via_sgd_chnum = 0; 1279 if (via_dxs_chnum + via_sgd_chnum < 1) { 1280 /* Minimalist ? */ 1281 via_dxs_chnum = 1; 1282 via_sgd_chnum = 0; 1283 } 1284 if (via_dxs_chnum > 0 && resource_int_value(device_get_name(dev), 1285 device_get_unit(dev), "via_dxs_src", &via_dxs_src) == 0) 1286 via->dxs_src = (via_dxs_src > 0) ? 1 : 0; 1287 else 1288 via->dxs_src = 0; 1289 1290 nsegs = (via_dxs_chnum + via_sgd_chnum + NWRCHANS) * VIA_SEGS_MAX; 1291 1292 /* DMA tag for buffers */ 1293 if (bus_dma_tag_create(/*parent*/bus_get_dma_tag(dev), /*alignment*/2, 1294 /*boundary*/0, 1295 /*lowaddr*/BUS_SPACE_MAXADDR_32BIT, 1296 /*highaddr*/BUS_SPACE_MAXADDR, 1297 /*filter*/NULL, /*filterarg*/NULL, 1298 /*maxsize*/via->bufsz, /*nsegments*/1, /*maxsegz*/0x3ffff, 1299 /*flags*/0, /*lockfunc*/NULL, 1300 /*lockarg*/NULL, &via->parent_dmat) != 0) { 1301 device_printf(dev, "unable to create dma tag\n"); 1302 goto bad; 1303 } 1304 1305 /* 1306 * DMA tag for SGD table. The 686 uses scatter/gather DMA and 1307 * requires a list in memory of work to do. We need only 16 bytes 1308 * for this list, and it is wasteful to allocate 16K. 1309 */ 1310 if (bus_dma_tag_create(/*parent*/bus_get_dma_tag(dev), /*alignment*/2, 1311 /*boundary*/0, 1312 /*lowaddr*/BUS_SPACE_MAXADDR_32BIT, 1313 /*highaddr*/BUS_SPACE_MAXADDR, 1314 /*filter*/NULL, /*filterarg*/NULL, 1315 /*maxsize*/nsegs * sizeof(struct via_dma_op), 1316 /*nsegments*/1, /*maxsegz*/0x3ffff, 1317 /*flags*/0, /*lockfunc*/NULL, 1318 /*lockarg*/NULL, &via->sgd_dmat) != 0) { 1319 device_printf(dev, "unable to create dma tag\n"); 1320 goto bad; 1321 } 1322 1323 if (bus_dmamem_alloc(via->sgd_dmat, (void **)&via->sgd_table, 1324 BUS_DMA_NOWAIT, &via->sgd_dmamap) == -1) 1325 goto bad; 1326 if (bus_dmamap_load(via->sgd_dmat, via->sgd_dmamap, via->sgd_table, 1327 nsegs * sizeof(struct via_dma_op), dma_cb, via, 0)) 1328 goto bad; 1329 1330 if (via_chip_init(dev)) 1331 goto bad; 1332 1333 via->codec = AC97_CREATE(dev, via, via_ac97); 1334 if (!via->codec) 1335 goto bad; 1336 1337 mixer_init(dev, ac97_getmixerclass(), via->codec); 1338 1339 via->codec_caps = ac97_getextcaps(via->codec); 1340 1341 /* Try to set VRA without generating an error, VRM not reqrd yet */ 1342 if (via->codec_caps & 1343 (AC97_EXTCAP_VRA | AC97_EXTCAP_VRM | AC97_EXTCAP_DRA)) { 1344 uint16_t ext = ac97_getextmode(via->codec); 1345 ext |= (via->codec_caps & 1346 (AC97_EXTCAP_VRA | AC97_EXTCAP_VRM)); 1347 ext &= ~AC97_EXTCAP_DRA; 1348 ac97_setextmode(via->codec, ext); 1349 } 1350 1351 snprintf(status, SND_STATUSLEN, "at io 0x%jx irq %jd %s", 1352 rman_get_start(via->reg), rman_get_start(via->irq), 1353 PCM_KLDSTRING(snd_via8233)); 1354 1355 /* Register */ 1356 if (pcm_register(dev, via, via_dxs_chnum + via_sgd_chnum, NWRCHANS)) 1357 goto bad; 1358 for (i = 0; i < via_dxs_chnum; i++) 1359 pcm_addchan(dev, PCMDIR_PLAY, &via8233dxs_class, via); 1360 for (i = 0; i < via_sgd_chnum; i++) 1361 pcm_addchan(dev, PCMDIR_PLAY, &via8233msgd_class, via); 1362 for (i = 0; i < NWRCHANS; i++) 1363 pcm_addchan(dev, PCMDIR_REC, &via8233wr_class, via); 1364 if (via_dxs_chnum > 0) 1365 via_init_sysctls(dev); 1366 device_printf(dev, "<VIA DXS %sabled: DXS%s %d / SGD %d / REC %d>\n", 1367 (via_dxs_chnum > 0) ? "En" : "Dis", (via->dxs_src) ? "(SRC)" : "", 1368 via_dxs_chnum, via_sgd_chnum, NWRCHANS); 1369 1370 pcm_setstatus(dev, status); 1371 1372 return (0); 1373 bad: 1374 if (via->codec) 1375 ac97_destroy(via->codec); 1376 if (via->reg) 1377 bus_release_resource(dev, SYS_RES_IOPORT, via->regid, via->reg); 1378 if (via->ih) 1379 bus_teardown_intr(dev, via->irq, via->ih); 1380 if (via->irq) 1381 bus_release_resource(dev, SYS_RES_IRQ, via->irqid, via->irq); 1382 if (via->parent_dmat) 1383 bus_dma_tag_destroy(via->parent_dmat); 1384 if (via->sgd_addr) 1385 bus_dmamap_unload(via->sgd_dmat, via->sgd_dmamap); 1386 if (via->sgd_table) 1387 bus_dmamem_free(via->sgd_dmat, via->sgd_table, via->sgd_dmamap); 1388 if (via->sgd_dmat) 1389 bus_dma_tag_destroy(via->sgd_dmat); 1390 if (via->lock) 1391 snd_mtxfree(via->lock); 1392 if (via) 1393 free(via, M_DEVBUF); 1394 return (ENXIO); 1395 } 1396 1397 static int 1398 via_detach(device_t dev) 1399 { 1400 int r; 1401 struct via_info *via; 1402 1403 r = pcm_unregister(dev); 1404 if (r) 1405 return (r); 1406 1407 via = pcm_getdevinfo(dev); 1408 1409 if (via != NULL && (via->play_num != 0 || via->rec_num != 0)) { 1410 snd_mtxlock(via->lock); 1411 via->polling = 0; 1412 callout_stop(&via->poll_timer); 1413 snd_mtxunlock(via->lock); 1414 callout_drain(&via->poll_timer); 1415 } 1416 1417 bus_release_resource(dev, SYS_RES_IOPORT, via->regid, via->reg); 1418 bus_teardown_intr(dev, via->irq, via->ih); 1419 bus_release_resource(dev, SYS_RES_IRQ, via->irqid, via->irq); 1420 bus_dma_tag_destroy(via->parent_dmat); 1421 bus_dmamap_unload(via->sgd_dmat, via->sgd_dmamap); 1422 bus_dmamem_free(via->sgd_dmat, via->sgd_table, via->sgd_dmamap); 1423 bus_dma_tag_destroy(via->sgd_dmat); 1424 snd_mtxfree(via->lock); 1425 free(via, M_DEVBUF); 1426 return (0); 1427 } 1428 1429 1430 static device_method_t via_methods[] = { 1431 DEVMETHOD(device_probe, via_probe), 1432 DEVMETHOD(device_attach, via_attach), 1433 DEVMETHOD(device_detach, via_detach), 1434 { 0, 0} 1435 }; 1436 1437 static driver_t via_driver = { 1438 "pcm", 1439 via_methods, 1440 PCM_SOFTC_SIZE, 1441 }; 1442 1443 DRIVER_MODULE(snd_via8233, pci, via_driver, pcm_devclass, 0, 0); 1444 MODULE_DEPEND(snd_via8233, sound, SOUND_MINVER, SOUND_PREFVER, SOUND_MAXVER); 1445 MODULE_VERSION(snd_via8233, 1); 1446