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