1 /* 2 * Copyright (c) 2000 David Jones <dej@ox.org> 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 * 26 * $FreeBSD$ 27 */ 28 29 #include <dev/sound/pcm/sound.h> 30 #include <dev/sound/pcm/ac97.h> 31 32 #include <pci/pcireg.h> 33 #include <pci/pcivar.h> 34 #include <sys/sysctl.h> 35 36 #include <dev/sound/pci/via82c686.h> 37 38 #define VIA_PCI_ID 0x30581106 39 #define NSEGS 16 /* Number of segments in SGD table */ 40 41 #define SEGS_PER_CHAN (NSEGS/2) 42 43 #undef DEB 44 #define DEB(x) 45 46 struct via_info; 47 48 struct via_chinfo { 49 struct via_info *parent; 50 pcm_channel *channel; 51 snd_dbuf *buffer; 52 int dir; 53 }; 54 55 struct via_info { 56 bus_space_tag_t st; 57 bus_space_handle_t sh; 58 bus_dma_tag_t parent_dmat; 59 bus_dma_tag_t sgd_dmat; 60 61 struct resource *reg, *irq; 62 int regid, irqid; 63 void *ih; 64 65 struct via_chinfo pch, rch; 66 struct via_dma_op *sgd_table; 67 u_int16_t codec_caps; 68 }; 69 70 static u_int32_t via_rd(struct via_info *via, int regno, int size); 71 static void via_wr(struct via_info *, int regno, u_int32_t data, int size); 72 73 int via_waitready_codec(struct via_info *via); 74 int via_waitvalid_codec(struct via_info *via); 75 u_int32_t via_read_codec(void *addr, int reg); 76 void via_write_codec(void *addr, int reg, u_int32_t val); 77 78 static void via_intr(void *); 79 bus_dmamap_callback_t dma_cb; 80 81 82 /* channel interface */ 83 static void *viachan_init(void *devinfo, snd_dbuf *b, pcm_channel *c, int dir); 84 static int viachan_setdir(void *data, int dir); 85 static int viachan_setformat(void *data, u_int32_t format); 86 static int viachan_setspeed(void *data, u_int32_t speed); 87 static int viachan_setblocksize(void *data, u_int32_t blocksize); 88 static int viachan_trigger(void *data, int go); 89 static int viachan_getptr(void *data); 90 static pcmchan_caps *viachan_getcaps(void *data); 91 92 static u_int32_t via_playfmt[] = { 93 AFMT_U8, 94 AFMT_STEREO | AFMT_U8, 95 AFMT_S16_LE, 96 AFMT_STEREO | AFMT_S16_LE, 97 0 98 }; 99 static pcmchan_caps via_playcaps = {4000, 48000, via_playfmt, 0}; 100 101 static u_int32_t via_recfmt[] = { 102 AFMT_U8, 103 AFMT_STEREO | AFMT_U8, 104 AFMT_S16_LE, 105 AFMT_STEREO | AFMT_S16_LE, 106 0 107 }; 108 static pcmchan_caps via_reccaps = {4000, 48000, via_recfmt, 0}; 109 110 static pcm_channel via_chantemplate = { 111 viachan_init, 112 viachan_setdir, 113 viachan_setformat, 114 viachan_setspeed, 115 viachan_setblocksize, 116 viachan_trigger, 117 viachan_getptr, 118 viachan_getcaps, 119 NULL, /* free */ 120 NULL, /* nop1 */ 121 NULL, /* nop2 */ 122 NULL, /* nop3 */ 123 NULL, /* nop4 */ 124 NULL, /* nop5 */ 125 NULL, /* nop6 */ 126 NULL, /* nop7 */ 127 }; 128 129 130 /* 131 * Probe and attach the card 132 */ 133 static int 134 via_probe(device_t dev) 135 { 136 if (pci_get_devid(dev) == VIA_PCI_ID) { 137 device_set_desc(dev, "VIA VT82C686A AC'97 Audio"); 138 return 0; 139 } 140 return ENXIO; 141 } 142 143 144 void dma_cb(void *p, bus_dma_segment_t *bds, int a, int b) 145 { 146 } 147 148 149 static int 150 via_attach(device_t dev) 151 { 152 struct via_info *via = 0; 153 struct ac97_info *codec = 0; 154 char status[SND_STATUSLEN]; 155 156 u_int32_t data; 157 158 u_int16_t v; 159 bus_dmamap_t sgd_dma_map; 160 161 if ((via = malloc(sizeof *via, M_DEVBUF, M_NOWAIT)) == NULL) { 162 device_printf(dev, "cannot allocate softc\n"); 163 return ENXIO; 164 } 165 bzero(via, sizeof *via); 166 167 /* Get resources */ 168 data = pci_read_config(dev, PCIR_COMMAND, 2); 169 data |= (PCIM_CMD_PORTEN | PCIM_CMD_BUSMASTEREN); 170 pci_write_config(dev, PCIR_COMMAND, data, 2); 171 data = pci_read_config(dev, PCIR_COMMAND, 2); 172 173 pci_write_config(dev, VIA_PCICONF_MISC, 174 VIA_PCICONF_ACLINKENAB | VIA_PCICONF_ACSGD | 175 VIA_PCICONF_ACNOTRST | VIA_PCICONF_ACVSR, 1); 176 177 via->regid = PCIR_MAPS; 178 via->reg = bus_alloc_resource(dev, SYS_RES_IOPORT, &via->regid, 179 0, ~0, 1, RF_ACTIVE); 180 if (!via->reg) { 181 device_printf(dev, "via: Cannot allocate bus resource."); 182 goto bad; 183 } 184 via->st = rman_get_bustag(via->reg); 185 via->sh = rman_get_bushandle(via->reg); 186 187 via->irqid = 0; 188 via->irq = bus_alloc_resource(dev, SYS_RES_IRQ, &via->irqid, 189 0, ~0, 1, RF_ACTIVE | RF_SHAREABLE); 190 if (!via->irq 191 || bus_setup_intr(dev, via->irq, INTR_TYPE_TTY, via_intr, via, &via->ih)){ 192 device_printf(dev, "unable to map interrupt\n"); 193 goto bad; 194 } 195 196 via_wr(via, VIA_PLAY_MODE, 197 VIA_RPMODE_AUTOSTART | 198 VIA_RPMODE_INTR_FLAG | VIA_RPMODE_INTR_EOL, 1); 199 via_wr(via, VIA_RECORD_MODE, 200 VIA_RPMODE_AUTOSTART | 201 VIA_RPMODE_INTR_FLAG | VIA_RPMODE_INTR_EOL, 1); 202 203 codec = ac97_create(dev, via, NULL, 204 via_read_codec, via_write_codec); 205 if (!codec) goto bad; 206 207 mixer_init(dev, &ac97_mixer, codec); 208 209 /* 210 * The mixer init resets the codec. So enabling VRA must be done 211 * afterwards. 212 */ 213 v = via_read_codec(via, AC97_REG_EXT_AUDIO_ID); 214 v &= (AC97_ENAB_VRA | AC97_ENAB_MICVRA); 215 via_write_codec(via, AC97_REG_EXT_AUDIO_STAT, v); 216 via->codec_caps = v; 217 { 218 v = via_read_codec(via, AC97_REG_EXT_AUDIO_STAT); 219 DEB(printf("init: codec stat: %d\n", v)); 220 } 221 222 if (!(v & AC97_CODEC_DOES_VRA)) { 223 /* no VRA => can do only 48 kbps */ 224 via_playcaps.minspeed = 48000; 225 via_reccaps.minspeed = 48000; 226 } 227 228 /* DMA tag for buffers */ 229 if (bus_dma_tag_create(/*parent*/NULL, /*alignment*/2, /*boundary*/0, 230 /*lowaddr*/BUS_SPACE_MAXADDR_32BIT, 231 /*highaddr*/BUS_SPACE_MAXADDR, 232 /*filter*/NULL, /*filterarg*/NULL, 233 /*maxsize*/VIA_BUFFSIZE, /*nsegments*/1, /*maxsegz*/0x3ffff, 234 /*flags*/0, &via->parent_dmat) != 0) { 235 device_printf(dev, "unable to create dma tag\n"); 236 goto bad; 237 } 238 239 /* 240 * DMA tag for SGD table. The 686 uses scatter/gather DMA and 241 * requires a list in memory of work to do. We need only 16 bytes 242 * for this list, and it is wasteful to allocate 16K. 243 */ 244 if (bus_dma_tag_create(/*parent*/NULL, /*alignment*/2, /*boundary*/0, 245 /*lowaddr*/BUS_SPACE_MAXADDR_32BIT, 246 /*highaddr*/BUS_SPACE_MAXADDR, 247 /*filter*/NULL, /*filterarg*/NULL, 248 /*maxsize*/NSEGS * sizeof(struct via_dma_op), 249 /*nsegments*/1, /*maxsegz*/0x3ffff, 250 /*flags*/0, &via->sgd_dmat) != 0) { 251 device_printf(dev, "unable to create dma tag\n"); 252 goto bad; 253 } 254 255 if (bus_dmamem_alloc(via->sgd_dmat, (void **)&via->sgd_table, 256 BUS_DMA_NOWAIT, &sgd_dma_map) == -1) goto bad; 257 if (bus_dmamap_load(via->sgd_dmat, sgd_dma_map, via->sgd_table, 258 NSEGS * sizeof(struct via_dma_op), dma_cb, 0, 0)) goto bad; 259 260 snprintf(status, SND_STATUSLEN, "at io 0x%lx irq %ld", 261 rman_get_start(via->reg), rman_get_start(via->irq)); 262 263 /* Register */ 264 if (pcm_register(dev, via, 1, 1)) goto bad; 265 pcm_addchan(dev, PCMDIR_PLAY, &via_chantemplate, via); 266 pcm_addchan(dev, PCMDIR_REC, &via_chantemplate, via); 267 pcm_setstatus(dev, status); 268 return 0; 269 bad: 270 if (codec) ac97_destroy(codec); 271 if (via->reg) bus_release_resource(dev, SYS_RES_IOPORT, via->regid, via->reg); 272 if (via->ih) bus_teardown_intr(dev, via->irq, via->ih); 273 if (via->irq) bus_release_resource(dev, SYS_RES_IRQ, via->irqid, via->irq); 274 if (via->parent_dmat) bus_dma_tag_destroy(via->parent_dmat); 275 if (via->sgd_dmat) bus_dma_tag_destroy(via->sgd_dmat); 276 if (via) free(via, M_DEVBUF); 277 return ENXIO; 278 } 279 280 static int 281 via_detach(device_t dev) 282 { 283 int r; 284 struct via_info *via = 0; 285 286 r = pcm_unregister(dev); 287 if (r) 288 return r; 289 290 via = pcm_getdevinfo(dev); 291 bus_release_resource(dev, SYS_RES_IOPORT, via->regid, via->reg); 292 bus_teardown_intr(dev, via->irq, via->ih); 293 bus_release_resource(dev, SYS_RES_IRQ, via->irqid, via->irq); 294 bus_dma_tag_destroy(via->parent_dmat); 295 bus_dma_tag_destroy(via->sgd_dmat); 296 free(via, M_DEVBUF); 297 return 0; 298 } 299 300 301 static device_method_t via_methods[] = { 302 DEVMETHOD(device_probe, via_probe), 303 DEVMETHOD(device_attach, via_attach), 304 DEVMETHOD(device_detach, via_detach), 305 { 0, 0} 306 }; 307 308 static driver_t via_driver = { 309 "pcm", 310 via_methods, 311 sizeof(snddev_info), 312 }; 313 314 static devclass_t pcm_devclass; 315 316 DRIVER_MODULE(via, pci, via_driver, pcm_devclass, 0, 0); 317 MODULE_DEPEND(via, snd_pcm, PCM_MINVER, PCM_PREFVER, PCM_MAXVER); 318 MODULE_VERSION(via, 1); 319 320 321 static u_int32_t 322 via_rd(struct via_info *via, int regno, int size) 323 { 324 325 switch (size) { 326 case 1: 327 return bus_space_read_1(via->st, via->sh, regno); 328 case 2: 329 return bus_space_read_2(via->st, via->sh, regno); 330 case 4: 331 return bus_space_read_4(via->st, via->sh, regno); 332 default: 333 return 0xFFFFFFFF; 334 } 335 } 336 337 338 static void 339 via_wr(struct via_info *via, int regno, u_int32_t data, int size) 340 { 341 342 switch (size) { 343 case 1: 344 bus_space_write_1(via->st, via->sh, regno, data); 345 break; 346 case 2: 347 bus_space_write_2(via->st, via->sh, regno, data); 348 break; 349 case 4: 350 bus_space_write_4(via->st, via->sh, regno, data); 351 break; 352 } 353 } 354 355 356 /* Codec interface */ 357 int 358 via_waitready_codec(struct via_info *via) 359 { 360 int i; 361 362 /* poll until codec not busy */ 363 for (i = 0; (i < TIMEOUT) && 364 (via_rd(via, VIA_CODEC_CTL, 4) & VIA_CODEC_BUSY); i++) 365 DELAY(1); 366 if (i >= TIMEOUT) { 367 printf("via: codec busy\n"); 368 return 1; 369 } 370 371 return 0; 372 } 373 374 375 int 376 via_waitvalid_codec(struct via_info *via) 377 { 378 int i; 379 380 /* poll until codec valid */ 381 for (i = 0; (i < TIMEOUT) && 382 !(via_rd(via, VIA_CODEC_CTL, 4) & VIA_CODEC_PRIVALID); i++) 383 DELAY(1); 384 if (i >= TIMEOUT) { 385 printf("via: codec invalid\n"); 386 return 1; 387 } 388 389 return 0; 390 } 391 392 393 void 394 via_write_codec(void *addr, int reg, u_int32_t val) 395 { 396 struct via_info *via = addr; 397 398 if (via_waitready_codec(via)) return; 399 400 via_wr(via, VIA_CODEC_CTL, 401 VIA_CODEC_PRIVALID | VIA_CODEC_INDEX(reg) | val, 4); 402 } 403 404 405 u_int32_t 406 via_read_codec(void *addr, int reg) 407 { 408 struct via_info *via = addr; 409 410 if (via_waitready_codec(via)) 411 return 1; 412 413 via_wr(via, VIA_CODEC_CTL, 414 VIA_CODEC_PRIVALID | VIA_CODEC_READ | VIA_CODEC_INDEX(reg),4); 415 416 if (via_waitready_codec(via)) 417 return 1; 418 419 if (via_waitvalid_codec(via)) 420 return 1; 421 422 return via_rd(via, VIA_CODEC_CTL, 2); 423 } 424 425 426 /* channel interface */ 427 static void * 428 viachan_init(void *devinfo, snd_dbuf *b, pcm_channel *c, int dir) 429 { 430 struct via_info *via = devinfo; 431 struct via_chinfo *ch = (dir == PCMDIR_PLAY) ? &via->pch : &via->rch; 432 433 ch->parent = via; 434 ch->channel = c; 435 ch->buffer = b; 436 b->bufsize = VIA_BUFFSIZE; 437 438 if (chn_allocbuf(ch->buffer, via->parent_dmat) == -1) return NULL; 439 return ch; 440 } 441 442 static int 443 viachan_setdir(void *data, int dir) 444 { 445 struct via_chinfo *ch = data; 446 struct via_info *via = ch->parent; 447 struct via_dma_op *ado; 448 int i, chunk_size; 449 int phys_addr, flag; 450 451 ch->dir = dir; 452 /* 453 * Build the scatter/gather DMA (SGD) table. 454 * There are four slots in the table: two for play, two for record. 455 * This creates two half-buffers, one of which is playing; the other 456 * is feeding. 457 */ 458 ado = via->sgd_table; 459 chunk_size = ch->buffer->bufsize / SEGS_PER_CHAN; 460 461 if (dir == PCMDIR_REC) { 462 ado += SEGS_PER_CHAN; 463 } 464 465 DEB(printf("SGD table located at va %p\n", ado)); 466 phys_addr = vtophys(ch->buffer->buf); 467 for (i = 0; i < SEGS_PER_CHAN; i++) { 468 ado->ptr = phys_addr; 469 flag = (i == SEGS_PER_CHAN-1) ? 470 VIA_DMAOP_EOL : VIA_DMAOP_FLAG; 471 ado->flags = flag | chunk_size; 472 DEB(printf("ado->ptr/flags = %x/%x\n", phys_addr, flag)); 473 phys_addr += chunk_size; 474 ado++; 475 } 476 return 0; 477 } 478 479 static int 480 viachan_setformat(void *data, u_int32_t format) 481 { 482 struct via_chinfo *ch = data; 483 struct via_info *via = ch->parent; 484 int mode, mode_set; 485 486 mode_set = 0; 487 if (format & AFMT_STEREO) 488 mode_set |= VIA_RPMODE_STEREO; 489 if (format & AFMT_S16_LE) 490 mode_set |= VIA_RPMODE_16BIT; 491 492 /* Set up for output format */ 493 if (ch->dir == PCMDIR_PLAY) { 494 DEB(printf("set play format: %x\n", format)); 495 mode = via_rd(via, VIA_PLAY_MODE, 1); 496 mode &= ~(VIA_RPMODE_16BIT | VIA_RPMODE_STEREO); 497 mode |= mode_set; 498 via_wr(via, VIA_PLAY_MODE, mode, 1); 499 } 500 else { 501 DEB(printf("set record format: %x\n", format)); 502 mode = via_rd(via, VIA_RECORD_MODE, 1); 503 mode &= ~(VIA_RPMODE_16BIT | VIA_RPMODE_STEREO); 504 mode |= mode_set; 505 via_wr(via, VIA_RECORD_MODE, mode, 1); 506 } 507 508 return 0; 509 } 510 511 static int 512 viachan_setspeed(void *data, u_int32_t speed) 513 { 514 struct via_chinfo *ch = data; 515 struct via_info *via = ch->parent; 516 517 /* 518 * Basic AC'97 defines a 48 kHz sample rate only. For other rates, 519 * upsampling is required. 520 * 521 * The VT82C686A does not perform upsampling, and neither do we. 522 * If the codec supports variable-rate audio (i.e. does the upsampling 523 * itself), then negotiate the rate with the codec. Otherwise, 524 * return 48 kHz cuz that's all you got. 525 */ 526 if (ch->dir == PCMDIR_PLAY) { 527 DEB(printf("requested play speed: %d\n", speed)); 528 if (via->codec_caps & AC97_CODEC_DOES_VRA) { 529 via_write_codec(via, AC97_REG_EXT_DAC_RATE, speed); 530 speed = via_read_codec(via, AC97_REG_EXT_DAC_RATE); 531 } 532 else { 533 DEB(printf("VRA not supported!\n")); 534 speed = 48000; 535 } 536 DEB(printf("obtained play speed: %d\n", speed)); 537 } 538 else { 539 DEB(printf("requested record speed: %d\n", speed)); 540 if (via->codec_caps & AC97_CODEC_DOES_VRA) { 541 via_write_codec(via, AC97_REG_EXT_ADC_RATE, speed); 542 speed = via_read_codec(via, AC97_REG_EXT_ADC_RATE); 543 } 544 else { 545 DEB(printf("VRA not supported!\n")); 546 speed = 48000; 547 } 548 DEB(printf("obtained record speed: %d\n", speed)); 549 } 550 return speed; 551 } 552 553 static int 554 viachan_setblocksize(void *data, u_int32_t blocksize) 555 { 556 struct via_chinfo *ch = data; 557 558 return ch->buffer->bufsize / 2; 559 } 560 561 static int 562 viachan_trigger(void *data, int go) 563 { 564 struct via_chinfo *ch = data; 565 struct via_info *via = ch->parent; 566 struct via_dma_op *ado; 567 568 if (go == PCMTRIG_EMLDMAWR || go == PCMTRIG_EMLDMARD) return 0; 569 if (ch->dir == PCMDIR_PLAY) { 570 if (go == PCMTRIG_START) { 571 ado = &via->sgd_table[0]; 572 DEB(printf("ado located at va=%p pa=%x\n", ado, vtophys(ado))); 573 via_wr(via, VIA_PLAY_DMAOPS_BASE, vtophys(ado),4); 574 via_wr(via, VIA_PLAY_CONTROL, 575 VIA_RPCTRL_START, 1); 576 } 577 else { 578 /* Stop DMA */ 579 via_wr(via, VIA_PLAY_CONTROL, 580 VIA_RPCTRL_TERMINATE, 1); 581 } 582 } else { 583 if (go == PCMTRIG_START) { 584 ado = &via->sgd_table[SEGS_PER_CHAN]; 585 DEB(printf("ado located at va=%p pa=%x\n", ado, vtophys(ado))); 586 via_wr(via, VIA_RECORD_DMAOPS_BASE, 587 vtophys(ado),4); 588 via_wr(via, VIA_RECORD_CONTROL, 589 VIA_RPCTRL_START, 1); 590 } 591 else { 592 /* Stop DMA */ 593 via_wr(via, VIA_RECORD_CONTROL, 594 VIA_RPCTRL_TERMINATE, 1); 595 } 596 } 597 598 DEB(printf("viachan_trigger: go=%d\n", go)); 599 return 0; 600 } 601 602 static int 603 viachan_getptr(void *data) 604 { 605 struct via_chinfo *ch = data; 606 struct via_info *via = ch->parent; 607 struct via_dma_op *ado; 608 int ptr, base, len, seg; 609 int base1; 610 611 if (ch->dir == PCMDIR_PLAY) { 612 ado = &via->sgd_table[0]; 613 base1 = via_rd(via, VIA_PLAY_DMAOPS_BASE, 4); 614 len = via_rd(via, VIA_PLAY_DMAOPS_COUNT, 4); 615 base = via_rd(via, VIA_PLAY_DMAOPS_BASE, 4); 616 if (base != base1) { /* Avoid race hazzard */ 617 len = via_rd(via, VIA_PLAY_DMAOPS_COUNT, 4); 618 } 619 DEB(printf("viachan_getptr: len / base = %x / %x\n", len, base)); 620 621 /* Base points to SGD segment to do, one past current */ 622 623 /* Determine how many segments have been done */ 624 seg = (base - vtophys(ado)) / sizeof(struct via_dma_op); 625 if (seg == 0) seg = SEGS_PER_CHAN; 626 627 /* Now work out offset: seg less count */ 628 ptr = seg * ch->buffer->bufsize / SEGS_PER_CHAN - len; 629 DEB(printf("return ptr=%d\n", ptr)); 630 return ptr; 631 } 632 else { 633 base1 = via_rd(via, VIA_RECORD_DMAOPS_BASE, 4); 634 ado = &via->sgd_table[SEGS_PER_CHAN]; 635 len = via_rd(via, VIA_RECORD_DMAOPS_COUNT, 4); 636 base = via_rd(via, VIA_RECORD_DMAOPS_BASE, 4); 637 if (base != base1) { /* Avoid race hazzard */ 638 len = via_rd(via, VIA_RECORD_DMAOPS_COUNT, 4); 639 } 640 DEB(printf("viachan_getptr: len / base = %x / %x\n", len, base)); 641 642 /* Base points to next block to do, one past current */ 643 644 /* Determine how many segments have been done */ 645 seg = (base - vtophys(ado)) / sizeof(struct via_dma_op); 646 if (seg == 0) seg = SEGS_PER_CHAN; 647 648 /* Now work out offset: seg less count */ 649 ptr = seg * ch->buffer->bufsize / SEGS_PER_CHAN - len; 650 651 /* DMA appears to operate on memory 'lines' of 32 bytes */ 652 /* so don't return any part line - it isn't in RAM yet */ 653 ptr = ptr & ~0x1f; 654 DEB(printf("return ptr=%d\n", ptr)); 655 return ptr; 656 } 657 return 0; 658 } 659 660 static pcmchan_caps * 661 viachan_getcaps(void *data) 662 { 663 struct via_chinfo *ch = data; 664 return (ch->dir == PCMDIR_PLAY) ? &via_playcaps : &via_reccaps; 665 } 666 667 static void 668 via_intr(void *p) 669 { 670 struct via_info *via = p; 671 int st; 672 673 DEB(printf("viachan_intr\n")); 674 /* Read channel */ 675 st = via_rd(via, VIA_PLAY_STAT, 1); 676 if (st & VIA_RPSTAT_INTR) { 677 via_wr(via, VIA_PLAY_STAT, VIA_RPSTAT_INTR, 1); 678 chn_intr(via->pch.channel); 679 } 680 681 /* Write channel */ 682 st = via_rd(via, VIA_RECORD_STAT, 1); 683 if (st & VIA_RPSTAT_INTR) { 684 via_wr(via, VIA_RECORD_STAT, VIA_RPSTAT_INTR, 1); 685 chn_intr(via->rch.channel); 686 } 687 } 688 689 690