2 * Copyright (c) 1999 Cameron Grant <cg@freebsd.org>
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
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.
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
26 * $FreeBSD: src/sys/dev/sound/pci/t4dwave.c,v 1.48.2.1 2007/11/15 16:59:54 ariff Exp $
29 #include <dev/sound/pcm/sound.h>
30 #include <dev/sound/pcm/ac97.h>
31 #include <dev/sound/pci/t4dwave.h>
33 #include <bus/pci/pcireg.h>
34 #include <bus/pci/pcivar.h>
36 SND_DECLARE_FILE("$DragonFly: src/sys/dev/sound/pci/t4dwave.c,v 1.11 2007/11/30 08:03:17 hasso Exp $");
38 /* -------------------------------------------------------------------- */
40 #define TDX_PCI_ID 0x20001023
41 #define TNX_PCI_ID 0x20011023
42 #define ALI_PCI_ID 0x545110b9
43 #define SPA_PCI_ID 0x70181039
45 #define TR_DEFAULT_BUFSZ 0x1000
46 #define TR_TIMEOUT_CDC 0xffff
47 #define TR_MAXPLAYCH 4
49 * Though, it's not clearly documented in trident datasheet, trident
50 * audio cards can't handle DMA addresses located above 1GB. The LBA
51 * (loop begin address) register which holds DMA base address is 32bits
53 * But the MSB 2bits are used for other purposes(I guess it is really
54 * bad idea). This effectivly limits the DMA address space up to 1GB.
56 #define TR_MAXADDR ((1 << 30) - 1)
61 /* channel registers */
63 u_int32_t cso, alpha, fms, fmc, ec;
67 u_int32_t gvsel, pan, vol, ctrl;
68 u_int32_t active:1, was_active:1;
70 struct snd_dbuf *buffer;
71 struct pcm_channel *channel;
72 struct tr_info *parent;
77 u_int32_t active:1, was_active:1;
78 struct snd_dbuf *buffer;
79 struct pcm_channel *channel;
80 struct tr_info *parent;
83 /* device private data */
89 bus_space_handle_t sh;
90 bus_dma_tag_t parent_dmat;
92 struct resource *reg, *irq;
93 int regtype, regid, irqid;
101 struct tr_chinfo chinfo[TR_MAXPLAYCH];
102 struct tr_rchinfo recchinfo;
105 /* -------------------------------------------------------------------- */
107 static u_int32_t tr_recfmt[] = {
109 AFMT_STEREO | AFMT_U8,
111 AFMT_STEREO | AFMT_S8,
113 AFMT_STEREO | AFMT_S16_LE,
115 AFMT_STEREO | AFMT_U16_LE,
118 static struct pcmchan_caps tr_reccaps = {4000, 48000, tr_recfmt, 0};
120 static u_int32_t tr_playfmt[] = {
122 AFMT_STEREO | AFMT_U8,
124 AFMT_STEREO | AFMT_S8,
126 AFMT_STEREO | AFMT_S16_LE,
128 AFMT_STEREO | AFMT_U16_LE,
131 static struct pcmchan_caps tr_playcaps = {4000, 48000, tr_playfmt, 0};
133 /* -------------------------------------------------------------------- */
138 tr_rd(struct tr_info *tr, int regno, int size)
142 return bus_space_read_1(tr->st, tr->sh, regno);
144 return bus_space_read_2(tr->st, tr->sh, regno);
146 return bus_space_read_4(tr->st, tr->sh, regno);
153 tr_wr(struct tr_info *tr, int regno, u_int32_t data, int size)
157 bus_space_write_1(tr->st, tr->sh, regno, data);
160 bus_space_write_2(tr->st, tr->sh, regno, data);
163 bus_space_write_4(tr->st, tr->sh, regno, data);
168 /* -------------------------------------------------------------------- */
172 tr_rdcd(kobj_t obj, void *devinfo, int regno)
174 struct tr_info *tr = (struct tr_info *)devinfo;
179 treg=SPA_REG_CODECRD;
184 treg=TDX_REG_CODECWR;
186 treg=TDX_REG_CODECRD;
190 treg=TDX_REG_CODECRD;
194 treg=(regno & 0x100)? TNX_REG_CODEC2RD : TNX_REG_CODEC1RD;
198 kprintf("!!! tr_rdcd defaulted !!!\n");
205 snd_mtxlock(tr->lock);
206 if (tr->type == ALI_PCI_ID) {
207 u_int32_t chk1, chk2;
209 for (i = TR_TIMEOUT_CDC; (i > 0) && (j & trw); i--)
210 j = tr_rd(tr, treg, 4);
212 chk1 = tr_rd(tr, 0xc8, 4);
213 chk2 = tr_rd(tr, 0xc8, 4);
214 for (i = TR_TIMEOUT_CDC; (i > 0) && (chk1 == chk2);
216 chk2 = tr_rd(tr, 0xc8, 4);
219 if (tr->type != ALI_PCI_ID || i > 0) {
220 tr_wr(tr, treg, regno | trw, 4);
222 for (i=TR_TIMEOUT_CDC; (i > 0) && (j & trw); i--)
223 j=tr_rd(tr, treg, 4);
225 snd_mtxunlock(tr->lock);
226 if (i == 0) kprintf("codec timeout during read of register %x\n", regno);
227 return (j >> TR_CDC_DATA) & 0xffff;
231 tr_wrcd(kobj_t obj, void *devinfo, int regno, u_int32_t data)
233 struct tr_info *tr = (struct tr_info *)devinfo;
238 treg=SPA_REG_CODECWR;
243 treg=TDX_REG_CODECWR;
247 treg=TNX_REG_CODECWR;
248 trw=TNX_CDC_RWSTAT | ((regno & 0x100)? TNX_CDC_SEC : 0);
251 kprintf("!!! tr_wrcd defaulted !!!");
259 kprintf("tr_wrcd: reg %x was %x", regno, tr_rdcd(devinfo, regno));
262 snd_mtxlock(tr->lock);
263 if (tr->type == ALI_PCI_ID) {
265 for (i = TR_TIMEOUT_CDC; (i > 0) && (j & trw); i--)
266 j = tr_rd(tr, treg, 4);
268 u_int32_t chk1, chk2;
269 chk1 = tr_rd(tr, 0xc8, 4);
270 chk2 = tr_rd(tr, 0xc8, 4);
271 for (i = TR_TIMEOUT_CDC; (i > 0) && (chk1 == chk2);
273 chk2 = tr_rd(tr, 0xc8, 4);
276 if (tr->type != ALI_PCI_ID || i > 0) {
277 for (i=TR_TIMEOUT_CDC; (i>0) && (j & trw); i--)
278 j=tr_rd(tr, treg, 4);
279 if (tr->type == ALI_PCI_ID && tr->rev > 0x01)
281 tr_wr(tr, treg, (data << TR_CDC_DATA) | regno | trw, 4);
284 kprintf(" - wrote %x, now %x\n", data, tr_rdcd(devinfo, regno));
286 snd_mtxunlock(tr->lock);
287 if (i==0) kprintf("codec timeout writing %x, data %x\n", regno, data);
288 return (i > 0)? 0 : -1;
291 static kobj_method_t tr_ac97_methods[] = {
292 KOBJMETHOD(ac97_read, tr_rdcd),
293 KOBJMETHOD(ac97_write, tr_wrcd),
296 AC97_DECLARE(tr_ac97);
298 /* -------------------------------------------------------------------- */
299 /* playback channel interrupts */
303 tr_testint(struct tr_chinfo *ch)
305 struct tr_info *tr = ch->parent;
308 bank = (ch->index & 0x20) ? 1 : 0;
309 chan = ch->index & 0x1f;
310 return tr_rd(tr, bank? TR_REG_ADDRINTB : TR_REG_ADDRINTA, 4) & (1 << chan);
315 tr_clrint(struct tr_chinfo *ch)
317 struct tr_info *tr = ch->parent;
320 bank = (ch->index & 0x20) ? 1 : 0;
321 chan = ch->index & 0x1f;
322 tr_wr(tr, bank? TR_REG_ADDRINTB : TR_REG_ADDRINTA, 1 << chan, 4);
326 tr_enaint(struct tr_chinfo *ch, int enable)
328 struct tr_info *tr = ch->parent;
332 snd_mtxlock(tr->lock);
333 bank = (ch->index & 0x20) ? 1 : 0;
334 chan = ch->index & 0x1f;
335 reg = bank? TR_REG_INTENB : TR_REG_INTENA;
337 i = tr_rd(tr, reg, 4);
339 i |= (enable? 1 : 0) << chan;
342 tr_wr(tr, reg, i, 4);
343 snd_mtxunlock(tr->lock);
346 /* playback channels */
349 tr_selch(struct tr_chinfo *ch)
351 struct tr_info *tr = ch->parent;
354 i = tr_rd(tr, TR_REG_CIR, 4);
356 i |= ch->index & 0x3f;
357 tr_wr(tr, TR_REG_CIR, i, 4);
361 tr_startch(struct tr_chinfo *ch)
363 struct tr_info *tr = ch->parent;
366 bank = (ch->index & 0x20) ? 1 : 0;
367 chan = ch->index & 0x1f;
368 tr_wr(tr, bank? TR_REG_STARTB : TR_REG_STARTA, 1 << chan, 4);
372 tr_stopch(struct tr_chinfo *ch)
374 struct tr_info *tr = ch->parent;
377 bank = (ch->index & 0x20) ? 1 : 0;
378 chan = ch->index & 0x1f;
379 tr_wr(tr, bank? TR_REG_STOPB : TR_REG_STOPA, 1 << chan, 4);
383 tr_wrch(struct tr_chinfo *ch)
385 struct tr_info *tr = ch->parent;
386 u_int32_t cr[TR_CHN_REGS], i;
388 ch->gvsel &= 0x00000001;
389 ch->fmc &= 0x00000003;
390 ch->fms &= 0x0000000f;
391 ch->ctrl &= 0x0000000f;
392 ch->pan &= 0x0000007f;
393 ch->rvol &= 0x0000007f;
394 ch->cvol &= 0x0000007f;
395 ch->vol &= 0x000000ff;
396 ch->ec &= 0x00000fff;
397 ch->alpha &= 0x00000fff;
398 ch->delta &= 0x0000ffff;
399 ch->lba &= 0x3fffffff;
402 cr[3]=(ch->fmc<<14) | (ch->rvol<<7) | (ch->cvol);
403 cr[4]=(ch->gvsel<<31) | (ch->pan<<24) | (ch->vol<<16) | (ch->ctrl<<12) | (ch->ec);
409 ch->cso &= 0x0000ffff;
410 ch->eso &= 0x0000ffff;
411 cr[0]=(ch->cso<<16) | (ch->alpha<<4) | (ch->fms);
412 cr[2]=(ch->eso<<16) | (ch->delta);
415 ch->cso &= 0x00ffffff;
416 ch->eso &= 0x00ffffff;
417 cr[0]=((ch->delta & 0xff)<<24) | (ch->cso);
418 cr[2]=((ch->delta>>8)<<24) | (ch->eso);
419 cr[3]|=(ch->alpha<<20) | (ch->fms<<16) | (ch->fmc<<14);
422 snd_mtxlock(tr->lock);
424 for (i=0; i<TR_CHN_REGS; i++)
425 tr_wr(tr, TR_REG_CHNBASE+(i<<2), cr[i], 4);
426 snd_mtxunlock(tr->lock);
430 tr_rdch(struct tr_chinfo *ch)
432 struct tr_info *tr = ch->parent;
435 snd_mtxlock(tr->lock);
438 cr[i]=tr_rd(tr, TR_REG_CHNBASE+(i<<2), 4);
439 snd_mtxunlock(tr->lock);
442 ch->lba= (cr[1] & 0x3fffffff);
443 ch->fmc= (cr[3] & 0x0000c000) >> 14;
444 ch->rvol= (cr[3] & 0x00003f80) >> 7;
445 ch->cvol= (cr[3] & 0x0000007f);
446 ch->gvsel= (cr[4] & 0x80000000) >> 31;
447 ch->pan= (cr[4] & 0x7f000000) >> 24;
448 ch->vol= (cr[4] & 0x00ff0000) >> 16;
449 ch->ctrl= (cr[4] & 0x0000f000) >> 12;
450 ch->ec= (cr[4] & 0x00000fff);
455 ch->cso= (cr[0] & 0xffff0000) >> 16;
456 ch->alpha= (cr[0] & 0x0000fff0) >> 4;
457 ch->fms= (cr[0] & 0x0000000f);
458 ch->eso= (cr[2] & 0xffff0000) >> 16;
459 ch->delta= (cr[2] & 0x0000ffff);
462 ch->cso= (cr[0] & 0x00ffffff);
463 ch->eso= (cr[2] & 0x00ffffff);
464 ch->delta= ((cr[2] & 0xff000000) >> 16) | ((cr[0] & 0xff000000) >> 24);
465 ch->alpha= (cr[3] & 0xfff00000) >> 20;
466 ch->fms= (cr[3] & 0x000f0000) >> 16;
472 tr_fmttobits(u_int32_t fmt)
477 bits |= (fmt & AFMT_SIGNED)? 0x2 : 0;
478 bits |= (fmt & AFMT_STEREO)? 0x4 : 0;
479 bits |= (fmt & AFMT_16BIT)? 0x8 : 0;
484 /* -------------------------------------------------------------------- */
485 /* channel interface */
488 trpchan_init(kobj_t obj, void *devinfo, struct snd_dbuf *b, struct pcm_channel *c, int dir)
490 struct tr_info *tr = devinfo;
491 struct tr_chinfo *ch;
493 KASSERT(dir == PCMDIR_PLAY, ("trpchan_init: bad direction"));
494 ch = &tr->chinfo[tr->playchns];
495 ch->index = tr->playchns++;
499 if (sndbuf_alloc(ch->buffer, tr->parent_dmat, tr->bufsz) != 0)
506 trpchan_setformat(kobj_t obj, void *data, u_int32_t format)
508 struct tr_chinfo *ch = data;
510 ch->ctrl = tr_fmttobits(format) | 0x01;
516 trpchan_setspeed(kobj_t obj, void *data, u_int32_t speed)
518 struct tr_chinfo *ch = data;
520 ch->delta = (speed << 12) / 48000;
521 return (ch->delta * 48000) >> 12;
525 trpchan_setblocksize(kobj_t obj, void *data, u_int32_t blocksize)
527 struct tr_chinfo *ch = data;
529 sndbuf_resize(ch->buffer, 2, blocksize);
534 trpchan_trigger(kobj_t obj, void *data, int go)
536 struct tr_chinfo *ch = data;
538 if (go == PCMTRIG_EMLDMAWR || go == PCMTRIG_EMLDMARD)
541 if (go == PCMTRIG_START) {
546 ch->lba = sndbuf_getbufaddr(ch->buffer);
548 ch->eso = (sndbuf_getsize(ch->buffer) / sndbuf_getbps(ch->buffer)) - 1;
549 ch->rvol = ch->cvol = 0x7f;
567 trpchan_getptr(kobj_t obj, void *data)
569 struct tr_chinfo *ch = data;
572 return ch->cso * sndbuf_getbps(ch->buffer);
575 static struct pcmchan_caps *
576 trpchan_getcaps(kobj_t obj, void *data)
581 static kobj_method_t trpchan_methods[] = {
582 KOBJMETHOD(channel_init, trpchan_init),
583 KOBJMETHOD(channel_setformat, trpchan_setformat),
584 KOBJMETHOD(channel_setspeed, trpchan_setspeed),
585 KOBJMETHOD(channel_setblocksize, trpchan_setblocksize),
586 KOBJMETHOD(channel_trigger, trpchan_trigger),
587 KOBJMETHOD(channel_getptr, trpchan_getptr),
588 KOBJMETHOD(channel_getcaps, trpchan_getcaps),
591 CHANNEL_DECLARE(trpchan);
593 /* -------------------------------------------------------------------- */
594 /* rec channel interface */
597 trrchan_init(kobj_t obj, void *devinfo, struct snd_dbuf *b, struct pcm_channel *c, int dir)
599 struct tr_info *tr = devinfo;
600 struct tr_rchinfo *ch;
602 KASSERT(dir == PCMDIR_REC, ("trrchan_init: bad direction"));
607 if (sndbuf_alloc(ch->buffer, tr->parent_dmat, tr->bufsz) != 0)
614 trrchan_setformat(kobj_t obj, void *data, u_int32_t format)
616 struct tr_rchinfo *ch = data;
617 struct tr_info *tr = ch->parent;
620 bits = tr_fmttobits(format);
621 /* set # of samples between interrupts */
622 i = (sndbuf_runsz(ch->buffer) >> ((bits & 0x08)? 1 : 0)) - 1;
623 tr_wr(tr, TR_REG_SBBL, i | (i << 16), 4);
624 /* set sample format */
625 i = 0x18 | (bits << 4);
626 tr_wr(tr, TR_REG_SBCTRL, i, 1);
633 trrchan_setspeed(kobj_t obj, void *data, u_int32_t speed)
635 struct tr_rchinfo *ch = data;
636 struct tr_info *tr = ch->parent;
639 ch->delta = (48000 << 12) / speed;
640 tr_wr(tr, TR_REG_SBDELTA, ch->delta, 2);
642 /* return closest possible speed */
643 return (48000 << 12) / ch->delta;
647 trrchan_setblocksize(kobj_t obj, void *data, u_int32_t blocksize)
649 struct tr_rchinfo *ch = data;
651 sndbuf_resize(ch->buffer, 2, blocksize);
657 trrchan_trigger(kobj_t obj, void *data, int go)
659 struct tr_rchinfo *ch = data;
660 struct tr_info *tr = ch->parent;
663 if (go == PCMTRIG_EMLDMAWR || go == PCMTRIG_EMLDMARD)
666 if (go == PCMTRIG_START) {
667 /* set up dma mode regs */
668 tr_wr(tr, TR_REG_DMAR15, 0, 1);
669 i = tr_rd(tr, TR_REG_DMAR11, 1) & 0x03;
670 tr_wr(tr, TR_REG_DMAR11, i | 0x54, 1);
671 /* set up base address */
672 tr_wr(tr, TR_REG_DMAR0, sndbuf_getbufaddr(ch->buffer), 4);
673 /* set up buffer size */
674 i = tr_rd(tr, TR_REG_DMAR4, 4) & ~0x00ffffff;
675 tr_wr(tr, TR_REG_DMAR4, i | (sndbuf_runsz(ch->buffer) - 1), 4);
677 tr_wr(tr, TR_REG_SBCTRL, tr_rd(tr, TR_REG_SBCTRL, 1) | 1, 1);
680 tr_wr(tr, TR_REG_SBCTRL, tr_rd(tr, TR_REG_SBCTRL, 1) & ~7, 1);
689 trrchan_getptr(kobj_t obj, void *data)
691 struct tr_rchinfo *ch = data;
692 struct tr_info *tr = ch->parent;
694 /* return current byte offset of channel */
695 return tr_rd(tr, TR_REG_DMAR0, 4) - sndbuf_getbufaddr(ch->buffer);
698 static struct pcmchan_caps *
699 trrchan_getcaps(kobj_t obj, void *data)
704 static kobj_method_t trrchan_methods[] = {
705 KOBJMETHOD(channel_init, trrchan_init),
706 KOBJMETHOD(channel_setformat, trrchan_setformat),
707 KOBJMETHOD(channel_setspeed, trrchan_setspeed),
708 KOBJMETHOD(channel_setblocksize, trrchan_setblocksize),
709 KOBJMETHOD(channel_trigger, trrchan_trigger),
710 KOBJMETHOD(channel_getptr, trrchan_getptr),
711 KOBJMETHOD(channel_getcaps, trrchan_getcaps),
714 CHANNEL_DECLARE(trrchan);
716 /* -------------------------------------------------------------------- */
717 /* The interrupt handler */
722 struct tr_info *tr = (struct tr_info *)p;
723 struct tr_chinfo *ch;
724 u_int32_t active, mask, bufhalf, chnum, intsrc;
727 intsrc = tr_rd(tr, TR_REG_MISCINT, 4);
728 if (intsrc & TR_INT_ADDR) {
732 active = tr_rd(tr, (chnum < 32)? TR_REG_ADDRINTA : TR_REG_ADDRINTB, 4);
733 bufhalf = tr_rd(tr, (chnum < 32)? TR_REG_CSPF_A : TR_REG_CSPF_B, 4);
737 tmp = (bufhalf & mask)? 1 : 0;
738 if (chnum < tr->playchns) {
739 ch = &tr->chinfo[chnum];
740 /* kprintf("%d @ %d, ", chnum, trpchan_getptr(NULL, ch)); */
741 if (ch->bufhalf != tmp) {
742 chn_intr(ch->channel);
749 } while (chnum & 31);
753 tr_wr(tr, (chnum <= 32)? TR_REG_ADDRINTA : TR_REG_ADDRINTB, active, 4);
756 if (intsrc & TR_INT_SB) {
757 chn_intr(tr->recchinfo.channel);
758 tr_rd(tr, TR_REG_SBR9, 1);
759 tr_rd(tr, TR_REG_SBR10, 1);
763 /* -------------------------------------------------------------------- */
766 * Probe and attach the card
770 tr_init(struct tr_info *tr)
774 tr_wr(tr, SPA_REG_GPIO, 0, 4);
775 tr_wr(tr, SPA_REG_CODECST, SPA_RST_OFF, 4);
778 tr_wr(tr, TDX_REG_CODECST, TDX_CDC_ON, 4);
781 tr_wr(tr, TNX_REG_CODECST, TNX_CDC_ON, 4);
785 tr_wr(tr, TR_REG_CIR, TR_CIR_MIDENA | TR_CIR_ADDRENA, 4);
790 tr_pci_probe(device_t dev)
792 switch (pci_get_devid(dev)) {
794 device_set_desc(dev, "SiS 7018");
795 return BUS_PROBE_DEFAULT;
797 device_set_desc(dev, "Acer Labs M5451");
798 return BUS_PROBE_DEFAULT;
800 device_set_desc(dev, "Trident 4DWave DX");
801 return BUS_PROBE_DEFAULT;
803 device_set_desc(dev, "Trident 4DWave NX");
804 return BUS_PROBE_DEFAULT;
811 tr_pci_attach(device_t dev)
815 struct ac97_info *codec = NULL;
817 char status[SND_STATUSLEN];
819 tr = kmalloc(sizeof(*tr), M_DEVBUF, M_WAITOK | M_ZERO);
820 tr->type = pci_get_devid(dev);
821 tr->rev = pci_get_revid(dev);
822 tr->lock = snd_mtxcreate(device_get_nameunit(dev), "sound softc");
824 if (resource_int_value(device_get_name(dev), device_get_unit(dev),
828 else if (i > TR_MAXPLAYCH)
843 data = pci_read_config(dev, PCIR_COMMAND, 2);
844 data |= (PCIM_CMD_PORTEN|PCIM_CMD_MEMEN|PCIM_CMD_BUSMASTEREN);
845 pci_write_config(dev, PCIR_COMMAND, data, 2);
846 data = pci_read_config(dev, PCIR_COMMAND, 2);
848 tr->regid = PCIR_BAR(0);
849 tr->regtype = SYS_RES_IOPORT;
850 tr->reg = bus_alloc_resource_any(dev, tr->regtype, &tr->regid,
853 tr->st = rman_get_bustag(tr->reg);
854 tr->sh = rman_get_bushandle(tr->reg);
856 device_printf(dev, "unable to map register space\n");
860 tr->bufsz = pcm_getbuffersize(dev, 4096, TR_DEFAULT_BUFSZ, 65536);
862 if (tr_init(tr) == -1) {
863 device_printf(dev, "unable to initialize the card\n");
868 codec = AC97_CREATE(dev, tr, tr_ac97);
869 if (codec == NULL) goto bad;
870 if (mixer_init(dev, ac97_getmixerclass(), codec) == -1) goto bad;
873 tr->irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &tr->irqid,
874 RF_ACTIVE | RF_SHAREABLE);
875 if (!tr->irq || snd_setup_intr(dev, tr->irq, 0, tr_intr, tr, &tr->ih)) {
876 device_printf(dev, "unable to map interrupt\n");
880 if (bus_dma_tag_create(/*parent*/NULL, /*alignment*/2, /*boundary*/0,
881 /*lowaddr*/TR_MAXADDR,
882 /*highaddr*/BUS_SPACE_MAXADDR,
883 /*filter*/NULL, /*filterarg*/NULL,
884 /*maxsize*/tr->bufsz, /*nsegments*/1, /*maxsegz*/0x3ffff,
886 &tr->parent_dmat) != 0) {
887 device_printf(dev, "unable to create dma tag\n");
891 ksnprintf(status, 64, "at io 0x%lx irq %ld %s",
892 rman_get_start(tr->reg), rman_get_start(tr->irq),PCM_KLDSTRING(snd_t4dwave));
894 if (pcm_register(dev, tr, dacn, 1))
896 pcm_addchan(dev, PCMDIR_REC, &trrchan_class, tr);
897 for (i = 0; i < dacn; i++)
898 pcm_addchan(dev, PCMDIR_PLAY, &trpchan_class, tr);
899 pcm_setstatus(dev, status);
904 if (codec) ac97_destroy(codec);
905 if (tr->reg) bus_release_resource(dev, tr->regtype, tr->regid, tr->reg);
906 if (tr->ih) bus_teardown_intr(dev, tr->irq, tr->ih);
907 if (tr->irq) bus_release_resource(dev, SYS_RES_IRQ, tr->irqid, tr->irq);
908 if (tr->parent_dmat) bus_dma_tag_destroy(tr->parent_dmat);
909 if (tr->lock) snd_mtxfree(tr->lock);
915 tr_pci_detach(device_t dev)
920 r = pcm_unregister(dev);
924 tr = pcm_getdevinfo(dev);
925 bus_release_resource(dev, tr->regtype, tr->regid, tr->reg);
926 bus_teardown_intr(dev, tr->irq, tr->ih);
927 bus_release_resource(dev, SYS_RES_IRQ, tr->irqid, tr->irq);
928 bus_dma_tag_destroy(tr->parent_dmat);
929 snd_mtxfree(tr->lock);
936 tr_pci_suspend(device_t dev)
941 tr = pcm_getdevinfo(dev);
943 for (i = 0; i < tr->playchns; i++) {
944 tr->chinfo[i].was_active = tr->chinfo[i].active;
945 if (tr->chinfo[i].active) {
946 trpchan_trigger(NULL, &tr->chinfo[i], PCMTRIG_STOP);
950 tr->recchinfo.was_active = tr->recchinfo.active;
951 if (tr->recchinfo.active) {
952 trrchan_trigger(NULL, &tr->recchinfo, PCMTRIG_STOP);
959 tr_pci_resume(device_t dev)
964 tr = pcm_getdevinfo(dev);
966 if (tr_init(tr) == -1) {
967 device_printf(dev, "unable to initialize the card\n");
971 if (mixer_reinit(dev) == -1) {
972 device_printf(dev, "unable to initialize the mixer\n");
976 for (i = 0; i < tr->playchns; i++) {
977 if (tr->chinfo[i].was_active) {
978 trpchan_trigger(NULL, &tr->chinfo[i], PCMTRIG_START);
982 if (tr->recchinfo.was_active) {
983 trrchan_trigger(NULL, &tr->recchinfo, PCMTRIG_START);
989 static device_method_t tr_methods[] = {
990 /* Device interface */
991 DEVMETHOD(device_probe, tr_pci_probe),
992 DEVMETHOD(device_attach, tr_pci_attach),
993 DEVMETHOD(device_detach, tr_pci_detach),
994 DEVMETHOD(device_suspend, tr_pci_suspend),
995 DEVMETHOD(device_resume, tr_pci_resume),
999 static driver_t tr_driver = {
1005 DRIVER_MODULE(snd_t4dwave, pci, tr_driver, pcm_devclass, NULL, NULL);
1006 MODULE_DEPEND(snd_t4dwave, sound, SOUND_MINVER, SOUND_PREFVER, SOUND_MAXVER);
1007 MODULE_VERSION(snd_t4dwave, 1);