2 * Copyright (c) 1999 Cameron Grant <gandalf@vilnya.demon.co.uk>
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 THE POSSIBILITY OF
26 * $FreeBSD: src/sys/dev/sound/pci/emu10k1.c,v 1.6.2.9 2002/04/22 15:49:32 cg Exp $
27 * $DragonFly: src/sys/dev/sound/pci/emu10k1.c,v 1.2 2003/06/17 04:28:30 dillon Exp $
30 #include <dev/sound/pcm/sound.h>
31 #include <dev/sound/pcm/ac97.h>
32 #include <gnu/dev/sound/pci/emu10k1.h>
34 #include <pci/pcireg.h>
35 #include <pci/pcivar.h>
36 #include <sys/queue.h>
38 SND_DECLARE_FILE("$DragonFly: src/sys/dev/sound/pci/emu10k1.c,v 1.2 2003/06/17 04:28:30 dillon Exp $");
40 /* -------------------------------------------------------------------- */
42 #define EMU10K1_PCI_ID 0x00021102
43 #define EMU10K2_PCI_ID 0x00041102
44 #define EMU_DEFAULT_BUFSZ 4096
49 SLIST_ENTRY(emu_memblk) link;
51 u_int32_t pte_start, pte_size;
55 u_int8_t bmap[MAXPAGES / 8];
58 SLIST_HEAD(, emu_memblk) blocks;
63 int b16:1, stereo:1, busy:1, running:1, ismaster:1;
67 struct emu_voice *slave;
68 struct pcm_channel *channel;
73 /* channel registers */
75 int spd, fmt, blksz, run;
76 struct emu_voice *master, *slave;
77 struct snd_dbuf *buffer;
78 struct pcm_channel *channel;
79 struct sc_info *parent;
83 int spd, fmt, run, blksz, num;
84 u_int32_t idxreg, basereg, sizereg, setupreg, irqmask;
85 struct snd_dbuf *buffer;
86 struct pcm_channel *channel;
87 struct sc_info *parent;
90 /* device private data */
94 u_int32_t tos_link:1, APS:1;
97 bus_space_handle_t sh;
98 bus_dma_tag_t parent_dmat;
100 struct resource *reg, *irq;
105 int timer, timerinterval;
108 struct emu_voice voice[64];
109 struct sc_pchinfo pch[EMU_CHANS];
110 struct sc_rchinfo rch[3];
113 /* -------------------------------------------------------------------- */
120 static int emu_init(struct sc_info *);
121 static void emu_intr(void *);
122 static void *emu_malloc(struct sc_info *sc, u_int32_t sz);
123 static void *emu_memalloc(struct sc_info *sc, u_int32_t sz);
124 static int emu_memfree(struct sc_info *sc, void *buf);
125 static int emu_memstart(struct sc_info *sc, void *buf);
127 static void emu_vdump(struct sc_info *sc, struct emu_voice *v);
130 /* talk to the card */
131 static u_int32_t emu_rd(struct sc_info *, int, int);
132 static void emu_wr(struct sc_info *, int, u_int32_t, int);
134 /* -------------------------------------------------------------------- */
136 static u_int32_t emu_rfmt_ac97[] = {
138 AFMT_STEREO | AFMT_S16_LE,
142 static u_int32_t emu_rfmt_mic[] = {
147 static u_int32_t emu_rfmt_efx[] = {
148 AFMT_STEREO | AFMT_S16_LE,
152 static struct pcmchan_caps emu_reccaps[3] = {
153 {8000, 48000, emu_rfmt_ac97, 0},
154 {8000, 8000, emu_rfmt_mic, 0},
155 {48000, 48000, emu_rfmt_efx, 0},
158 static u_int32_t emu_pfmt[] = {
160 AFMT_STEREO | AFMT_U8,
162 AFMT_STEREO | AFMT_S16_LE,
166 static struct pcmchan_caps emu_playcaps = {4000, 48000, emu_pfmt, 0};
168 static int adcspeed[8] = {48000, 44100, 32000, 24000, 22050, 16000, 11025, 8000};
170 /* -------------------------------------------------------------------- */
173 emu_rd(struct sc_info *sc, int regno, int size)
177 return bus_space_read_1(sc->st, sc->sh, regno);
179 return bus_space_read_2(sc->st, sc->sh, regno);
181 return bus_space_read_4(sc->st, sc->sh, regno);
188 emu_wr(struct sc_info *sc, int regno, u_int32_t data, int size)
192 bus_space_write_1(sc->st, sc->sh, regno, data);
195 bus_space_write_2(sc->st, sc->sh, regno, data);
198 bus_space_write_4(sc->st, sc->sh, regno, data);
204 emu_rdptr(struct sc_info *sc, int chn, int reg)
206 u_int32_t ptr, val, mask, size, offset;
208 ptr = ((reg << 16) & PTR_ADDRESS_MASK) | (chn & PTR_CHANNELNUM_MASK);
209 emu_wr(sc, PTR, ptr, 4);
210 val = emu_rd(sc, DATA, 4);
211 if (reg & 0xff000000) {
212 size = (reg >> 24) & 0x3f;
213 offset = (reg >> 16) & 0x1f;
214 mask = ((1 << size) - 1) << offset;
222 emu_wrptr(struct sc_info *sc, int chn, int reg, u_int32_t data)
224 u_int32_t ptr, mask, size, offset;
226 ptr = ((reg << 16) & PTR_ADDRESS_MASK) | (chn & PTR_CHANNELNUM_MASK);
227 emu_wr(sc, PTR, ptr, 4);
228 if (reg & 0xff000000) {
229 size = (reg >> 24) & 0x3f;
230 offset = (reg >> 16) & 0x1f;
231 mask = ((1 << size) - 1) << offset;
234 data |= emu_rd(sc, DATA, 4) & ~mask;
236 emu_wr(sc, DATA, data, 4);
240 emu_wrefx(struct sc_info *sc, unsigned int pc, unsigned int data)
242 emu_wrptr(sc, 0, MICROCODEBASE + pc, data);
245 /* -------------------------------------------------------------------- */
247 /* no locking needed */
250 emu_rdcd(kobj_t obj, void *devinfo, int regno)
252 struct sc_info *sc = (struct sc_info *)devinfo;
254 emu_wr(sc, AC97ADDRESS, regno, 1);
255 return emu_rd(sc, AC97DATA, 2);
259 emu_wrcd(kobj_t obj, void *devinfo, int regno, u_int32_t data)
261 struct sc_info *sc = (struct sc_info *)devinfo;
263 emu_wr(sc, AC97ADDRESS, regno, 1);
264 emu_wr(sc, AC97DATA, data, 2);
268 static kobj_method_t emu_ac97_methods[] = {
269 KOBJMETHOD(ac97_read, emu_rdcd),
270 KOBJMETHOD(ac97_write, emu_wrcd),
273 AC97_DECLARE(emu_ac97);
275 /* -------------------------------------------------------------------- */
278 emu_settimer(struct sc_info *sc)
280 struct sc_pchinfo *pch;
281 struct sc_rchinfo *rch;
285 for (i = 0; i < EMU_CHANS; i++) {
288 tmp = (pch->spd * sndbuf_getbps(pch->buffer)) / pch->blksz;
294 for (i = 0; i < 3; i++) {
297 tmp = (rch->spd * sndbuf_getbps(rch->buffer)) / rch->blksz;
302 RANGE(rate, 48, 9600);
303 sc->timerinterval = 48000 / rate;
304 emu_wr(sc, TIMER, sc->timerinterval & 0x03ff, 2);
306 return sc->timerinterval;
310 emu_enatimer(struct sc_info *sc, int go)
314 if (sc->timer++ == 0) {
315 x = emu_rd(sc, INTE, 4);
316 x |= INTE_INTERVALTIMERENB;
317 emu_wr(sc, INTE, x, 4);
321 x = emu_rd(sc, INTE, 4);
322 x &= ~INTE_INTERVALTIMERENB;
323 emu_wr(sc, INTE, x, 4);
329 emu_enastop(struct sc_info *sc, char channel, int enable)
331 int reg = (channel & 0x20)? SOLEH : SOLEL;
334 reg |= channel << 16;
335 emu_wrptr(sc, 0, reg, enable);
339 emu_recval(int speed) {
343 while (val < 7 && speed < adcspeed[val])
349 emu_rate_to_pitch(u_int32_t rate)
351 static u_int32_t logMagTable[128] = {
352 0x00000, 0x02dfc, 0x05b9e, 0x088e6, 0x0b5d6, 0x0e26f, 0x10eb3, 0x13aa2,
353 0x1663f, 0x1918a, 0x1bc84, 0x1e72e, 0x2118b, 0x23b9a, 0x2655d, 0x28ed5,
354 0x2b803, 0x2e0e8, 0x30985, 0x331db, 0x359eb, 0x381b6, 0x3a93d, 0x3d081,
355 0x3f782, 0x41e42, 0x444c1, 0x46b01, 0x49101, 0x4b6c4, 0x4dc49, 0x50191,
356 0x5269e, 0x54b6f, 0x57006, 0x59463, 0x5b888, 0x5dc74, 0x60029, 0x623a7,
357 0x646ee, 0x66a00, 0x68cdd, 0x6af86, 0x6d1fa, 0x6f43c, 0x7164b, 0x73829,
358 0x759d4, 0x77b4f, 0x79c9a, 0x7bdb5, 0x7dea1, 0x7ff5e, 0x81fed, 0x8404e,
359 0x86082, 0x88089, 0x8a064, 0x8c014, 0x8df98, 0x8fef1, 0x91e20, 0x93d26,
360 0x95c01, 0x97ab4, 0x9993e, 0x9b79f, 0x9d5d9, 0x9f3ec, 0xa11d8, 0xa2f9d,
361 0xa4d3c, 0xa6ab5, 0xa8808, 0xaa537, 0xac241, 0xadf26, 0xafbe7, 0xb1885,
362 0xb3500, 0xb5157, 0xb6d8c, 0xb899f, 0xba58f, 0xbc15e, 0xbdd0c, 0xbf899,
363 0xc1404, 0xc2f50, 0xc4a7b, 0xc6587, 0xc8073, 0xc9b3f, 0xcb5ed, 0xcd07c,
364 0xceaec, 0xd053f, 0xd1f73, 0xd398a, 0xd5384, 0xd6d60, 0xd8720, 0xda0c3,
365 0xdba4a, 0xdd3b4, 0xded03, 0xe0636, 0xe1f4e, 0xe384a, 0xe512c, 0xe69f3,
366 0xe829f, 0xe9b31, 0xeb3a9, 0xecc08, 0xee44c, 0xefc78, 0xf148a, 0xf2c83,
367 0xf4463, 0xf5c2a, 0xf73da, 0xf8b71, 0xfa2f0, 0xfba57, 0xfd1a7, 0xfe8df
369 static char logSlopeTable[128] = {
370 0x5c, 0x5c, 0x5b, 0x5a, 0x5a, 0x59, 0x58, 0x58,
371 0x57, 0x56, 0x56, 0x55, 0x55, 0x54, 0x53, 0x53,
372 0x52, 0x52, 0x51, 0x51, 0x50, 0x50, 0x4f, 0x4f,
373 0x4e, 0x4d, 0x4d, 0x4d, 0x4c, 0x4c, 0x4b, 0x4b,
374 0x4a, 0x4a, 0x49, 0x49, 0x48, 0x48, 0x47, 0x47,
375 0x47, 0x46, 0x46, 0x45, 0x45, 0x45, 0x44, 0x44,
376 0x43, 0x43, 0x43, 0x42, 0x42, 0x42, 0x41, 0x41,
377 0x41, 0x40, 0x40, 0x40, 0x3f, 0x3f, 0x3f, 0x3e,
378 0x3e, 0x3e, 0x3d, 0x3d, 0x3d, 0x3c, 0x3c, 0x3c,
379 0x3b, 0x3b, 0x3b, 0x3b, 0x3a, 0x3a, 0x3a, 0x39,
380 0x39, 0x39, 0x39, 0x38, 0x38, 0x38, 0x38, 0x37,
381 0x37, 0x37, 0x37, 0x36, 0x36, 0x36, 0x36, 0x35,
382 0x35, 0x35, 0x35, 0x34, 0x34, 0x34, 0x34, 0x34,
383 0x33, 0x33, 0x33, 0x33, 0x32, 0x32, 0x32, 0x32,
384 0x32, 0x31, 0x31, 0x31, 0x31, 0x31, 0x30, 0x30,
385 0x30, 0x30, 0x30, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f
390 return 0; /* Bail out if no leading "1" */
391 rate *= 11185; /* Scale 48000 to 0x20002380 */
392 for (i = 31; i > 0; i--) {
393 if (rate & 0x80000000) { /* Detect leading "1" */
394 return (((u_int32_t) (i - 15) << 20) +
395 logMagTable[0x7f & (rate >> 24)] +
396 (0x7f & (rate >> 17)) *
397 logSlopeTable[0x7f & (rate >> 24)]);
402 return 0; /* Should never reach this point */
406 emu_rate_to_linearpitch(u_int32_t rate)
408 rate = (rate << 8) / 375;
409 return (rate >> 1) + (rate & 1);
412 static struct emu_voice *
413 emu_valloc(struct sc_info *sc)
419 for (i = 0; i < 64 && sc->voice[i].busy; i++);
428 emu_vinit(struct sc_info *sc, struct emu_voice *m, struct emu_voice *s,
429 u_int32_t sz, struct snd_dbuf *b)
433 buf = emu_memalloc(sc, sz);
437 sndbuf_setup(b, buf, sz);
438 m->start = emu_memstart(sc, buf) * EMUPAGESIZE;
439 m->end = m->start + sz;
447 m->buf = vtophys(buf);
466 emu_vsetup(struct sc_pchinfo *ch)
468 struct emu_voice *v = ch->master;
471 v->b16 = (ch->fmt & AFMT_16BIT)? 1 : 0;
472 v->stereo = (ch->fmt & AFMT_STEREO)? 1 : 0;
473 if (v->slave != NULL) {
474 v->slave->b16 = v->b16;
475 v->slave->stereo = v->stereo;
480 if (v->slave != NULL)
481 v->slave->speed = v->speed;
486 emu_vwrite(struct sc_info *sc, struct emu_voice *v)
490 u_int32_t sa, ea, start, val, silent_page;
492 s = (v->stereo? 1 : 0) + (v->b16? 1 : 0);
497 l = r = x = y = v->vol;
499 l = v->ismaster? l : 0;
500 r = v->ismaster? 0 : r;
503 emu_wrptr(sc, v->vnum, CPF, v->stereo? CPF_STEREO_MASK : 0);
504 val = v->stereo? 28 : 30;
505 val *= v->b16? 1 : 2;
508 emu_wrptr(sc, v->vnum, FXRT, 0xd01c0000);
510 emu_wrptr(sc, v->vnum, PTRX, (x << 8) | r);
511 emu_wrptr(sc, v->vnum, DSL, ea | (y << 24));
512 emu_wrptr(sc, v->vnum, PSST, sa | (l << 24));
513 emu_wrptr(sc, v->vnum, CCCA, start | (v->b16? 0 : CCCA_8BITSELECT));
515 emu_wrptr(sc, v->vnum, Z1, 0);
516 emu_wrptr(sc, v->vnum, Z2, 0);
518 silent_page = ((u_int32_t)vtophys(sc->mem.silent_page) << 1) | MAP_PTI_MASK;
519 emu_wrptr(sc, v->vnum, MAPA, silent_page);
520 emu_wrptr(sc, v->vnum, MAPB, silent_page);
522 emu_wrptr(sc, v->vnum, CVCF, CVCF_CURRENTFILTER_MASK);
523 emu_wrptr(sc, v->vnum, VTFT, VTFT_FILTERTARGET_MASK);
524 emu_wrptr(sc, v->vnum, ATKHLDM, 0);
525 emu_wrptr(sc, v->vnum, DCYSUSM, DCYSUSM_DECAYTIME_MASK);
526 emu_wrptr(sc, v->vnum, LFOVAL1, 0x8000);
527 emu_wrptr(sc, v->vnum, LFOVAL2, 0x8000);
528 emu_wrptr(sc, v->vnum, FMMOD, 0);
529 emu_wrptr(sc, v->vnum, TREMFRQ, 0);
530 emu_wrptr(sc, v->vnum, FM2FRQ2, 0);
531 emu_wrptr(sc, v->vnum, ENVVAL, 0x8000);
533 emu_wrptr(sc, v->vnum, ATKHLDV, ATKHLDV_HOLDTIME_MASK | ATKHLDV_ATTACKTIME_MASK);
534 emu_wrptr(sc, v->vnum, ENVVOL, 0x8000);
536 emu_wrptr(sc, v->vnum, PEFE_FILTERAMOUNT, 0x7f);
537 emu_wrptr(sc, v->vnum, PEFE_PITCHAMOUNT, 0);
539 if (v->slave != NULL)
540 emu_vwrite(sc, v->slave);
544 emu_vtrigger(struct sc_info *sc, struct emu_voice *v, int go)
546 u_int32_t pitch_target, initial_pitch;
547 u_int32_t cra, cs, ccis;
552 cs = v->stereo? 4 : 2;
553 ccis = v->stereo? 28 : 30;
554 ccis *= v->b16? 1 : 2;
555 sample = v->b16? 0x00000000 : 0x80808080;
557 for (i = 0; i < cs; i++)
558 emu_wrptr(sc, v->vnum, CD0 + i, sample);
559 emu_wrptr(sc, v->vnum, CCR_CACHEINVALIDSIZE, 0);
560 emu_wrptr(sc, v->vnum, CCR_READADDRESS, cra);
561 emu_wrptr(sc, v->vnum, CCR_CACHEINVALIDSIZE, ccis);
563 emu_wrptr(sc, v->vnum, IFATN, 0xff00);
564 emu_wrptr(sc, v->vnum, VTFT, 0xffffffff);
565 emu_wrptr(sc, v->vnum, CVCF, 0xffffffff);
566 emu_wrptr(sc, v->vnum, DCYSUSV, 0x00007f7f);
567 emu_enastop(sc, v->vnum, 0);
569 pitch_target = emu_rate_to_linearpitch(v->speed);
570 initial_pitch = emu_rate_to_pitch(v->speed) >> 8;
571 emu_wrptr(sc, v->vnum, PTRX_PITCHTARGET, pitch_target);
572 emu_wrptr(sc, v->vnum, CPF_CURRENTPITCH, pitch_target);
573 emu_wrptr(sc, v->vnum, IP, initial_pitch);
575 emu_wrptr(sc, v->vnum, PTRX_PITCHTARGET, 0);
576 emu_wrptr(sc, v->vnum, CPF_CURRENTPITCH, 0);
577 emu_wrptr(sc, v->vnum, IFATN, 0xffff);
578 emu_wrptr(sc, v->vnum, VTFT, 0x0000ffff);
579 emu_wrptr(sc, v->vnum, CVCF, 0x0000ffff);
580 emu_wrptr(sc, v->vnum, IP, 0);
581 emu_enastop(sc, v->vnum, 1);
583 if (v->slave != NULL)
584 emu_vtrigger(sc, v->slave, go);
588 emu_vpos(struct sc_info *sc, struct emu_voice *v)
592 s = (v->b16? 1 : 0) + (v->stereo? 1 : 0);
593 ptr = (emu_rdptr(sc, v->vnum, CCCA_CURRADDR) - (v->start >> s)) << s;
594 return ptr & ~0x0000001f;
599 emu_vdump(struct sc_info *sc, struct emu_voice *v)
601 char *regname[] = { "cpf", "ptrx", "cvcf", "vtft", "z2", "z1", "psst", "dsl",
602 "ccca", "ccr", "clp", "fxrt", "mapa", "mapb", NULL, NULL,
603 "envvol", "atkhldv", "dcysusv", "lfoval1",
604 "envval", "atkhldm", "dcysusm", "lfoval2",
605 "ip", "ifatn", "pefe", "fmmod", "tremfrq", "fmfrq2",
609 printf("voice number %d\n", v->vnum);
610 for (i = 0, x = 0; i <= 0x1e; i++) {
611 if (regname[i] == NULL)
613 printf("%s\t[%08x]", regname[i], emu_rdptr(sc, v->vnum, i));
614 printf("%s", (x == 2)? "\n" : "\t");
623 /* channel interface */
625 emupchan_init(kobj_t obj, void *devinfo, struct snd_dbuf *b, struct pcm_channel *c, int dir)
627 struct sc_info *sc = devinfo;
628 struct sc_pchinfo *ch;
631 KASSERT(dir == PCMDIR_PLAY, ("emupchan_init: bad direction"));
632 ch = &sc->pch[sc->pnum++];
636 ch->blksz = sc->bufsz / 2;
639 snd_mtxlock(sc->lock);
640 ch->master = emu_valloc(sc);
641 ch->slave = emu_valloc(sc);
642 r = (emu_vinit(sc, ch->master, ch->slave, sc->bufsz, ch->buffer))? NULL : ch;
643 snd_mtxunlock(sc->lock);
649 emupchan_free(kobj_t obj, void *data)
651 struct sc_pchinfo *ch = data;
652 struct sc_info *sc = ch->parent;
655 snd_mtxlock(sc->lock);
656 r = emu_memfree(sc, sndbuf_getbuf(ch->buffer));
657 snd_mtxunlock(sc->lock);
663 emupchan_setformat(kobj_t obj, void *data, u_int32_t format)
665 struct sc_pchinfo *ch = data;
672 emupchan_setspeed(kobj_t obj, void *data, u_int32_t speed)
674 struct sc_pchinfo *ch = data;
681 emupchan_setblocksize(kobj_t obj, void *data, u_int32_t blocksize)
683 struct sc_pchinfo *ch = data;
684 struct sc_info *sc = ch->parent;
687 ch->blksz = blocksize;
688 snd_mtxlock(sc->lock);
690 irqrate = 48000 / sc->timerinterval;
691 snd_mtxunlock(sc->lock);
692 blksz = (ch->spd * sndbuf_getbps(ch->buffer)) / irqrate;
697 emupchan_trigger(kobj_t obj, void *data, int go)
699 struct sc_pchinfo *ch = data;
700 struct sc_info *sc = ch->parent;
702 if (go == PCMTRIG_EMLDMAWR || go == PCMTRIG_EMLDMARD)
705 snd_mtxlock(sc->lock);
706 if (go == PCMTRIG_START) {
708 emu_vwrite(sc, ch->master);
712 printf("start [%d bit, %s, %d hz]\n",
713 ch->master->b16? 16 : 8,
714 ch->master->stereo? "stereo" : "mono",
716 emu_vdump(sc, ch->master);
717 emu_vdump(sc, ch->slave);
720 ch->run = (go == PCMTRIG_START)? 1 : 0;
721 emu_vtrigger(sc, ch->master, ch->run);
722 snd_mtxunlock(sc->lock);
727 emupchan_getptr(kobj_t obj, void *data)
729 struct sc_pchinfo *ch = data;
730 struct sc_info *sc = ch->parent;
733 snd_mtxlock(sc->lock);
734 r = emu_vpos(sc, ch->master);
735 snd_mtxunlock(sc->lock);
740 static struct pcmchan_caps *
741 emupchan_getcaps(kobj_t obj, void *data)
743 return &emu_playcaps;
746 static kobj_method_t emupchan_methods[] = {
747 KOBJMETHOD(channel_init, emupchan_init),
748 KOBJMETHOD(channel_free, emupchan_free),
749 KOBJMETHOD(channel_setformat, emupchan_setformat),
750 KOBJMETHOD(channel_setspeed, emupchan_setspeed),
751 KOBJMETHOD(channel_setblocksize, emupchan_setblocksize),
752 KOBJMETHOD(channel_trigger, emupchan_trigger),
753 KOBJMETHOD(channel_getptr, emupchan_getptr),
754 KOBJMETHOD(channel_getcaps, emupchan_getcaps),
757 CHANNEL_DECLARE(emupchan);
759 /* channel interface */
761 emurchan_init(kobj_t obj, void *devinfo, struct snd_dbuf *b, struct pcm_channel *c, int dir)
763 struct sc_info *sc = devinfo;
764 struct sc_rchinfo *ch;
766 KASSERT(dir == PCMDIR_REC, ("emurchan_init: bad direction"));
767 ch = &sc->rch[sc->rnum];
771 ch->blksz = sc->bufsz / 2;
780 ch->setupreg = ADCCR;
781 ch->irqmask = INTE_ADCBUFENABLE;
789 ch->irqmask = INTE_EFXBUFENABLE;
797 ch->irqmask = INTE_MICBUFENABLE;
801 if (sndbuf_alloc(ch->buffer, sc->parent_dmat, sc->bufsz) == -1)
804 snd_mtxlock(sc->lock);
805 emu_wrptr(sc, 0, ch->basereg, vtophys(sndbuf_getbuf(ch->buffer)));
806 emu_wrptr(sc, 0, ch->sizereg, 0); /* off */
807 snd_mtxunlock(sc->lock);
813 emurchan_setformat(kobj_t obj, void *data, u_int32_t format)
815 struct sc_rchinfo *ch = data;
822 emurchan_setspeed(kobj_t obj, void *data, u_int32_t speed)
824 struct sc_rchinfo *ch = data;
827 speed = adcspeed[emu_recval(speed)];
837 emurchan_setblocksize(kobj_t obj, void *data, u_int32_t blocksize)
839 struct sc_rchinfo *ch = data;
840 struct sc_info *sc = ch->parent;
843 ch->blksz = blocksize;
844 snd_mtxlock(sc->lock);
846 irqrate = 48000 / sc->timerinterval;
847 snd_mtxunlock(sc->lock);
848 blksz = (ch->spd * sndbuf_getbps(ch->buffer)) / irqrate;
852 /* semantic note: must start at beginning of buffer */
854 emurchan_trigger(kobj_t obj, void *data, int go)
856 struct sc_rchinfo *ch = data;
857 struct sc_info *sc = ch->parent;
862 sz = ADCBS_BUFSIZE_4096;
866 sz = ADCBS_BUFSIZE_8192;
870 sz = ADCBS_BUFSIZE_16384;
874 sz = ADCBS_BUFSIZE_32768;
878 sz = ADCBS_BUFSIZE_65536;
882 sz = ADCBS_BUFSIZE_4096;
885 snd_mtxlock(sc->lock);
889 emu_wrptr(sc, 0, ch->sizereg, sz);
891 val = ADCCR_LCHANENABLE;
892 if (ch->fmt & AFMT_STEREO)
893 val |= ADCCR_RCHANENABLE;
894 val |= emu_recval(ch->spd);
895 emu_wrptr(sc, 0, ch->setupreg, 0);
896 emu_wrptr(sc, 0, ch->setupreg, val);
898 val = emu_rd(sc, INTE, 4);
900 emu_wr(sc, INTE, val, 4);
906 emu_wrptr(sc, 0, ch->sizereg, 0);
908 emu_wrptr(sc, 0, ch->setupreg, 0);
909 val = emu_rd(sc, INTE, 4);
911 emu_wr(sc, INTE, val, 4);
914 case PCMTRIG_EMLDMAWR:
915 case PCMTRIG_EMLDMARD:
919 snd_mtxunlock(sc->lock);
925 emurchan_getptr(kobj_t obj, void *data)
927 struct sc_rchinfo *ch = data;
928 struct sc_info *sc = ch->parent;
931 snd_mtxlock(sc->lock);
932 r = emu_rdptr(sc, 0, ch->idxreg) & 0x0000ffff;
933 snd_mtxunlock(sc->lock);
938 static struct pcmchan_caps *
939 emurchan_getcaps(kobj_t obj, void *data)
941 struct sc_rchinfo *ch = data;
943 return &emu_reccaps[ch->num];
946 static kobj_method_t emurchan_methods[] = {
947 KOBJMETHOD(channel_init, emurchan_init),
948 KOBJMETHOD(channel_setformat, emurchan_setformat),
949 KOBJMETHOD(channel_setspeed, emurchan_setspeed),
950 KOBJMETHOD(channel_setblocksize, emurchan_setblocksize),
951 KOBJMETHOD(channel_trigger, emurchan_trigger),
952 KOBJMETHOD(channel_getptr, emurchan_getptr),
953 KOBJMETHOD(channel_getcaps, emurchan_getcaps),
956 CHANNEL_DECLARE(emurchan);
958 /* -------------------------------------------------------------------- */
959 /* The interrupt handler */
963 struct sc_info *sc = (struct sc_info *)p;
964 u_int32_t stat, ack, i, x;
967 stat = emu_rd(sc, IPR, 4);
973 if (stat & IPR_INTERVALTIMER) {
974 ack |= IPR_INTERVALTIMER;
976 for (i = 0; i < EMU_CHANS; i++) {
977 if (sc->pch[i].run) {
979 chn_intr(sc->pch[i].channel);
987 if (stat & (IPR_ADCBUFFULL | IPR_ADCBUFHALFFULL)) {
988 ack |= stat & (IPR_ADCBUFFULL | IPR_ADCBUFHALFFULL);
989 if (sc->rch[0].channel)
990 chn_intr(sc->rch[0].channel);
992 if (stat & (IPR_EFXBUFFULL | IPR_EFXBUFHALFFULL)) {
993 ack |= stat & (IPR_EFXBUFFULL | IPR_EFXBUFHALFFULL);
994 if (sc->rch[1].channel)
995 chn_intr(sc->rch[1].channel);
997 if (stat & (IPR_MICBUFFULL | IPR_MICBUFHALFFULL)) {
998 ack |= stat & (IPR_MICBUFFULL | IPR_MICBUFHALFFULL);
999 if (sc->rch[2].channel)
1000 chn_intr(sc->rch[2].channel);
1002 if (stat & IPR_PCIERROR) {
1003 ack |= IPR_PCIERROR;
1004 device_printf(sc->dev, "pci error\n");
1005 /* we still get an nmi with ecc ram even if we ack this */
1007 if (stat & IPR_SAMPLERATETRACKER) {
1008 ack |= IPR_SAMPLERATETRACKER;
1009 /* device_printf(sc->dev, "sample rate tracker lock status change\n"); */
1013 device_printf(sc->dev, "dodgy irq: %x (harmless)\n", stat & ~ack);
1015 emu_wr(sc, IPR, stat, 4);
1019 /* -------------------------------------------------------------------- */
1022 emu_setmap(void *arg, bus_dma_segment_t *segs, int nseg, int error)
1026 *phys = error? 0 : (void *)segs->ds_addr;
1029 printf("emu: setmap (%lx, %lx), nseg=%d, error=%d\n",
1030 (unsigned long)segs->ds_addr, (unsigned long)segs->ds_len,
1036 emu_malloc(struct sc_info *sc, u_int32_t sz)
1038 void *buf, *phys = 0;
1041 if (bus_dmamem_alloc(sc->parent_dmat, &buf, BUS_DMA_NOWAIT, &map))
1043 if (bus_dmamap_load(sc->parent_dmat, map, buf, sz, emu_setmap, &phys, 0)
1050 emu_free(struct sc_info *sc, void *buf)
1052 bus_dmamem_free(sc->parent_dmat, buf, NULL);
1056 emu_memalloc(struct sc_info *sc, u_int32_t sz)
1058 u_int32_t blksz, start, idx, ofs, tmp, found;
1059 struct emu_mem *mem = &sc->mem;
1060 struct emu_memblk *blk;
1063 blksz = sz / EMUPAGESIZE;
1064 if (sz > (blksz * EMUPAGESIZE))
1066 /* find a free block in the bitmap */
1069 while (!found && start + blksz < MAXPAGES) {
1071 for (idx = start; idx < start + blksz; idx++)
1072 if (mem->bmap[idx >> 3] & (1 << (idx & 7)))
1079 blk = malloc(sizeof(*blk), M_DEVBUF, M_NOWAIT);
1082 buf = emu_malloc(sc, sz);
1084 free(blk, M_DEVBUF);
1088 blk->pte_start = start;
1089 blk->pte_size = blksz;
1090 /* printf("buf %p, pte_start %d, pte_size %d\n", blk->buf, blk->pte_start, blk->pte_size); */
1092 for (idx = start; idx < start + blksz; idx++) {
1093 mem->bmap[idx >> 3] |= 1 << (idx & 7);
1094 tmp = (u_int32_t)vtophys((u_int8_t *)buf + ofs);
1095 /* printf("pte[%d] -> %x phys, %x virt\n", idx, tmp, ((u_int32_t)buf) + ofs); */
1096 mem->ptb_pages[idx] = (tmp << 1) | idx;
1099 SLIST_INSERT_HEAD(&mem->blocks, blk, link);
1104 emu_memfree(struct sc_info *sc, void *buf)
1107 struct emu_mem *mem = &sc->mem;
1108 struct emu_memblk *blk, *i;
1111 SLIST_FOREACH(i, &mem->blocks, link) {
1117 SLIST_REMOVE(&mem->blocks, blk, emu_memblk, link);
1119 tmp = (u_int32_t)vtophys(sc->mem.silent_page) << 1;
1120 for (idx = blk->pte_start; idx < blk->pte_start + blk->pte_size; idx++) {
1121 mem->bmap[idx >> 3] &= ~(1 << (idx & 7));
1122 mem->ptb_pages[idx] = tmp | idx;
1124 free(blk, M_DEVBUF);
1129 emu_memstart(struct sc_info *sc, void *buf)
1131 struct emu_mem *mem = &sc->mem;
1132 struct emu_memblk *blk, *i;
1135 SLIST_FOREACH(i, &mem->blocks, link) {
1141 return blk->pte_start;
1145 emu_addefxop(struct sc_info *sc, int op, int z, int w, int x, int y, u_int32_t *pc)
1147 emu_wrefx(sc, (*pc) * 2, (x << 10) | y);
1148 emu_wrefx(sc, (*pc) * 2 + 1, (op << 20) | (z << 10) | w);
1153 emu_initefx(struct sc_info *sc)
1158 for (i = 0; i < 512; i++) {
1159 emu_wrefx(sc, i * 2, 0x10040);
1160 emu_wrefx(sc, i * 2 + 1, 0x610040);
1163 for (i = 0; i < 256; i++)
1164 emu_wrptr(sc, 0, FXGPREGBASE + i, 0);
1166 /* FX-8010 DSP Registers:
1168 0x000-0x00f : 16 registers
1170 0x010/0x011 : AC97 Codec (l/r)
1171 0x012/0x013 : ADC, S/PDIF (l/r)
1172 0x014/0x015 : Mic(left), Zoom (l/r)
1173 0x016/0x017 : APS S/PDIF?? (l/r)
1175 0x020/0x021 : AC97 Output (l/r)
1176 0x022/0x023 : TOS link out (l/r)
1177 0x024/0x025 : ??? (l/r)
1178 0x026/0x027 : LiveDrive Headphone (l/r)
1179 0x028/0x029 : Rear Channel (l/r)
1180 0x02a/0x02b : ADC Recording Buffer (l/r)
1182 0x040 - 0x044 = 0 - 4
1183 0x045 = 0x8, 0x046 = 0x10, 0x047 = 0x20
1184 0x048 = 0x100, 0x049 = 0x10000, 0x04a = 0x80000
1185 0x04b = 0x10000000, 0x04c = 0x20000000, 0x04d = 0x40000000
1186 0x04e = 0x80000000, 0x04f = 0x7fffffff
1189 0x058 : Noise source?
1190 0x059 : Noise source?
1191 General Purpose Registers
1193 Tank Memory Data Registers
1195 Tank Memory Address Registers
1200 0 : z := w + (x * y >> 31)
1205 /* Routing - this will be configurable in later version */
1207 /* GPR[0/1] = FX * 4 + SPDIF-in */
1208 emu_addefxop(sc, 4, 0x100, 0x12, 0, 0x44, &pc);
1209 emu_addefxop(sc, 4, 0x101, 0x13, 1, 0x44, &pc);
1210 /* GPR[0/1] += APS-input */
1211 emu_addefxop(sc, 6, 0x100, 0x100, 0x40, sc->APS ? 0x16 : 0x40, &pc);
1212 emu_addefxop(sc, 6, 0x101, 0x101, 0x40, sc->APS ? 0x17 : 0x40, &pc);
1213 /* FrontOut (AC97) = GPR[0/1] */
1214 emu_addefxop(sc, 6, 0x20, 0x40, 0x40, 0x100, &pc);
1215 emu_addefxop(sc, 6, 0x21, 0x40, 0x41, 0x101, &pc);
1216 /* RearOut = (GPR[0/1] * RearVolume) >> 31 */
1217 /* RearVolume = GRP[0x10/0x11] */
1218 emu_addefxop(sc, 0, 0x28, 0x40, 0x110, 0x100, &pc);
1219 emu_addefxop(sc, 0, 0x29, 0x40, 0x111, 0x101, &pc);
1220 /* TOS out = GPR[0/1] */
1221 emu_addefxop(sc, 6, 0x22, 0x40, 0x40, 0x100, &pc);
1222 emu_addefxop(sc, 6, 0x23, 0x40, 0x40, 0x101, &pc);
1224 emu_addefxop(sc, 6, 0x24, 0x40, 0x40, 0x40, &pc);
1225 emu_addefxop(sc, 6, 0x25, 0x40, 0x40, 0x40, &pc);
1227 emu_addefxop(sc, 6, 0x26, 0x40, 0x40, 0x40, &pc);
1228 emu_addefxop(sc, 6, 0x27, 0x40, 0x40, 0x40, &pc);
1229 /* Input0 (AC97) -> Record */
1230 emu_addefxop(sc, 6, 0x2a, 0x40, 0x40, 0x10, &pc);
1231 emu_addefxop(sc, 6, 0x2b, 0x40, 0x40, 0x11, &pc);
1233 emu_wrptr(sc, 0, DBG, 0);
1236 /* Probe and attach the card */
1238 emu_init(struct sc_info *sc)
1240 u_int32_t spcs, ch, tmp, i;
1242 /* disable audio and lock cache */
1243 emu_wr(sc, HCFG, HCFG_LOCKSOUNDCACHE | HCFG_LOCKTANKCACHE | HCFG_MUTEBUTTONENABLE, 4);
1245 /* reset recording buffers */
1246 emu_wrptr(sc, 0, MICBS, ADCBS_BUFSIZE_NONE);
1247 emu_wrptr(sc, 0, MICBA, 0);
1248 emu_wrptr(sc, 0, FXBS, ADCBS_BUFSIZE_NONE);
1249 emu_wrptr(sc, 0, FXBA, 0);
1250 emu_wrptr(sc, 0, ADCBS, ADCBS_BUFSIZE_NONE);
1251 emu_wrptr(sc, 0, ADCBA, 0);
1253 /* disable channel interrupt */
1254 emu_wr(sc, INTE, INTE_INTERVALTIMERENB | INTE_SAMPLERATETRACKER | INTE_PCIERRORENABLE, 4);
1255 emu_wrptr(sc, 0, CLIEL, 0);
1256 emu_wrptr(sc, 0, CLIEH, 0);
1257 emu_wrptr(sc, 0, SOLEL, 0);
1258 emu_wrptr(sc, 0, SOLEH, 0);
1260 /* init envelope engine */
1261 for (ch = 0; ch < NUM_G; ch++) {
1262 emu_wrptr(sc, ch, DCYSUSV, ENV_OFF);
1263 emu_wrptr(sc, ch, IP, 0);
1264 emu_wrptr(sc, ch, VTFT, 0xffff);
1265 emu_wrptr(sc, ch, CVCF, 0xffff);
1266 emu_wrptr(sc, ch, PTRX, 0);
1267 emu_wrptr(sc, ch, CPF, 0);
1268 emu_wrptr(sc, ch, CCR, 0);
1270 emu_wrptr(sc, ch, PSST, 0);
1271 emu_wrptr(sc, ch, DSL, 0x10);
1272 emu_wrptr(sc, ch, CCCA, 0);
1273 emu_wrptr(sc, ch, Z1, 0);
1274 emu_wrptr(sc, ch, Z2, 0);
1275 emu_wrptr(sc, ch, FXRT, 0xd01c0000);
1277 emu_wrptr(sc, ch, ATKHLDM, 0);
1278 emu_wrptr(sc, ch, DCYSUSM, 0);
1279 emu_wrptr(sc, ch, IFATN, 0xffff);
1280 emu_wrptr(sc, ch, PEFE, 0);
1281 emu_wrptr(sc, ch, FMMOD, 0);
1282 emu_wrptr(sc, ch, TREMFRQ, 24); /* 1 Hz */
1283 emu_wrptr(sc, ch, FM2FRQ2, 24); /* 1 Hz */
1284 emu_wrptr(sc, ch, TEMPENV, 0);
1286 /*** these are last so OFF prevents writing ***/
1287 emu_wrptr(sc, ch, LFOVAL2, 0);
1288 emu_wrptr(sc, ch, LFOVAL1, 0);
1289 emu_wrptr(sc, ch, ATKHLDV, 0);
1290 emu_wrptr(sc, ch, ENVVOL, 0);
1291 emu_wrptr(sc, ch, ENVVAL, 0);
1293 sc->voice[ch].vnum = ch;
1294 sc->voice[ch].slave = NULL;
1295 sc->voice[ch].busy = 0;
1296 sc->voice[ch].ismaster = 0;
1297 sc->voice[ch].running = 0;
1298 sc->voice[ch].b16 = 0;
1299 sc->voice[ch].stereo = 0;
1300 sc->voice[ch].speed = 0;
1301 sc->voice[ch].start = 0;
1302 sc->voice[ch].end = 0;
1303 sc->voice[ch].channel = NULL;
1305 sc->pnum = sc->rnum = 0;
1308 * Init to 0x02109204 :
1309 * Clock accuracy = 0 (1000ppm)
1310 * Sample Rate = 2 (48kHz)
1311 * Audio Channel = 1 (Left of 2)
1312 * Source Number = 0 (Unspecified)
1313 * Generation Status = 1 (Original for Cat Code 12)
1314 * Cat Code = 12 (Digital Signal Mixer)
1316 * Emphasis = 0 (None)
1317 * CP = 1 (Copyright unasserted)
1318 * AN = 0 (Audio data)
1321 spcs = SPCS_CLKACCY_1000PPM | SPCS_SAMPLERATE_48 |
1322 SPCS_CHANNELNUM_LEFT | SPCS_SOURCENUM_UNSPEC |
1323 SPCS_GENERATIONSTATUS | 0x00001200 | 0x00000000 |
1324 SPCS_EMPHASIS_NONE | SPCS_COPYRIGHT;
1325 emu_wrptr(sc, 0, SPCS0, spcs);
1326 emu_wrptr(sc, 0, SPCS1, spcs);
1327 emu_wrptr(sc, 0, SPCS2, spcs);
1331 SLIST_INIT(&sc->mem.blocks);
1332 sc->mem.ptb_pages = emu_malloc(sc, MAXPAGES * sizeof(u_int32_t));
1333 if (sc->mem.ptb_pages == NULL)
1336 sc->mem.silent_page = emu_malloc(sc, EMUPAGESIZE);
1337 if (sc->mem.silent_page == NULL) {
1338 emu_free(sc, sc->mem.ptb_pages);
1341 /* Clear page with silence & setup all pointers to this page */
1342 bzero(sc->mem.silent_page, EMUPAGESIZE);
1343 tmp = (u_int32_t)vtophys(sc->mem.silent_page) << 1;
1344 for (i = 0; i < MAXPAGES; i++)
1345 sc->mem.ptb_pages[i] = tmp | i;
1347 emu_wrptr(sc, 0, PTB, vtophys(sc->mem.ptb_pages));
1348 emu_wrptr(sc, 0, TCB, 0); /* taken from original driver */
1349 emu_wrptr(sc, 0, TCBS, 0); /* taken from original driver */
1351 for (ch = 0; ch < NUM_G; ch++) {
1352 emu_wrptr(sc, ch, MAPA, tmp | MAP_PTI_MASK);
1353 emu_wrptr(sc, ch, MAPB, tmp | MAP_PTI_MASK);
1356 /* emu_memalloc(sc, EMUPAGESIZE); */
1358 * Hokay, now enable the AUD bit
1360 * Mute Disable Audio = 0
1361 * Lock Tank Memory = 1
1362 * Lock Sound Memory = 0
1365 tmp = HCFG_AUDIOENABLE | HCFG_LOCKTANKCACHE | HCFG_AUTOMUTE;
1367 tmp |= HCFG_JOYENABLE;
1368 emu_wr(sc, HCFG, tmp, 4);
1370 /* TOSLink detection */
1372 tmp = emu_rd(sc, HCFG, 4);
1373 if (tmp & (HCFG_GPINPUT0 | HCFG_GPINPUT1)) {
1374 emu_wr(sc, HCFG, tmp | 0x800, 4);
1376 if (tmp != (emu_rd(sc, HCFG, 4) & ~0x800)) {
1378 emu_wr(sc, HCFG, tmp, 4);
1386 emu_uninit(struct sc_info *sc)
1390 emu_wr(sc, INTE, 0, 4);
1391 for (ch = 0; ch < NUM_G; ch++)
1392 emu_wrptr(sc, ch, DCYSUSV, ENV_OFF);
1393 for (ch = 0; ch < NUM_G; ch++) {
1394 emu_wrptr(sc, ch, VTFT, 0);
1395 emu_wrptr(sc, ch, CVCF, 0);
1396 emu_wrptr(sc, ch, PTRX, 0);
1397 emu_wrptr(sc, ch, CPF, 0);
1400 /* disable audio and lock cache */
1401 emu_wr(sc, HCFG, HCFG_LOCKSOUNDCACHE | HCFG_LOCKTANKCACHE | HCFG_MUTEBUTTONENABLE, 4);
1403 emu_wrptr(sc, 0, PTB, 0);
1404 /* reset recording buffers */
1405 emu_wrptr(sc, 0, MICBS, ADCBS_BUFSIZE_NONE);
1406 emu_wrptr(sc, 0, MICBA, 0);
1407 emu_wrptr(sc, 0, FXBS, ADCBS_BUFSIZE_NONE);
1408 emu_wrptr(sc, 0, FXBA, 0);
1409 emu_wrptr(sc, 0, FXWC, 0);
1410 emu_wrptr(sc, 0, ADCBS, ADCBS_BUFSIZE_NONE);
1411 emu_wrptr(sc, 0, ADCBA, 0);
1412 emu_wrptr(sc, 0, TCB, 0);
1413 emu_wrptr(sc, 0, TCBS, 0);
1415 /* disable channel interrupt */
1416 emu_wrptr(sc, 0, CLIEL, 0);
1417 emu_wrptr(sc, 0, CLIEH, 0);
1418 emu_wrptr(sc, 0, SOLEL, 0);
1419 emu_wrptr(sc, 0, SOLEH, 0);
1421 /* init envelope engine */
1422 if (!SLIST_EMPTY(&sc->mem.blocks))
1423 device_printf(sc->dev, "warning: memblock list not empty\n");
1424 emu_free(sc, sc->mem.ptb_pages);
1425 emu_free(sc, sc->mem.silent_page);
1431 emu_pci_probe(device_t dev)
1435 switch (pci_get_devid(dev)) {
1436 case EMU10K1_PCI_ID:
1437 s = "Creative EMU10K1";
1440 case EMU10K2_PCI_ID:
1441 s = "Creative EMU10K2";
1448 device_set_desc(dev, s);
1453 emu_pci_attach(device_t dev)
1455 struct ac97_info *codec = NULL;
1459 char status[SND_STATUSLEN];
1461 if ((sc = malloc(sizeof(*sc), M_DEVBUF, M_WAITOK | M_ZERO)) == NULL) {
1462 device_printf(dev, "cannot allocate softc\n");
1466 sc->lock = snd_mtxcreate(device_get_nameunit(dev), "sound softc");
1468 sc->type = pci_get_devid(dev);
1469 sc->rev = pci_get_revid(dev);
1471 data = pci_read_config(dev, PCIR_COMMAND, 2);
1472 data |= (PCIM_CMD_PORTEN | PCIM_CMD_BUSMASTEREN);
1473 pci_write_config(dev, PCIR_COMMAND, data, 2);
1474 data = pci_read_config(dev, PCIR_COMMAND, 2);
1477 sc->reg = bus_alloc_resource(dev, SYS_RES_IOPORT, &i, 0, ~0, 1, RF_ACTIVE);
1478 if (sc->reg == NULL) {
1479 device_printf(dev, "unable to map register space\n");
1482 sc->st = rman_get_bustag(sc->reg);
1483 sc->sh = rman_get_bushandle(sc->reg);
1485 sc->bufsz = pcm_getbuffersize(dev, 4096, EMU_DEFAULT_BUFSZ, 65536);
1487 if (bus_dma_tag_create(/*parent*/NULL, /*alignment*/2, /*boundary*/0,
1488 /*lowaddr*/1 << 31, /* can only access 0-2gb */
1489 /*highaddr*/BUS_SPACE_MAXADDR,
1490 /*filter*/NULL, /*filterarg*/NULL,
1491 /*maxsize*/sc->bufsz, /*nsegments*/1, /*maxsegz*/0x3ffff,
1492 /*flags*/0, &sc->parent_dmat) != 0) {
1493 device_printf(dev, "unable to create dma tag\n");
1497 if (emu_init(sc) == -1) {
1498 device_printf(dev, "unable to initialize the card\n");
1502 codec = AC97_CREATE(dev, sc, emu_ac97);
1503 if (codec == NULL) goto bad;
1504 gotmic = (ac97_getcaps(codec) & AC97_CAP_MICCHANNEL)? 1 : 0;
1505 if (mixer_init(dev, ac97_getmixerclass(), codec) == -1) goto bad;
1508 sc->irq = bus_alloc_resource(dev, SYS_RES_IRQ, &i, 0, ~0, 1, RF_ACTIVE | RF_SHAREABLE);
1509 if (!sc->irq || snd_setup_intr(dev, sc->irq, INTR_MPSAFE, emu_intr, sc, &sc->ih)) {
1510 device_printf(dev, "unable to map interrupt\n");
1514 snprintf(status, SND_STATUSLEN, "at io 0x%lx irq %ld", rman_get_start(sc->reg), rman_get_start(sc->irq));
1516 if (pcm_register(dev, sc, EMU_CHANS, gotmic? 3 : 2)) goto bad;
1517 for (i = 0; i < EMU_CHANS; i++)
1518 pcm_addchan(dev, PCMDIR_PLAY, &emupchan_class, sc);
1519 for (i = 0; i < (gotmic? 3 : 2); i++)
1520 pcm_addchan(dev, PCMDIR_REC, &emurchan_class, sc);
1522 pcm_setstatus(dev, status);
1527 if (codec) ac97_destroy(codec);
1528 if (sc->reg) bus_release_resource(dev, SYS_RES_IOPORT, PCIR_MAPS, sc->reg);
1529 if (sc->ih) bus_teardown_intr(dev, sc->irq, sc->ih);
1530 if (sc->irq) bus_release_resource(dev, SYS_RES_IRQ, 0, sc->irq);
1531 if (sc->parent_dmat) bus_dma_tag_destroy(sc->parent_dmat);
1532 if (sc->lock) snd_mtxfree(sc->lock);
1538 emu_pci_detach(device_t dev)
1543 r = pcm_unregister(dev);
1547 sc = pcm_getdevinfo(dev);
1551 bus_release_resource(dev, SYS_RES_IOPORT, PCIR_MAPS, sc->reg);
1552 bus_teardown_intr(dev, sc->irq, sc->ih);
1553 bus_release_resource(dev, SYS_RES_IRQ, 0, sc->irq);
1554 bus_dma_tag_destroy(sc->parent_dmat);
1555 snd_mtxfree(sc->lock);
1561 /* add suspend, resume */
1562 static device_method_t emu_methods[] = {
1563 /* Device interface */
1564 DEVMETHOD(device_probe, emu_pci_probe),
1565 DEVMETHOD(device_attach, emu_pci_attach),
1566 DEVMETHOD(device_detach, emu_pci_detach),
1571 static driver_t emu_driver = {
1577 DRIVER_MODULE(snd_emu10k1, pci, emu_driver, pcm_devclass, 0, 0);
1578 MODULE_DEPEND(snd_emu10k1, snd_pcm, PCM_MINVER, PCM_PREFVER, PCM_MAXVER);
1579 MODULE_VERSION(snd_emu10k1, 1);
1581 /* dummy driver to silence the joystick device */
1583 emujoy_pci_probe(device_t dev)
1587 switch (pci_get_devid(dev)) {
1589 s = "Creative EMU10K1 Joystick";
1593 s = "Creative EMU10K2 Joystick";
1598 if (s) device_set_desc(dev, s);
1599 return s? -1000 : ENXIO;
1603 emujoy_pci_attach(device_t dev)
1609 emujoy_pci_detach(device_t dev)
1614 static device_method_t emujoy_methods[] = {
1615 DEVMETHOD(device_probe, emujoy_pci_probe),
1616 DEVMETHOD(device_attach, emujoy_pci_attach),
1617 DEVMETHOD(device_detach, emujoy_pci_detach),
1622 static driver_t emujoy_driver = {
1628 static devclass_t emujoy_devclass;
1630 DRIVER_MODULE(emujoy, pci, emujoy_driver, emujoy_devclass, 0, 0);