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