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