1 /* 2 * Copyright (c) 1999 Cameron Grant <gandalf@vilnya.demon.co.uk> 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, WHETHERIN 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 THEPOSSIBILITY OF 24 * SUCH DAMAGE. 25 * 26 * $FreeBSD$ 27 */ 28 29 #include "pci.h" 30 #include "pcm.h" 31 32 #include <dev/pcm/sound.h> 33 #include <dev/pcm/ac97.h> 34 #include <dev/pcm/pci/t4dwave.h> 35 36 #include <pci/pcireg.h> 37 #include <pci/pcivar.h> 38 39 #if NPCI != 0 40 41 /* -------------------------------------------------------------------- */ 42 43 struct tr_info; 44 45 /* channel registers */ 46 struct tr_chinfo { 47 u_int32_t cso, alpha, fms, fmc, ec; 48 u_int32_t lba; 49 u_int32_t eso, delta; 50 u_int32_t rvol, cvol; 51 u_int32_t gvsel, pan, vol, ctrl; 52 int index; 53 snd_dbuf *buffer; 54 pcm_channel *channel; 55 struct tr_info *parent; 56 }; 57 58 /* device private data */ 59 struct tr_info { 60 u_int32_t type; 61 62 bus_space_tag_t st; 63 bus_space_handle_t sh; 64 bus_dma_tag_t parent_dmat; 65 66 struct resource *reg, *irq; 67 int regtype, regid, irqid; 68 void *ih; 69 70 u_int32_t playchns; 71 struct tr_chinfo chinfo[TR_MAXPLAYCH]; 72 struct tr_chinfo recchinfo; 73 }; 74 75 /* -------------------------------------------------------------------- */ 76 77 /* 78 * prototypes 79 */ 80 81 /* channel interface */ 82 static void *trchan_init(void *devinfo, snd_dbuf *b, pcm_channel *c, int dir); 83 static int trchan_setdir(void *data, int dir); 84 static int trchan_setformat(void *data, u_int32_t format); 85 static int trchan_setspeed(void *data, u_int32_t speed); 86 static int trchan_setblocksize(void *data, u_int32_t blocksize); 87 static int trchan_trigger(void *data, int go); 88 static int trchan_getptr(void *data); 89 static pcmchan_caps *trchan_getcaps(void *data); 90 91 /* talk to the codec - called from ac97.c */ 92 static u_int32_t tr_rdcd(void *, int); 93 static void tr_wrcd(void *, int, u_int32_t); 94 95 /* stuff */ 96 static int tr_init(struct tr_info *); 97 static void tr_intr(void *); 98 99 /* talk to the card */ 100 static u_int32_t tr_rd(struct tr_info *, int, int); 101 static void tr_wr(struct tr_info *, int, u_int32_t, int); 102 103 /* manipulate playback channels */ 104 static void tr_clrint(struct tr_info *, char); 105 static void tr_enaint(struct tr_info *, char, int); 106 static u_int32_t tr_testint(struct tr_info *, char); 107 static void tr_rdch(struct tr_info *, char, struct tr_chinfo *); 108 static void tr_wrch(struct tr_info *, char, struct tr_chinfo *); 109 static void tr_selch(struct tr_info *, char); 110 static void tr_startch(struct tr_info *, char); 111 static void tr_stopch(struct tr_info *, char); 112 113 /* -------------------------------------------------------------------- */ 114 115 static pcmchan_caps tr_reccaps = { 116 4000, 48000, 117 AFMT_STEREO | AFMT_U8 | AFMT_S8 | AFMT_S16_LE | AFMT_U16_LE, 118 AFMT_STEREO | AFMT_S16_LE 119 }; 120 121 static pcmchan_caps tr_playcaps = { 122 4000, 48000, 123 AFMT_STEREO | AFMT_U8 | AFMT_S8 | AFMT_S16_LE | AFMT_U16_LE, 124 AFMT_U16_LE 125 }; 126 127 static pcm_channel tr_chantemplate = { 128 trchan_init, 129 trchan_setdir, 130 trchan_setformat, 131 trchan_setspeed, 132 trchan_setblocksize, 133 trchan_trigger, 134 trchan_getptr, 135 trchan_getcaps, 136 }; 137 138 /* -------------------------------------------------------------------- */ 139 140 static u_int32_t 141 tr_fmttobits(u_int32_t fmt) 142 { 143 u_int32_t bits = 0; 144 bits |= (fmt & AFMT_STEREO)? 0x4 : 0; 145 bits |= (fmt & (AFMT_S8 | AFMT_S16_LE))? 0x2 : 0; 146 bits |= (fmt & (AFMT_S16_LE | AFMT_U16_LE))? 0x8 : 0; 147 return bits; 148 } 149 150 /* Hardware */ 151 152 static u_int32_t 153 tr_rd(struct tr_info *tr, int regno, int size) 154 { 155 switch(size) { 156 case 1: 157 return bus_space_read_1(tr->st, tr->sh, regno); 158 case 2: 159 return bus_space_read_2(tr->st, tr->sh, regno); 160 case 4: 161 return bus_space_read_4(tr->st, tr->sh, regno); 162 default: 163 return 0xffffffff; 164 } 165 } 166 167 static void 168 tr_wr(struct tr_info *tr, int regno, u_int32_t data, int size) 169 { 170 switch(size) { 171 case 1: 172 bus_space_write_1(tr->st, tr->sh, regno, data); 173 break; 174 case 2: 175 bus_space_write_2(tr->st, tr->sh, regno, data); 176 break; 177 case 4: 178 bus_space_write_4(tr->st, tr->sh, regno, data); 179 break; 180 } 181 } 182 183 /* ac97 codec */ 184 185 static u_int32_t 186 tr_rdcd(void *devinfo, int regno) 187 { 188 struct tr_info *tr = (struct tr_info *)devinfo; 189 int i, j, treg, trw; 190 191 switch (tr->type) { 192 case TDX_PCI_ID: 193 treg=TDX_REG_CODECRD; 194 trw=TDX_CDC_RWSTAT; 195 break; 196 case TNX_PCI_ID: 197 treg=(regno & 0x100)? TNX_REG_CODEC2RD : TNX_REG_CODEC1RD; 198 trw=TNX_CDC_RWSTAT; 199 break; 200 default: 201 printf("!!! tr_rdcd defaulted !!!\n"); 202 return 0xffffffff; 203 } 204 205 regno &= 0x7f; 206 tr_wr(tr, treg, regno | trw, 4); 207 j=trw; 208 for (i=TR_TIMEOUT_CDC; (i > 0) && (j & trw); i--) j=tr_rd(tr, treg, 4); 209 if (i == 0) printf("codec timeout during read of register %x\n", regno); 210 return (j >> TR_CDC_DATA) & 0xffff; 211 } 212 213 static void 214 tr_wrcd(void *devinfo, int regno, u_int32_t data) 215 { 216 struct tr_info *tr = (struct tr_info *)devinfo; 217 int i, j, treg, trw; 218 219 switch (tr->type) { 220 case TDX_PCI_ID: 221 treg=TDX_REG_CODECWR; 222 trw=TDX_CDC_RWSTAT; 223 break; 224 case TNX_PCI_ID: 225 treg=TNX_REG_CODECWR; 226 trw=TNX_CDC_RWSTAT | ((regno & 0x100)? TNX_CDC_SEC : 0); 227 break; 228 default: 229 printf("!!! tr_wrcd defaulted !!!"); 230 return; 231 } 232 233 regno &= 0x7f; 234 #if 0 235 printf("tr_wrcd: reg %x was %x", regno, tr_rdcd(devinfo, regno)); 236 #endif 237 j=trw; 238 for (i=TR_TIMEOUT_CDC; (i>0) && (j & trw); i--) j=tr_rd(tr, treg, 4); 239 tr_wr(tr, treg, (data << TR_CDC_DATA) | regno | trw, 4); 240 #if 0 241 printf(" - wrote %x, now %x\n", data, tr_rdcd(devinfo, regno)); 242 #endif 243 if (i==0) printf("codec timeout writing %x, data %x\n", regno, data); 244 } 245 246 /* playback channel interrupts */ 247 248 static u_int32_t 249 tr_testint(struct tr_info *tr, char channel) 250 { 251 return tr_rd(tr, (channel & 0x20)? TR_REG_ADDRINTB : TR_REG_ADDRINTA, 252 4) & (1<<(channel & 0x1f)); 253 } 254 255 static void 256 tr_clrint(struct tr_info *tr, char channel) 257 { 258 tr_wr(tr, (channel & 0x20)? TR_REG_ADDRINTB : TR_REG_ADDRINTA, 259 1<<(channel & 0x1f), 4); 260 } 261 262 static void 263 tr_enaint(struct tr_info *tr, char channel, int enable) 264 { 265 u_int32_t reg = (channel & 0x20)? TR_REG_INTENB : TR_REG_INTENA; 266 u_int32_t i = tr_rd(tr, reg, 4); 267 channel &= 0x1f; 268 i &= ~(1 << channel); 269 i |= (enable? 1 : 0) << channel; 270 tr_clrint(tr, channel); 271 tr_wr(tr, reg, i, 4); 272 } 273 274 /* playback channels */ 275 276 static void 277 tr_selch(struct tr_info *tr, char channel) 278 { 279 int i=tr_rd(tr, TR_REG_CIR, 4); 280 i &= ~TR_CIR_MASK; 281 i |= channel & 0x3f; 282 tr_wr(tr, TR_REG_CIR, i, 4); 283 } 284 285 static void 286 tr_startch(struct tr_info *tr, char channel) 287 { 288 tr_wr(tr, (channel & 0x20)? TR_REG_STARTB : TR_REG_STARTA, 289 1<<(channel & 0x1f), 4); 290 } 291 292 static void 293 tr_stopch(struct tr_info *tr, char channel) 294 { 295 tr_wr(tr, (channel & 0x20)? TR_REG_STOPB : TR_REG_STOPA, 296 1<<(channel & 0x1f), 4); 297 } 298 299 static void 300 tr_wrch(struct tr_info *tr, char channel, struct tr_chinfo *ch) 301 { 302 u_int32_t cr[TR_CHN_REGS], i; 303 304 ch->gvsel &= 0x00000001; 305 ch->fmc &= 0x00000003; 306 ch->fms &= 0x0000000f; 307 ch->ctrl &= 0x0000000f; 308 ch->pan &= 0x0000007f; 309 ch->rvol &= 0x0000007f; 310 ch->cvol &= 0x0000007f; 311 ch->vol &= 0x000000ff; 312 ch->ec &= 0x00000fff; 313 ch->alpha &= 0x00000fff; 314 ch->delta &= 0x0000ffff; 315 ch->lba &= 0x3fffffff; 316 317 cr[1]=ch->lba; 318 cr[3]=(ch->rvol<<7) | (ch->cvol); 319 cr[4]=(ch->gvsel<<31)|(ch->pan<<24)|(ch->vol<<16)|(ch->ctrl<<12)|(ch->ec); 320 321 switch (tr->type) { 322 case TDX_PCI_ID: 323 ch->cso &= 0x0000ffff; 324 ch->eso &= 0x0000ffff; 325 cr[0]=(ch->cso<<16) | (ch->alpha<<4) | (ch->fms); 326 cr[2]=(ch->eso<<16) | (ch->delta); 327 cr[3]|=0x0000c000; 328 break; 329 case TNX_PCI_ID: 330 ch->cso &= 0x00ffffff; 331 ch->eso &= 0x00ffffff; 332 cr[0]=((ch->delta & 0xff)<<24) | (ch->cso); 333 cr[2]=((ch->delta>>16)<<24) | (ch->eso); 334 cr[3]|=(ch->alpha<<20) | (ch->fms<<16) | (ch->fmc<<14); 335 break; 336 } 337 tr_selch(tr, channel); 338 for (i=0; i<TR_CHN_REGS; i++) 339 tr_wr(tr, TR_REG_CHNBASE+(i<<2), cr[i], 4); 340 } 341 342 static void 343 tr_rdch(struct tr_info *tr, char channel, struct tr_chinfo *ch) 344 { 345 u_int32_t cr[5], i; 346 tr_selch(tr, channel); 347 for (i=0; i<5; i++) cr[i]=tr_rd(tr, TR_REG_CHNBASE+(i<<2), 4); 348 ch->lba= (cr[1] & 0x3fffffff); 349 ch->fmc= (cr[3] & 0x0000c000) >> 14; 350 ch->rvol= (cr[3] & 0x00003f80) >> 7; 351 ch->cvol= (cr[3] & 0x0000007f); 352 ch->gvsel= (cr[4] & 0x80000000) >> 31; 353 ch->pan= (cr[4] & 0x7f000000) >> 24; 354 ch->vol= (cr[4] & 0x00ff0000) >> 16; 355 ch->ctrl= (cr[4] & 0x0000f000) >> 12; 356 ch->ec= (cr[4] & 0x00000fff); 357 switch(tr->type) { 358 case TDX_PCI_ID: 359 ch->cso= (cr[0] & 0xffff0000) >> 16; 360 ch->alpha= (cr[0] & 0x0000fff0) >> 4; 361 ch->fms= (cr[0] & 0x0000000f); 362 ch->eso= (cr[2] & 0xffff0000) >> 16; 363 ch->delta= (cr[2] & 0x0000ffff); 364 break; 365 case TNX_PCI_ID: 366 ch->cso= (cr[0] & 0x00ffffff); 367 ch->eso= (cr[2] & 0x00ffffff); 368 ch->delta= ((cr[2] & 0xff000000) >> 16) | 369 ((cr[0] & 0xff000000) >> 24); 370 ch->alpha= (cr[3] & 0xfff00000) >> 20; 371 ch->fms= (cr[3] & 0x000f0000) >> 16; 372 break; 373 } 374 } 375 376 /* channel interface */ 377 378 void * 379 trchan_init(void *devinfo, snd_dbuf *b, pcm_channel *c, int dir) 380 { 381 struct tr_info *tr = devinfo; 382 struct tr_chinfo *ch; 383 if (dir == PCMDIR_PLAY) { 384 ch = &tr->chinfo[tr->playchns]; 385 ch->index = tr->playchns++; 386 } else { 387 ch = &tr->recchinfo; 388 ch->index = -1; 389 } 390 ch->buffer = b; 391 ch->buffer->bufsize = TR_BUFFSIZE; 392 ch->parent = tr; 393 ch->channel = c; 394 if (chn_allocbuf(ch->buffer, tr->parent_dmat) == -1) return NULL; 395 else return ch; 396 } 397 398 static int 399 trchan_setdir(void *data, int dir) 400 { 401 struct tr_chinfo *ch = data; 402 struct tr_info *tr = ch->parent; 403 if (dir == PCMDIR_PLAY && ch->index >= 0) { 404 ch->fmc = ch->fms = ch->ec = ch->alpha = 0; 405 ch->lba = vtophys(ch->buffer->buf); 406 ch->cso = 0; 407 ch->eso = ch->buffer->bufsize - 1; 408 ch->rvol = ch->cvol = 0; 409 ch->gvsel = 0; 410 ch->pan = 0; 411 ch->vol = 0; 412 ch->ctrl = 0x01; 413 ch->delta = 0; 414 tr_wrch(tr, ch->index, ch); 415 tr_enaint(tr, ch->index, 1); 416 } else if (dir == PCMDIR_REC && ch->index == -1) { 417 /* set up dma mode regs */ 418 u_int32_t i; 419 tr_wr(tr, TR_REG_DMAR15, 0, 1); 420 i = tr_rd(tr, TR_REG_DMAR11, 1) & 0x03; 421 tr_wr(tr, TR_REG_DMAR11, i | 0x54, 1); 422 /* set up base address */ 423 tr_wr(tr, TR_REG_DMAR0, vtophys(ch->buffer->buf), 4); 424 /* set up buffer size */ 425 i = tr_rd(tr, TR_REG_DMAR4, 4) & ~0x00ffffff; 426 tr_wr(tr, TR_REG_DMAR4, i | (ch->buffer->bufsize - 1), 4); 427 } else return -1; 428 return 0; 429 } 430 431 static int 432 trchan_setformat(void *data, u_int32_t format) 433 { 434 struct tr_chinfo *ch = data; 435 struct tr_info *tr = ch->parent; 436 u_int32_t bits = tr_fmttobits(format); 437 438 if (ch->index >= 0) { 439 tr_rdch(tr, ch->index, ch); 440 ch->eso = (ch->buffer->bufsize / ch->buffer->sample_size) - 1; 441 ch->ctrl = bits | 0x01; 442 tr_wrch(tr, ch->index, ch); 443 } else { 444 u_int32_t i; 445 /* set # of samples between interrupts */ 446 i = (TR_INTSAMPLES >> ((bits & 0x08)? 1 : 0)) - 1; 447 tr_wr(tr, TR_REG_SBBL, i | (i << 16), 4); 448 /* set sample format */ 449 i = 0x18 | (bits << 4); 450 tr_wr(tr, TR_REG_SBCTRL, i, 1); 451 } 452 return 0; 453 } 454 455 static int 456 trchan_setspeed(void *data, u_int32_t speed) 457 { 458 struct tr_chinfo *ch = data; 459 struct tr_info *tr = ch->parent; 460 461 if (ch->index >= 0) { 462 tr_rdch(tr, ch->index, ch); 463 ch->delta = (speed << 12) / 48000; 464 tr_wrch(tr, ch->index, ch); 465 return (ch->delta * 48000) >> 12; 466 } else { 467 /* setup speed */ 468 ch->delta = (48000 << 12) / speed; 469 tr_wr(tr, TR_REG_SBDELTA, ch->delta, 2); 470 return (48000 << 12) / ch->delta; 471 } 472 return 0; 473 } 474 475 static int 476 trchan_setblocksize(void *data, u_int32_t blocksize) 477 { 478 struct tr_chinfo *ch = data; 479 return ch->buffer->bufsize / 2; 480 } 481 482 static int 483 trchan_trigger(void *data, int go) 484 { 485 struct tr_chinfo *ch = data; 486 struct tr_info *tr = ch->parent; 487 if (ch->index >= 0) { 488 if (go == PCMTRIG_START) tr_startch(tr, ch->index); 489 else tr_stopch(tr, ch->index); 490 } else { 491 u_int32_t i = tr_rd(tr, TR_REG_SBCTRL, 1) & ~7; 492 tr_wr(tr, TR_REG_SBCTRL, i | (go == PCMTRIG_START)? 1 : 0, 1); 493 } 494 return 0; 495 } 496 497 static int 498 trchan_getptr(void *data) 499 { 500 struct tr_chinfo *ch = data; 501 struct tr_info *tr = ch->parent; 502 if (ch->index >= 0) { 503 tr_rdch(tr, ch->index, ch); 504 return ch->cso * ch->buffer->sample_size; 505 } else return tr_rd(tr, TR_REG_DMAR0, 4) - vtophys(ch->buffer->buf); 506 } 507 508 static pcmchan_caps * 509 trchan_getcaps(void *data) 510 { 511 struct tr_chinfo *ch = data; 512 return (ch->index >= 0)? &tr_playcaps : &tr_reccaps; 513 } 514 515 /* The interrupt handler */ 516 517 static void 518 tr_intr(void *p) 519 { 520 struct tr_info *tr = (struct tr_info *)p; 521 u_int32_t intsrc = tr_rd(tr, TR_REG_MISCINT, 4); 522 523 if (intsrc & TR_INT_ADDR) { 524 int i; 525 for (i = 0; i < tr->playchns; i++) { 526 if (tr_testint(tr, i)) { 527 chn_intr(tr->chinfo[i].channel); 528 tr_clrint(tr, i); 529 } 530 } 531 } 532 if (intsrc & TR_INT_SB) { 533 chn_intr(tr->recchinfo.channel); 534 tr_rd(tr, TR_REG_SBR9, 1); 535 tr_rd(tr, TR_REG_SBR10, 1); 536 } 537 } 538 539 /* -------------------------------------------------------------------- */ 540 541 /* 542 * Probe and attach the card 543 */ 544 545 static int 546 tr_init(struct tr_info *tr) 547 { 548 if (tr->type == TDX_PCI_ID) { 549 tr_wr(tr, TDX_REG_CODECST, TDX_CDC_ON, 4); 550 } else tr_wr(tr, TNX_REG_CODECST, TNX_CDC_ON, 4); 551 552 tr_wr(tr, TR_REG_CIR, TR_CIR_MIDENA | TR_CIR_ADDRENA, 4); 553 tr->playchns = 0; 554 return 0; 555 } 556 557 static int 558 tr_pci_probe(device_t dev) 559 { 560 if (pci_get_devid(dev) == TDX_PCI_ID) { 561 device_set_desc(dev, "Trident 4DWave DX"); 562 return 0; 563 } 564 if (pci_get_devid(dev) == TNX_PCI_ID) { 565 device_set_desc(dev, "Trident 4DWave NX"); 566 return 0; 567 } 568 569 return ENXIO; 570 } 571 572 static int 573 tr_pci_attach(device_t dev) 574 { 575 snddev_info *d; 576 u_int32_t data; 577 struct tr_info *tr; 578 struct ac97_info *codec; 579 int i; 580 int mapped; 581 char status[SND_STATUSLEN]; 582 583 d = device_get_softc(dev); 584 if ((tr = malloc(sizeof(*tr), M_DEVBUF, M_NOWAIT)) == NULL) { 585 device_printf(dev, "cannot allocate softc\n"); 586 return ENXIO; 587 } 588 589 bzero(tr, sizeof(*tr)); 590 tr->type = pci_get_devid(dev); 591 592 data = pci_read_config(dev, PCIR_COMMAND, 2); 593 data |= (PCIM_CMD_PORTEN|PCIM_CMD_MEMEN|PCIM_CMD_BUSMASTEREN); 594 pci_write_config(dev, PCIR_COMMAND, data, 2); 595 data = pci_read_config(dev, PCIR_COMMAND, 2); 596 597 mapped = 0; 598 /* XXX dfr: is this strictly necessary? */ 599 for (i = 0; (mapped == 0) && (i < PCI_MAXMAPS_0); i++) { 600 tr->regid = PCIR_MAPS + i*4; 601 tr->regtype = SYS_RES_MEMORY; 602 tr->reg = bus_alloc_resource(dev, tr->regtype, &tr->regid, 603 0, ~0, 1, RF_ACTIVE); 604 if (!tr->reg) { 605 tr->regtype = SYS_RES_IOPORT; 606 tr->reg = bus_alloc_resource(dev, tr->regtype, 607 &tr->regid, 0, ~0, 1, 608 RF_ACTIVE); 609 } 610 if (tr->reg) { 611 tr->st = rman_get_bustag(tr->reg); 612 tr->sh = rman_get_bushandle(tr->reg); 613 mapped++; 614 } 615 } 616 617 if (mapped == 0) { 618 device_printf(dev, "unable to map register space\n"); 619 goto bad; 620 } 621 622 if (tr_init(tr) == -1) { 623 device_printf(dev, "unable to initialize the card\n"); 624 goto bad; 625 } 626 627 codec = ac97_create(tr, tr_rdcd, tr_wrcd); 628 if (codec == NULL) goto bad; 629 mixer_init(d, &ac97_mixer, codec); 630 631 tr->irqid = 0; 632 tr->irq = bus_alloc_resource(dev, SYS_RES_IRQ, &tr->irqid, 633 0, ~0, 1, RF_ACTIVE | RF_SHAREABLE); 634 if (!tr->irq || 635 bus_setup_intr(dev, tr->irq, INTR_TYPE_TTY, tr_intr, tr, &tr->ih)) { 636 device_printf(dev, "unable to map interrupt\n"); 637 goto bad; 638 } 639 640 if (bus_dma_tag_create(/*parent*/NULL, /*alignment*/2, /*boundary*/0, 641 /*lowaddr*/BUS_SPACE_MAXADDR_32BIT, 642 /*highaddr*/BUS_SPACE_MAXADDR, 643 /*filter*/NULL, /*filterarg*/NULL, 644 /*maxsize*/TR_BUFFSIZE, /*nsegments*/1, /*maxsegz*/0x3ffff, 645 /*flags*/0, &tr->parent_dmat) != 0) { 646 device_printf(dev, "unable to create dma tag\n"); 647 goto bad; 648 } 649 650 snprintf(status, 64, "at %s 0x%lx irq %ld", 651 (tr->regtype == SYS_RES_IOPORT)? "io" : "memory", 652 rman_get_start(tr->reg), rman_get_start(tr->irq)); 653 654 if (pcm_register(dev, tr, TR_MAXPLAYCH, 1)) goto bad; 655 pcm_addchan(dev, PCMDIR_REC, &tr_chantemplate, tr); 656 for (i = 0; i < TR_MAXPLAYCH; i++) 657 pcm_addchan(dev, PCMDIR_PLAY, &tr_chantemplate, tr); 658 pcm_setstatus(dev, status); 659 660 return 0; 661 662 bad: 663 if (tr->reg) bus_release_resource(dev, tr->regtype, tr->regid, tr->reg); 664 if (tr->ih) bus_teardown_intr(dev, tr->irq, tr->ih); 665 if (tr->irq) bus_release_resource(dev, SYS_RES_IRQ, tr->irqid, tr->irq); 666 free(tr, M_DEVBUF); 667 return ENXIO; 668 } 669 670 static device_method_t tr_methods[] = { 671 /* Device interface */ 672 DEVMETHOD(device_probe, tr_pci_probe), 673 DEVMETHOD(device_attach, tr_pci_attach), 674 675 { 0, 0 } 676 }; 677 678 static driver_t tr_driver = { 679 "pcm", 680 tr_methods, 681 sizeof(snddev_info), 682 }; 683 684 static devclass_t pcm_devclass; 685 686 DRIVER_MODULE(tr, pci, tr_driver, pcm_devclass, 0, 0); 687 688 #endif /* NPCI != 0 */ 689