t4dwave.c (71503) | t4dwave.c (74763) |
---|---|
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 unchanged lines hidden (view full) --- 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 * | 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 unchanged lines hidden (view full) --- 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: head/sys/dev/sound/pci/t4dwave.c 71503 2001-01-24 01:20:04Z cg $ | 26 * $FreeBSD: head/sys/dev/sound/pci/t4dwave.c 74763 2001-03-24 23:10:29Z cg $ |
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> --- 12 unchanged lines hidden (view full) --- 47/* channel registers */ 48struct tr_chinfo { 49 u_int32_t cso, alpha, fms, fmc, ec; 50 u_int32_t lba; 51 u_int32_t eso, delta; 52 u_int32_t rvol, cvol; 53 u_int32_t gvsel, pan, vol, ctrl; 54 int index, bufhalf; | 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> --- 12 unchanged lines hidden (view full) --- 47/* channel registers */ 48struct tr_chinfo { 49 u_int32_t cso, alpha, fms, fmc, ec; 50 u_int32_t lba; 51 u_int32_t eso, delta; 52 u_int32_t rvol, cvol; 53 u_int32_t gvsel, pan, vol, ctrl; 54 int index, bufhalf; |
55 snd_dbuf *buffer; 56 pcm_channel *channel; | 55 struct snd_dbuf *buffer; 56 struct pcm_channel *channel; |
57 struct tr_info *parent; 58}; 59 60struct tr_rchinfo { 61 u_int32_t delta; | 57 struct tr_info *parent; 58}; 59 60struct tr_rchinfo { 61 u_int32_t delta; |
62 snd_dbuf *buffer; 63 pcm_channel *channel; | 62 struct snd_dbuf *buffer; 63 struct pcm_channel *channel; |
64 struct tr_info *parent; 65}; 66 67/* device private data */ 68struct tr_info { 69 u_int32_t type; 70 71 bus_space_tag_t st; 72 bus_space_handle_t sh; 73 bus_dma_tag_t parent_dmat; 74 75 struct resource *reg, *irq; 76 int regtype, regid, irqid; 77 void *ih; 78 | 64 struct tr_info *parent; 65}; 66 67/* device private data */ 68struct tr_info { 69 u_int32_t type; 70 71 bus_space_tag_t st; 72 bus_space_handle_t sh; 73 bus_dma_tag_t parent_dmat; 74 75 struct resource *reg, *irq; 76 int regtype, regid, irqid; 77 void *ih; 78 |
79 void *lock; 80 |
|
79 u_int32_t playchns; 80 struct tr_chinfo chinfo[TR_MAXPLAYCH]; 81 struct tr_rchinfo recchinfo; 82}; 83 84/* -------------------------------------------------------------------- */ 85 86static u_int32_t tr_recfmt[] = { 87 AFMT_U8, 88 AFMT_STEREO | AFMT_U8, 89 AFMT_S8, 90 AFMT_STEREO | AFMT_S8, 91 AFMT_S16_LE, 92 AFMT_STEREO | AFMT_S16_LE, 93 AFMT_U16_LE, 94 AFMT_STEREO | AFMT_U16_LE, 95 0 96}; | 81 u_int32_t playchns; 82 struct tr_chinfo chinfo[TR_MAXPLAYCH]; 83 struct tr_rchinfo recchinfo; 84}; 85 86/* -------------------------------------------------------------------- */ 87 88static u_int32_t tr_recfmt[] = { 89 AFMT_U8, 90 AFMT_STEREO | AFMT_U8, 91 AFMT_S8, 92 AFMT_STEREO | AFMT_S8, 93 AFMT_S16_LE, 94 AFMT_STEREO | AFMT_S16_LE, 95 AFMT_U16_LE, 96 AFMT_STEREO | AFMT_U16_LE, 97 0 98}; |
97static pcmchan_caps tr_reccaps = {4000, 48000, tr_recfmt, 0}; | 99static struct pcmchan_caps tr_reccaps = {4000, 48000, tr_recfmt, 0}; |
98 99static u_int32_t tr_playfmt[] = { 100 AFMT_U8, 101 AFMT_STEREO | AFMT_U8, 102 AFMT_S8, 103 AFMT_STEREO | AFMT_S8, 104 AFMT_S16_LE, 105 AFMT_STEREO | AFMT_S16_LE, 106 AFMT_U16_LE, 107 AFMT_STEREO | AFMT_U16_LE, 108 0 109}; | 100 101static u_int32_t tr_playfmt[] = { 102 AFMT_U8, 103 AFMT_STEREO | AFMT_U8, 104 AFMT_S8, 105 AFMT_STEREO | AFMT_S8, 106 AFMT_S16_LE, 107 AFMT_STEREO | AFMT_S16_LE, 108 AFMT_U16_LE, 109 AFMT_STEREO | AFMT_U16_LE, 110 0 111}; |
110static pcmchan_caps tr_playcaps = {4000, 48000, tr_playfmt, 0}; | 112static struct pcmchan_caps tr_playcaps = {4000, 48000, tr_playfmt, 0}; |
111 112/* -------------------------------------------------------------------- */ 113 114/* Hardware */ 115 116static u_int32_t 117tr_rd(struct tr_info *tr, int regno, int size) 118{ --- 44 unchanged lines hidden (view full) --- 163 trw=TNX_CDC_RWSTAT; 164 break; 165 default: 166 printf("!!! tr_rdcd defaulted !!!\n"); 167 return -1; 168 } 169 170 regno &= 0x7f; | 113 114/* -------------------------------------------------------------------- */ 115 116/* Hardware */ 117 118static u_int32_t 119tr_rd(struct tr_info *tr, int regno, int size) 120{ --- 44 unchanged lines hidden (view full) --- 165 trw=TNX_CDC_RWSTAT; 166 break; 167 default: 168 printf("!!! tr_rdcd defaulted !!!\n"); 169 return -1; 170 } 171 172 regno &= 0x7f; |
173 snd_mtxlock(tr->lock); |
|
171 tr_wr(tr, treg, regno | trw, 4); 172 j=trw; 173 for (i=TR_TIMEOUT_CDC; (i > 0) && (j & trw); i--) j=tr_rd(tr, treg, 4); | 174 tr_wr(tr, treg, regno | trw, 4); 175 j=trw; 176 for (i=TR_TIMEOUT_CDC; (i > 0) && (j & trw); i--) j=tr_rd(tr, treg, 4); |
177 snd_mtxunlock(tr->lock); |
|
174 if (i == 0) printf("codec timeout during read of register %x\n", regno); 175 return (j >> TR_CDC_DATA) & 0xffff; 176} 177 178static int 179tr_wrcd(kobj_t obj, void *devinfo, int regno, u_int32_t data) 180{ 181 struct tr_info *tr = (struct tr_info *)devinfo; --- 13 unchanged lines hidden (view full) --- 195 return -1; 196 } 197 198 regno &= 0x7f; 199#if 0 200 printf("tr_wrcd: reg %x was %x", regno, tr_rdcd(devinfo, regno)); 201#endif 202 j=trw; | 178 if (i == 0) printf("codec timeout during read of register %x\n", regno); 179 return (j >> TR_CDC_DATA) & 0xffff; 180} 181 182static int 183tr_wrcd(kobj_t obj, void *devinfo, int regno, u_int32_t data) 184{ 185 struct tr_info *tr = (struct tr_info *)devinfo; --- 13 unchanged lines hidden (view full) --- 199 return -1; 200 } 201 202 regno &= 0x7f; 203#if 0 204 printf("tr_wrcd: reg %x was %x", regno, tr_rdcd(devinfo, regno)); 205#endif 206 j=trw; |
207 snd_mtxlock(tr->lock); |
|
203 for (i=TR_TIMEOUT_CDC; (i>0) && (j & trw); i--) j=tr_rd(tr, treg, 4); 204 tr_wr(tr, treg, (data << TR_CDC_DATA) | regno | trw, 4); 205#if 0 206 printf(" - wrote %x, now %x\n", data, tr_rdcd(devinfo, regno)); 207#endif | 208 for (i=TR_TIMEOUT_CDC; (i>0) && (j & trw); i--) j=tr_rd(tr, treg, 4); 209 tr_wr(tr, treg, (data << TR_CDC_DATA) | regno | trw, 4); 210#if 0 211 printf(" - wrote %x, now %x\n", data, tr_rdcd(devinfo, regno)); 212#endif |
213 snd_mtxunlock(tr->lock); |
|
208 if (i==0) printf("codec timeout writing %x, data %x\n", regno, data); 209 return (i > 0)? 0 : -1; 210} 211 212static kobj_method_t tr_ac97_methods[] = { 213 KOBJMETHOD(ac97_read, tr_rdcd), 214 KOBJMETHOD(ac97_write, tr_wrcd), 215 { 0, 0 } --- 29 unchanged lines hidden (view full) --- 245 246static void 247tr_enaint(struct tr_chinfo *ch, int enable) 248{ 249 struct tr_info *tr = ch->parent; 250 u_int32_t i, reg; 251 int bank, chan; 252 | 214 if (i==0) printf("codec timeout writing %x, data %x\n", regno, data); 215 return (i > 0)? 0 : -1; 216} 217 218static kobj_method_t tr_ac97_methods[] = { 219 KOBJMETHOD(ac97_read, tr_rdcd), 220 KOBJMETHOD(ac97_write, tr_wrcd), 221 { 0, 0 } --- 29 unchanged lines hidden (view full) --- 251 252static void 253tr_enaint(struct tr_chinfo *ch, int enable) 254{ 255 struct tr_info *tr = ch->parent; 256 u_int32_t i, reg; 257 int bank, chan; 258 |
259 snd_mtxlock(tr->lock); |
|
253 bank = (ch->index & 0x20) ? 1 : 0; 254 chan = ch->index & 0x1f; 255 reg = bank? TR_REG_INTENB : TR_REG_INTENA; 256 257 i = tr_rd(tr, reg, 4); 258 i &= ~(1 << chan); 259 i |= (enable? 1 : 0) << chan; 260 261 tr_clrint(ch); 262 tr_wr(tr, reg, i, 4); | 260 bank = (ch->index & 0x20) ? 1 : 0; 261 chan = ch->index & 0x1f; 262 reg = bank? TR_REG_INTENB : TR_REG_INTENA; 263 264 i = tr_rd(tr, reg, 4); 265 i &= ~(1 << chan); 266 i |= (enable? 1 : 0) << chan; 267 268 tr_clrint(ch); 269 tr_wr(tr, reg, i, 4); |
270 snd_mtxunlock(tr->lock); |
|
263} 264 265/* playback channels */ 266 267static void 268tr_selch(struct tr_chinfo *ch) 269{ 270 struct tr_info *tr = ch->parent; --- 60 unchanged lines hidden (view full) --- 331 case TNX_PCI_ID: 332 ch->cso &= 0x00ffffff; 333 ch->eso &= 0x00ffffff; 334 cr[0]=((ch->delta & 0xff)<<24) | (ch->cso); 335 cr[2]=((ch->delta>>16)<<24) | (ch->eso); 336 cr[3]|=(ch->alpha<<20) | (ch->fms<<16) | (ch->fmc<<14); 337 break; 338 } | 271} 272 273/* playback channels */ 274 275static void 276tr_selch(struct tr_chinfo *ch) 277{ 278 struct tr_info *tr = ch->parent; --- 60 unchanged lines hidden (view full) --- 339 case TNX_PCI_ID: 340 ch->cso &= 0x00ffffff; 341 ch->eso &= 0x00ffffff; 342 cr[0]=((ch->delta & 0xff)<<24) | (ch->cso); 343 cr[2]=((ch->delta>>16)<<24) | (ch->eso); 344 cr[3]|=(ch->alpha<<20) | (ch->fms<<16) | (ch->fmc<<14); 345 break; 346 } |
347 snd_mtxlock(tr->lock); |
|
339 tr_selch(ch); 340 for (i=0; i<TR_CHN_REGS; i++) 341 tr_wr(tr, TR_REG_CHNBASE+(i<<2), cr[i], 4); | 348 tr_selch(ch); 349 for (i=0; i<TR_CHN_REGS; i++) 350 tr_wr(tr, TR_REG_CHNBASE+(i<<2), cr[i], 4); |
351 snd_mtxunlock(tr->lock); |
|
342} 343 344static void 345tr_rdch(struct tr_chinfo *ch) 346{ 347 struct tr_info *tr = ch->parent; 348 u_int32_t cr[5], i; 349 | 352} 353 354static void 355tr_rdch(struct tr_chinfo *ch) 356{ 357 struct tr_info *tr = ch->parent; 358 u_int32_t cr[5], i; 359 |
360 snd_mtxlock(tr->lock); |
|
350 tr_selch(ch); 351 for (i=0; i<5; i++) 352 cr[i]=tr_rd(tr, TR_REG_CHNBASE+(i<<2), 4); | 361 tr_selch(ch); 362 for (i=0; i<5; i++) 363 cr[i]=tr_rd(tr, TR_REG_CHNBASE+(i<<2), 4); |
364 snd_mtxunlock(tr->lock); |
|
353 354 355 ch->lba= (cr[1] & 0x3fffffff); 356 ch->fmc= (cr[3] & 0x0000c000) >> 14; 357 ch->rvol= (cr[3] & 0x00003f80) >> 7; 358 ch->cvol= (cr[3] & 0x0000007f); 359 ch->gvsel= (cr[4] & 0x80000000) >> 31; 360 ch->pan= (cr[4] & 0x7f000000) >> 24; --- 30 unchanged lines hidden (view full) --- 391 392 return bits; 393} 394 395/* -------------------------------------------------------------------- */ 396/* channel interface */ 397 398static void * | 365 366 367 ch->lba= (cr[1] & 0x3fffffff); 368 ch->fmc= (cr[3] & 0x0000c000) >> 14; 369 ch->rvol= (cr[3] & 0x00003f80) >> 7; 370 ch->cvol= (cr[3] & 0x0000007f); 371 ch->gvsel= (cr[4] & 0x80000000) >> 31; 372 ch->pan= (cr[4] & 0x7f000000) >> 24; --- 30 unchanged lines hidden (view full) --- 403 404 return bits; 405} 406 407/* -------------------------------------------------------------------- */ 408/* channel interface */ 409 410static void * |
399trpchan_init(kobj_t obj, void *devinfo, snd_dbuf *b, pcm_channel *c, int dir) | 411trpchan_init(kobj_t obj, void *devinfo, struct snd_dbuf *b, struct pcm_channel *c, int dir) |
400{ 401 struct tr_info *tr = devinfo; 402 struct tr_chinfo *ch; 403 404 KASSERT(dir == PCMDIR_PLAY, ("trpchan_init: bad direction")); 405 ch = &tr->chinfo[tr->playchns]; 406 ch->index = tr->playchns++; 407 ch->buffer = b; --- 67 unchanged lines hidden (view full) --- 475trpchan_getptr(kobj_t obj, void *data) 476{ 477 struct tr_chinfo *ch = data; 478 479 tr_rdch(ch); 480 return ch->cso * sndbuf_getbps(ch->buffer); 481} 482 | 412{ 413 struct tr_info *tr = devinfo; 414 struct tr_chinfo *ch; 415 416 KASSERT(dir == PCMDIR_PLAY, ("trpchan_init: bad direction")); 417 ch = &tr->chinfo[tr->playchns]; 418 ch->index = tr->playchns++; 419 ch->buffer = b; --- 67 unchanged lines hidden (view full) --- 487trpchan_getptr(kobj_t obj, void *data) 488{ 489 struct tr_chinfo *ch = data; 490 491 tr_rdch(ch); 492 return ch->cso * sndbuf_getbps(ch->buffer); 493} 494 |
483static pcmchan_caps * | 495static struct pcmchan_caps * |
484trpchan_getcaps(kobj_t obj, void *data) 485{ 486 return &tr_playcaps; 487} 488 489static kobj_method_t trpchan_methods[] = { 490 KOBJMETHOD(channel_init, trpchan_init), 491 KOBJMETHOD(channel_setformat, trpchan_setformat), --- 5 unchanged lines hidden (view full) --- 497 { 0, 0 } 498}; 499CHANNEL_DECLARE(trpchan); 500 501/* -------------------------------------------------------------------- */ 502/* rec channel interface */ 503 504static void * | 496trpchan_getcaps(kobj_t obj, void *data) 497{ 498 return &tr_playcaps; 499} 500 501static kobj_method_t trpchan_methods[] = { 502 KOBJMETHOD(channel_init, trpchan_init), 503 KOBJMETHOD(channel_setformat, trpchan_setformat), --- 5 unchanged lines hidden (view full) --- 509 { 0, 0 } 510}; 511CHANNEL_DECLARE(trpchan); 512 513/* -------------------------------------------------------------------- */ 514/* rec channel interface */ 515 516static void * |
505trrchan_init(kobj_t obj, void *devinfo, snd_dbuf *b, pcm_channel *c, int dir) | 517trrchan_init(kobj_t obj, void *devinfo, struct snd_dbuf *b, struct pcm_channel *c, int dir) |
506{ 507 struct tr_info *tr = devinfo; 508 struct tr_rchinfo *ch; 509 510 KASSERT(dir == PCMDIR_REC, ("trrchan_init: bad direction")); 511 ch = &tr->recchinfo; 512 ch->buffer = b; 513 ch->parent = tr; --- 81 unchanged lines hidden (view full) --- 595{ 596 struct tr_rchinfo *ch = data; 597 struct tr_info *tr = ch->parent; 598 599 /* return current byte offset of channel */ 600 return tr_rd(tr, TR_REG_DMAR0, 4) - vtophys(sndbuf_getbuf(ch->buffer)); 601} 602 | 518{ 519 struct tr_info *tr = devinfo; 520 struct tr_rchinfo *ch; 521 522 KASSERT(dir == PCMDIR_REC, ("trrchan_init: bad direction")); 523 ch = &tr->recchinfo; 524 ch->buffer = b; 525 ch->parent = tr; --- 81 unchanged lines hidden (view full) --- 607{ 608 struct tr_rchinfo *ch = data; 609 struct tr_info *tr = ch->parent; 610 611 /* return current byte offset of channel */ 612 return tr_rd(tr, TR_REG_DMAR0, 4) - vtophys(sndbuf_getbuf(ch->buffer)); 613} 614 |
603static pcmchan_caps * | 615static struct pcmchan_caps * |
604trrchan_getcaps(kobj_t obj, void *data) 605{ 606 return &tr_reccaps; 607} 608 609static kobj_method_t trrchan_methods[] = { 610 KOBJMETHOD(channel_init, trrchan_init), 611 KOBJMETHOD(channel_setformat, trrchan_setformat), --- 29 unchanged lines hidden (view full) --- 641 if (active & mask) { 642 tmp = (bufhalf & mask)? 1 : 0; 643 if (chnum < tr->playchns) { 644 ch = &tr->chinfo[chnum]; 645 /* printf("%d @ %d, ", chnum, trpchan_getptr(NULL, ch)); */ 646 if (ch->bufhalf != tmp) { 647 chn_intr(ch->channel); 648 ch->bufhalf = tmp; | 616trrchan_getcaps(kobj_t obj, void *data) 617{ 618 return &tr_reccaps; 619} 620 621static kobj_method_t trrchan_methods[] = { 622 KOBJMETHOD(channel_init, trrchan_init), 623 KOBJMETHOD(channel_setformat, trrchan_setformat), --- 29 unchanged lines hidden (view full) --- 653 if (active & mask) { 654 tmp = (bufhalf & mask)? 1 : 0; 655 if (chnum < tr->playchns) { 656 ch = &tr->chinfo[chnum]; 657 /* printf("%d @ %d, ", chnum, trpchan_getptr(NULL, ch)); */ 658 if (ch->bufhalf != tmp) { 659 chn_intr(ch->channel); 660 ch->bufhalf = tmp; |
649 } else 650 printf("same bufhalf\n"); 651 | 661 } |
652 } 653 } 654 chnum++; 655 mask <<= 1; 656 } while (chnum & 31); 657 } else 658 chnum += 32; 659 --- 51 unchanged lines hidden (view full) --- 711 712 if ((tr = malloc(sizeof(*tr), M_DEVBUF, M_NOWAIT)) == NULL) { 713 device_printf(dev, "cannot allocate softc\n"); 714 return ENXIO; 715 } 716 717 bzero(tr, sizeof(*tr)); 718 tr->type = pci_get_devid(dev); | 662 } 663 } 664 chnum++; 665 mask <<= 1; 666 } while (chnum & 31); 667 } else 668 chnum += 32; 669 --- 51 unchanged lines hidden (view full) --- 721 722 if ((tr = malloc(sizeof(*tr), M_DEVBUF, M_NOWAIT)) == NULL) { 723 device_printf(dev, "cannot allocate softc\n"); 724 return ENXIO; 725 } 726 727 bzero(tr, sizeof(*tr)); 728 tr->type = pci_get_devid(dev); |
729 tr->lock = snd_mtxcreate(device_get_nameunit(dev)); |
|
719 720 data = pci_read_config(dev, PCIR_COMMAND, 2); 721 data |= (PCIM_CMD_PORTEN|PCIM_CMD_MEMEN|PCIM_CMD_BUSMASTEREN); 722 pci_write_config(dev, PCIR_COMMAND, data, 2); 723 data = pci_read_config(dev, PCIR_COMMAND, 2); 724 725 tr->regid = PCIR_MAPS; 726 tr->regtype = SYS_RES_IOPORT; --- 13 unchanged lines hidden (view full) --- 740 741 codec = AC97_CREATE(dev, tr, tr_ac97); 742 if (codec == NULL) goto bad; 743 if (mixer_init(dev, ac97_getmixerclass(), codec) == -1) goto bad; 744 745 tr->irqid = 0; 746 tr->irq = bus_alloc_resource(dev, SYS_RES_IRQ, &tr->irqid, 747 0, ~0, 1, RF_ACTIVE | RF_SHAREABLE); | 730 731 data = pci_read_config(dev, PCIR_COMMAND, 2); 732 data |= (PCIM_CMD_PORTEN|PCIM_CMD_MEMEN|PCIM_CMD_BUSMASTEREN); 733 pci_write_config(dev, PCIR_COMMAND, data, 2); 734 data = pci_read_config(dev, PCIR_COMMAND, 2); 735 736 tr->regid = PCIR_MAPS; 737 tr->regtype = SYS_RES_IOPORT; --- 13 unchanged lines hidden (view full) --- 751 752 codec = AC97_CREATE(dev, tr, tr_ac97); 753 if (codec == NULL) goto bad; 754 if (mixer_init(dev, ac97_getmixerclass(), codec) == -1) goto bad; 755 756 tr->irqid = 0; 757 tr->irq = bus_alloc_resource(dev, SYS_RES_IRQ, &tr->irqid, 758 0, ~0, 1, RF_ACTIVE | RF_SHAREABLE); |
748 if (!tr->irq || 749 bus_setup_intr(dev, tr->irq, INTR_TYPE_TTY, tr_intr, tr, &tr->ih)) { | 759 if (!tr->irq || snd_setup_intr(dev, tr->irq, INTR_MPSAFE, tr_intr, tr, &tr->ih)) { |
750 device_printf(dev, "unable to map interrupt\n"); 751 goto bad; 752 } 753 754 if (bus_dma_tag_create(/*parent*/NULL, /*alignment*/2, /*boundary*/0, 755 /*lowaddr*/BUS_SPACE_MAXADDR_32BIT, 756 /*highaddr*/BUS_SPACE_MAXADDR, 757 /*filter*/NULL, /*filterarg*/NULL, --- 15 unchanged lines hidden (view full) --- 773 return 0; 774 775bad: 776 if (codec) ac97_destroy(codec); 777 if (tr->reg) bus_release_resource(dev, tr->regtype, tr->regid, tr->reg); 778 if (tr->ih) bus_teardown_intr(dev, tr->irq, tr->ih); 779 if (tr->irq) bus_release_resource(dev, SYS_RES_IRQ, tr->irqid, tr->irq); 780 if (tr->parent_dmat) bus_dma_tag_destroy(tr->parent_dmat); | 760 device_printf(dev, "unable to map interrupt\n"); 761 goto bad; 762 } 763 764 if (bus_dma_tag_create(/*parent*/NULL, /*alignment*/2, /*boundary*/0, 765 /*lowaddr*/BUS_SPACE_MAXADDR_32BIT, 766 /*highaddr*/BUS_SPACE_MAXADDR, 767 /*filter*/NULL, /*filterarg*/NULL, --- 15 unchanged lines hidden (view full) --- 783 return 0; 784 785bad: 786 if (codec) ac97_destroy(codec); 787 if (tr->reg) bus_release_resource(dev, tr->regtype, tr->regid, tr->reg); 788 if (tr->ih) bus_teardown_intr(dev, tr->irq, tr->ih); 789 if (tr->irq) bus_release_resource(dev, SYS_RES_IRQ, tr->irqid, tr->irq); 790 if (tr->parent_dmat) bus_dma_tag_destroy(tr->parent_dmat); |
791 if (tr->lock) snd_mtxfree(tr->lock); |
|
781 free(tr, M_DEVBUF); 782 return ENXIO; 783} 784 785static int 786tr_pci_detach(device_t dev) 787{ 788 int r; 789 struct tr_info *tr; 790 791 r = pcm_unregister(dev); 792 if (r) 793 return r; 794 795 tr = pcm_getdevinfo(dev); 796 bus_release_resource(dev, tr->regtype, tr->regid, tr->reg); 797 bus_teardown_intr(dev, tr->irq, tr->ih); 798 bus_release_resource(dev, SYS_RES_IRQ, tr->irqid, tr->irq); 799 bus_dma_tag_destroy(tr->parent_dmat); | 792 free(tr, M_DEVBUF); 793 return ENXIO; 794} 795 796static int 797tr_pci_detach(device_t dev) 798{ 799 int r; 800 struct tr_info *tr; 801 802 r = pcm_unregister(dev); 803 if (r) 804 return r; 805 806 tr = pcm_getdevinfo(dev); 807 bus_release_resource(dev, tr->regtype, tr->regid, tr->reg); 808 bus_teardown_intr(dev, tr->irq, tr->ih); 809 bus_release_resource(dev, SYS_RES_IRQ, tr->irqid, tr->irq); 810 bus_dma_tag_destroy(tr->parent_dmat); |
811 snd_mtxfree(tr->lock); |
|
800 free(tr, M_DEVBUF); 801 802 return 0; 803} 804 805static device_method_t tr_methods[] = { 806 /* Device interface */ 807 DEVMETHOD(device_probe, tr_pci_probe), 808 DEVMETHOD(device_attach, tr_pci_attach), 809 DEVMETHOD(device_detach, tr_pci_detach), 810 811 { 0, 0 } 812}; 813 814static driver_t tr_driver = { 815 "pcm", 816 tr_methods, | 812 free(tr, M_DEVBUF); 813 814 return 0; 815} 816 817static device_method_t tr_methods[] = { 818 /* Device interface */ 819 DEVMETHOD(device_probe, tr_pci_probe), 820 DEVMETHOD(device_attach, tr_pci_attach), 821 DEVMETHOD(device_detach, tr_pci_detach), 822 823 { 0, 0 } 824}; 825 826static driver_t tr_driver = { 827 "pcm", 828 tr_methods, |
817 sizeof(snddev_info), | 829 sizeof(struct snddev_info), |
818}; 819 820static devclass_t pcm_devclass; 821 822DRIVER_MODULE(snd_t4dwave, pci, tr_driver, pcm_devclass, 0, 0); 823MODULE_DEPEND(snd_t4dwave, snd_pcm, PCM_MINVER, PCM_PREFVER, PCM_MAXVER); 824MODULE_VERSION(snd_t4dwave, 1); | 830}; 831 832static devclass_t pcm_devclass; 833 834DRIVER_MODULE(snd_t4dwave, pci, tr_driver, pcm_devclass, 0, 0); 835MODULE_DEPEND(snd_t4dwave, snd_pcm, PCM_MINVER, PCM_PREFVER, PCM_MAXVER); 836MODULE_VERSION(snd_t4dwave, 1); |