Deleted Added
sdiff udiff text old ( 111556 ) new ( 113653 )
full compact
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 THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 */
26
27#include <dev/sound/pcm/sound.h>
28#include <dev/sound/pcm/ac97.h>
29#include <gnu/dev/sound/pci/emu10k1.h>
30
31#include <pci/pcireg.h>
32#include <pci/pcivar.h>
33#include <sys/queue.h>
34
35SND_DECLARE_FILE("$FreeBSD: head/sys/dev/sound/pci/emu10k1.c 111556 2003-02-26 16:11:18Z cognet $");
36
37/* -------------------------------------------------------------------- */
38
39#define EMU10K1_PCI_ID 0x00021102
40#define EMU10K2_PCI_ID 0x00041102
41#define EMU_DEFAULT_BUFSZ 4096
42#define EMU_CHANS 4
43#undef EMUDEBUG
44
45struct emu_memblk {
46 SLIST_ENTRY(emu_memblk) link;
47 void *buf;
48 bus_addr_t buf_addr;
49 u_int32_t pte_start, pte_size;
50};
51
52struct emu_mem {
53 u_int8_t bmap[MAXPAGES / 8];
54 u_int32_t *ptb_pages;
55 void *silent_page;
56 bus_addr_t silent_page_addr;
57 bus_addr_t ptb_pages_addr;
58 SLIST_HEAD(, emu_memblk) blocks;
59};
60
61struct emu_voice {
62 int vnum;
63 int b16:1, stereo:1, busy:1, running:1, ismaster:1;
64 int speed;
65 int start, end, vol;
66 u_int32_t buf;
67 struct emu_voice *slave;
68 struct pcm_channel *channel;
69};
70
71struct sc_info;
72
73/* channel registers */
74struct sc_pchinfo {
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;
80};
81
82struct sc_rchinfo {
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;
88};
89
90/* device private data */
91struct sc_info {
92 device_t dev;
93 u_int32_t type, rev;
94 u_int32_t tos_link:1, APS:1;
95
96 bus_space_tag_t st;
97 bus_space_handle_t sh;
98 bus_dma_tag_t parent_dmat;
99
100 struct resource *reg, *irq;
101 void *ih;
102 struct mtx *lock;
103
104 unsigned int bufsz;
105 int timer, timerinterval;
106 int pnum, rnum;
107 struct emu_mem mem;
108 struct emu_voice voice[64];
109 struct sc_pchinfo pch[EMU_CHANS];
110 struct sc_rchinfo rch[3];
111};
112
113/* -------------------------------------------------------------------- */
114
115/*
116 * prototypes
117 */
118
119/* stuff */
120static int emu_init(struct sc_info *);
121static void emu_intr(void *);
122static void *emu_malloc(struct sc_info *sc, u_int32_t sz, bus_addr_t *addr);
123static void *emu_memalloc(struct sc_info *sc, u_int32_t sz, bus_addr_t *addr);
124static int emu_memfree(struct sc_info *sc, void *buf);
125static int emu_memstart(struct sc_info *sc, void *buf);
126#ifdef EMUDEBUG
127static void emu_vdump(struct sc_info *sc, struct emu_voice *v);
128#endif
129
130/* talk to the card */
131static u_int32_t emu_rd(struct sc_info *, int, int);
132static void emu_wr(struct sc_info *, int, u_int32_t, int);
133
134/* -------------------------------------------------------------------- */
135
136static u_int32_t emu_rfmt_ac97[] = {
137 AFMT_S16_LE,
138 AFMT_STEREO | AFMT_S16_LE,
139 0
140};
141
142static u_int32_t emu_rfmt_mic[] = {
143 AFMT_U8,
144 0
145};
146
147static u_int32_t emu_rfmt_efx[] = {
148 AFMT_STEREO | AFMT_S16_LE,
149 0
150};
151
152static 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},
156};
157
158static u_int32_t emu_pfmt[] = {
159 AFMT_U8,
160 AFMT_STEREO | AFMT_U8,
161 AFMT_S16_LE,
162 AFMT_STEREO | AFMT_S16_LE,
163 0
164};
165
166static struct pcmchan_caps emu_playcaps = {4000, 48000, emu_pfmt, 0};
167
168static int adcspeed[8] = {48000, 44100, 32000, 24000, 22050, 16000, 11025, 8000};
169
170/* -------------------------------------------------------------------- */
171/* Hardware */
172static u_int32_t
173emu_rd(struct sc_info *sc, int regno, int size)
174{
175 switch (size) {
176 case 1:
177 return bus_space_read_1(sc->st, sc->sh, regno);
178 case 2:
179 return bus_space_read_2(sc->st, sc->sh, regno);
180 case 4:
181 return bus_space_read_4(sc->st, sc->sh, regno);
182 default:
183 return 0xffffffff;
184 }
185}
186
187static void
188emu_wr(struct sc_info *sc, int regno, u_int32_t data, int size)
189{
190 switch (size) {
191 case 1:
192 bus_space_write_1(sc->st, sc->sh, regno, data);
193 break;
194 case 2:
195 bus_space_write_2(sc->st, sc->sh, regno, data);
196 break;
197 case 4:
198 bus_space_write_4(sc->st, sc->sh, regno, data);
199 break;
200 }
201}
202
203static u_int32_t
204emu_rdptr(struct sc_info *sc, int chn, int reg)
205{
206 u_int32_t ptr, val, mask, size, offset;
207
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;
215 val &= mask;
216 val >>= offset;
217 }
218 return val;
219}
220
221static void
222emu_wrptr(struct sc_info *sc, int chn, int reg, u_int32_t data)
223{
224 u_int32_t ptr, mask, size, offset;
225
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;
232 data <<= offset;
233 data &= mask;
234 data |= emu_rd(sc, DATA, 4) & ~mask;
235 }
236 emu_wr(sc, DATA, data, 4);
237}
238
239static void
240emu_wrefx(struct sc_info *sc, unsigned int pc, unsigned int data)
241{
242 emu_wrptr(sc, 0, MICROCODEBASE + pc, data);
243}
244
245/* -------------------------------------------------------------------- */
246/* ac97 codec */
247/* no locking needed */
248
249static int
250emu_rdcd(kobj_t obj, void *devinfo, int regno)
251{
252 struct sc_info *sc = (struct sc_info *)devinfo;
253
254 emu_wr(sc, AC97ADDRESS, regno, 1);
255 return emu_rd(sc, AC97DATA, 2);
256}
257
258static int
259emu_wrcd(kobj_t obj, void *devinfo, int regno, u_int32_t data)
260{
261 struct sc_info *sc = (struct sc_info *)devinfo;
262
263 emu_wr(sc, AC97ADDRESS, regno, 1);
264 emu_wr(sc, AC97DATA, data, 2);
265 return 0;
266}
267
268static kobj_method_t emu_ac97_methods[] = {
269 KOBJMETHOD(ac97_read, emu_rdcd),
270 KOBJMETHOD(ac97_write, emu_wrcd),
271 { 0, 0 }
272};
273AC97_DECLARE(emu_ac97);
274
275/* -------------------------------------------------------------------- */
276/* stuff */
277static int
278emu_settimer(struct sc_info *sc)
279{
280 struct sc_pchinfo *pch;
281 struct sc_rchinfo *rch;
282 int i, tmp, rate;
283
284 rate = 0;
285 for (i = 0; i < EMU_CHANS; i++) {
286 pch = &sc->pch[i];
287 if (pch->buffer) {
288 tmp = (pch->spd * sndbuf_getbps(pch->buffer)) / pch->blksz;
289 if (tmp > rate)
290 rate = tmp;
291 }
292 }
293
294 for (i = 0; i < 3; i++) {
295 rch = &sc->rch[i];
296 if (rch->buffer) {
297 tmp = (rch->spd * sndbuf_getbps(rch->buffer)) / rch->blksz;
298 if (tmp > rate)
299 rate = tmp;
300 }
301 }
302 RANGE(rate, 48, 9600);
303 sc->timerinterval = 48000 / rate;
304 emu_wr(sc, TIMER, sc->timerinterval & 0x03ff, 2);
305
306 return sc->timerinterval;
307}
308
309static int
310emu_enatimer(struct sc_info *sc, int go)
311{
312 u_int32_t x;
313 if (go) {
314 if (sc->timer++ == 0) {
315 x = emu_rd(sc, INTE, 4);
316 x |= INTE_INTERVALTIMERENB;
317 emu_wr(sc, INTE, x, 4);
318 }
319 } else {
320 sc->timer = 0;
321 x = emu_rd(sc, INTE, 4);
322 x &= ~INTE_INTERVALTIMERENB;
323 emu_wr(sc, INTE, x, 4);
324 }
325 return 0;
326}
327
328static void
329emu_enastop(struct sc_info *sc, char channel, int enable)
330{
331 int reg = (channel & 0x20)? SOLEH : SOLEL;
332 channel &= 0x1f;
333 reg |= 1 << 24;
334 reg |= channel << 16;
335 emu_wrptr(sc, 0, reg, enable);
336}
337
338static int
339emu_recval(int speed) {
340 int val;
341
342 val = 0;
343 while (val < 7 && speed < adcspeed[val])
344 val++;
345 return val;
346}
347
348static u_int32_t
349emu_rate_to_pitch(u_int32_t rate)
350{
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
368 };
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
386 };
387 int i;
388
389 if (rate == 0)
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)]);
398 }
399 rate <<= 1;
400 }
401
402 return 0; /* Should never reach this point */
403}
404
405static u_int32_t
406emu_rate_to_linearpitch(u_int32_t rate)
407{
408 rate = (rate << 8) / 375;
409 return (rate >> 1) + (rate & 1);
410}
411
412static struct emu_voice *
413emu_valloc(struct sc_info *sc)
414{
415 struct emu_voice *v;
416 int i;
417
418 v = NULL;
419 for (i = 0; i < 64 && sc->voice[i].busy; i++);
420 if (i < 64) {
421 v = &sc->voice[i];
422 v->busy = 1;
423 }
424 return v;
425}
426
427static int
428emu_vinit(struct sc_info *sc, struct emu_voice *m, struct emu_voice *s,
429 u_int32_t sz, struct snd_dbuf *b)
430{
431 void *buf;
432 bus_addr_t tmp_addr;
433
434 buf = emu_memalloc(sc, sz, &tmp_addr);
435 if (buf == NULL)
436 return -1;
437 if (b != NULL)
438 sndbuf_setup(b, buf, sz);
439 m->start = emu_memstart(sc, buf) * EMUPAGESIZE;
440 m->end = m->start + sz;
441 m->channel = NULL;
442 m->speed = 0;
443 m->b16 = 0;
444 m->stereo = 0;
445 m->running = 0;
446 m->ismaster = 1;
447 m->vol = 0xff;
448 m->buf = tmp_addr;
449 m->slave = s;
450 if (s != NULL) {
451 s->start = m->start;
452 s->end = m->end;
453 s->channel = NULL;
454 s->speed = 0;
455 s->b16 = 0;
456 s->stereo = 0;
457 s->running = 0;
458 s->ismaster = 0;
459 s->vol = m->vol;
460 s->buf = m->buf;
461 s->slave = NULL;
462 }
463 return 0;
464}
465
466static void
467emu_vsetup(struct sc_pchinfo *ch)
468{
469 struct emu_voice *v = ch->master;
470
471 if (ch->fmt) {
472 v->b16 = (ch->fmt & AFMT_16BIT)? 1 : 0;
473 v->stereo = (ch->fmt & AFMT_STEREO)? 1 : 0;
474 if (v->slave != NULL) {
475 v->slave->b16 = v->b16;
476 v->slave->stereo = v->stereo;
477 }
478 }
479 if (ch->spd) {
480 v->speed = ch->spd;
481 if (v->slave != NULL)
482 v->slave->speed = v->speed;
483 }
484}
485
486static void
487emu_vwrite(struct sc_info *sc, struct emu_voice *v)
488{
489 int s;
490 int l, r, x, y;
491 u_int32_t sa, ea, start, val, silent_page;
492
493 s = (v->stereo? 1 : 0) + (v->b16? 1 : 0);
494
495 sa = v->start >> s;
496 ea = v->end >> s;
497
498 l = r = x = y = v->vol;
499 if (v->stereo) {
500 l = v->ismaster? l : 0;
501 r = v->ismaster? 0 : r;
502 }
503
504 emu_wrptr(sc, v->vnum, CPF, v->stereo? CPF_STEREO_MASK : 0);
505 val = v->stereo? 28 : 30;
506 val *= v->b16? 1 : 2;
507 start = sa + val;
508
509 emu_wrptr(sc, v->vnum, FXRT, 0xd01c0000);
510
511 emu_wrptr(sc, v->vnum, PTRX, (x << 8) | r);
512 emu_wrptr(sc, v->vnum, DSL, ea | (y << 24));
513 emu_wrptr(sc, v->vnum, PSST, sa | (l << 24));
514 emu_wrptr(sc, v->vnum, CCCA, start | (v->b16? 0 : CCCA_8BITSELECT));
515
516 emu_wrptr(sc, v->vnum, Z1, 0);
517 emu_wrptr(sc, v->vnum, Z2, 0);
518
519 silent_page = ((u_int32_t)(sc->mem.silent_page_addr) << 1) | MAP_PTI_MASK;
520 emu_wrptr(sc, v->vnum, MAPA, silent_page);
521 emu_wrptr(sc, v->vnum, MAPB, silent_page);
522
523 emu_wrptr(sc, v->vnum, CVCF, CVCF_CURRENTFILTER_MASK);
524 emu_wrptr(sc, v->vnum, VTFT, VTFT_FILTERTARGET_MASK);
525 emu_wrptr(sc, v->vnum, ATKHLDM, 0);
526 emu_wrptr(sc, v->vnum, DCYSUSM, DCYSUSM_DECAYTIME_MASK);
527 emu_wrptr(sc, v->vnum, LFOVAL1, 0x8000);
528 emu_wrptr(sc, v->vnum, LFOVAL2, 0x8000);
529 emu_wrptr(sc, v->vnum, FMMOD, 0);
530 emu_wrptr(sc, v->vnum, TREMFRQ, 0);
531 emu_wrptr(sc, v->vnum, FM2FRQ2, 0);
532 emu_wrptr(sc, v->vnum, ENVVAL, 0x8000);
533
534 emu_wrptr(sc, v->vnum, ATKHLDV, ATKHLDV_HOLDTIME_MASK | ATKHLDV_ATTACKTIME_MASK);
535 emu_wrptr(sc, v->vnum, ENVVOL, 0x8000);
536
537 emu_wrptr(sc, v->vnum, PEFE_FILTERAMOUNT, 0x7f);
538 emu_wrptr(sc, v->vnum, PEFE_PITCHAMOUNT, 0);
539
540 if (v->slave != NULL)
541 emu_vwrite(sc, v->slave);
542}
543
544static void
545emu_vtrigger(struct sc_info *sc, struct emu_voice *v, int go)
546{
547 u_int32_t pitch_target, initial_pitch;
548 u_int32_t cra, cs, ccis;
549 u_int32_t sample, i;
550
551 if (go) {
552 cra = 64;
553 cs = v->stereo? 4 : 2;
554 ccis = v->stereo? 28 : 30;
555 ccis *= v->b16? 1 : 2;
556 sample = v->b16? 0x00000000 : 0x80808080;
557
558 for (i = 0; i < cs; i++)
559 emu_wrptr(sc, v->vnum, CD0 + i, sample);
560 emu_wrptr(sc, v->vnum, CCR_CACHEINVALIDSIZE, 0);
561 emu_wrptr(sc, v->vnum, CCR_READADDRESS, cra);
562 emu_wrptr(sc, v->vnum, CCR_CACHEINVALIDSIZE, ccis);
563
564 emu_wrptr(sc, v->vnum, IFATN, 0xff00);
565 emu_wrptr(sc, v->vnum, VTFT, 0xffffffff);
566 emu_wrptr(sc, v->vnum, CVCF, 0xffffffff);
567 emu_wrptr(sc, v->vnum, DCYSUSV, 0x00007f7f);
568 emu_enastop(sc, v->vnum, 0);
569
570 pitch_target = emu_rate_to_linearpitch(v->speed);
571 initial_pitch = emu_rate_to_pitch(v->speed) >> 8;
572 emu_wrptr(sc, v->vnum, PTRX_PITCHTARGET, pitch_target);
573 emu_wrptr(sc, v->vnum, CPF_CURRENTPITCH, pitch_target);
574 emu_wrptr(sc, v->vnum, IP, initial_pitch);
575 } else {
576 emu_wrptr(sc, v->vnum, PTRX_PITCHTARGET, 0);
577 emu_wrptr(sc, v->vnum, CPF_CURRENTPITCH, 0);
578 emu_wrptr(sc, v->vnum, IFATN, 0xffff);
579 emu_wrptr(sc, v->vnum, VTFT, 0x0000ffff);
580 emu_wrptr(sc, v->vnum, CVCF, 0x0000ffff);
581 emu_wrptr(sc, v->vnum, IP, 0);
582 emu_enastop(sc, v->vnum, 1);
583 }
584 if (v->slave != NULL)
585 emu_vtrigger(sc, v->slave, go);
586}
587
588static int
589emu_vpos(struct sc_info *sc, struct emu_voice *v)
590{
591 int s, ptr;
592
593 s = (v->b16? 1 : 0) + (v->stereo? 1 : 0);
594 ptr = (emu_rdptr(sc, v->vnum, CCCA_CURRADDR) - (v->start >> s)) << s;
595 return ptr & ~0x0000001f;
596}
597
598#ifdef EMUDEBUG
599static void
600emu_vdump(struct sc_info *sc, struct emu_voice *v)
601{
602 char *regname[] = { "cpf", "ptrx", "cvcf", "vtft", "z2", "z1", "psst", "dsl",
603 "ccca", "ccr", "clp", "fxrt", "mapa", "mapb", NULL, NULL,
604 "envvol", "atkhldv", "dcysusv", "lfoval1",
605 "envval", "atkhldm", "dcysusm", "lfoval2",
606 "ip", "ifatn", "pefe", "fmmod", "tremfrq", "fmfrq2",
607 "tempenv" };
608 int i, x;
609
610 printf("voice number %d\n", v->vnum);
611 for (i = 0, x = 0; i <= 0x1e; i++) {
612 if (regname[i] == NULL)
613 continue;
614 printf("%s\t[%08x]", regname[i], emu_rdptr(sc, v->vnum, i));
615 printf("%s", (x == 2)? "\n" : "\t");
616 x++;
617 if (x > 2)
618 x = 0;
619 }
620 printf("\n\n");
621}
622#endif
623
624/* channel interface */
625static void *
626emupchan_init(kobj_t obj, void *devinfo, struct snd_dbuf *b, struct pcm_channel *c, int dir)
627{
628 struct sc_info *sc = devinfo;
629 struct sc_pchinfo *ch;
630 void *r;
631
632 KASSERT(dir == PCMDIR_PLAY, ("emupchan_init: bad direction"));
633 ch = &sc->pch[sc->pnum++];
634 ch->buffer = b;
635 ch->parent = sc;
636 ch->channel = c;
637 ch->blksz = sc->bufsz / 2;
638 ch->fmt = AFMT_U8;
639 ch->spd = 8000;
640 snd_mtxlock(sc->lock);
641 ch->master = emu_valloc(sc);
642 ch->slave = emu_valloc(sc);
643 snd_mtxunlock(sc->lock);
644 r = (emu_vinit(sc, ch->master, ch->slave, sc->bufsz, ch->buffer))? NULL : ch;
645
646 return r;
647}
648
649static int
650emupchan_free(kobj_t obj, void *data)
651{
652 struct sc_pchinfo *ch = data;
653 struct sc_info *sc = ch->parent;
654 int r;
655
656 snd_mtxlock(sc->lock);
657 r = emu_memfree(sc, sndbuf_getbuf(ch->buffer));
658 snd_mtxunlock(sc->lock);
659
660 return r;
661}
662
663static int
664emupchan_setformat(kobj_t obj, void *data, u_int32_t format)
665{
666 struct sc_pchinfo *ch = data;
667
668 ch->fmt = format;
669 return 0;
670}
671
672static int
673emupchan_setspeed(kobj_t obj, void *data, u_int32_t speed)
674{
675 struct sc_pchinfo *ch = data;
676
677 ch->spd = speed;
678 return ch->spd;
679}
680
681static int
682emupchan_setblocksize(kobj_t obj, void *data, u_int32_t blocksize)
683{
684 struct sc_pchinfo *ch = data;
685 struct sc_info *sc = ch->parent;
686 int irqrate, blksz;
687
688 ch->blksz = blocksize;
689 snd_mtxlock(sc->lock);
690 emu_settimer(sc);
691 irqrate = 48000 / sc->timerinterval;
692 snd_mtxunlock(sc->lock);
693 blksz = (ch->spd * sndbuf_getbps(ch->buffer)) / irqrate;
694 return blocksize;
695}
696
697static int
698emupchan_trigger(kobj_t obj, void *data, int go)
699{
700 struct sc_pchinfo *ch = data;
701 struct sc_info *sc = ch->parent;
702
703 if (go == PCMTRIG_EMLDMAWR || go == PCMTRIG_EMLDMARD)
704 return 0;
705
706 snd_mtxlock(sc->lock);
707 if (go == PCMTRIG_START) {
708 emu_vsetup(ch);
709 emu_vwrite(sc, ch->master);
710 emu_settimer(sc);
711 emu_enatimer(sc, 1);
712#ifdef EMUDEBUG
713 printf("start [%d bit, %s, %d hz]\n",
714 ch->master->b16? 16 : 8,
715 ch->master->stereo? "stereo" : "mono",
716 ch->master->speed);
717 emu_vdump(sc, ch->master);
718 emu_vdump(sc, ch->slave);
719#endif
720 }
721 ch->run = (go == PCMTRIG_START)? 1 : 0;
722 emu_vtrigger(sc, ch->master, ch->run);
723 snd_mtxunlock(sc->lock);
724 return 0;
725}
726
727static int
728emupchan_getptr(kobj_t obj, void *data)
729{
730 struct sc_pchinfo *ch = data;
731 struct sc_info *sc = ch->parent;
732 int r;
733
734 snd_mtxlock(sc->lock);
735 r = emu_vpos(sc, ch->master);
736 snd_mtxunlock(sc->lock);
737
738 return r;
739}
740
741static struct pcmchan_caps *
742emupchan_getcaps(kobj_t obj, void *data)
743{
744 return &emu_playcaps;
745}
746
747static kobj_method_t emupchan_methods[] = {
748 KOBJMETHOD(channel_init, emupchan_init),
749 KOBJMETHOD(channel_free, emupchan_free),
750 KOBJMETHOD(channel_setformat, emupchan_setformat),
751 KOBJMETHOD(channel_setspeed, emupchan_setspeed),
752 KOBJMETHOD(channel_setblocksize, emupchan_setblocksize),
753 KOBJMETHOD(channel_trigger, emupchan_trigger),
754 KOBJMETHOD(channel_getptr, emupchan_getptr),
755 KOBJMETHOD(channel_getcaps, emupchan_getcaps),
756 { 0, 0 }
757};
758CHANNEL_DECLARE(emupchan);
759
760/* channel interface */
761static void *
762emurchan_init(kobj_t obj, void *devinfo, struct snd_dbuf *b, struct pcm_channel *c, int dir)
763{
764 struct sc_info *sc = devinfo;
765 struct sc_rchinfo *ch;
766
767 KASSERT(dir == PCMDIR_REC, ("emurchan_init: bad direction"));
768 ch = &sc->rch[sc->rnum];
769 ch->buffer = b;
770 ch->parent = sc;
771 ch->channel = c;
772 ch->blksz = sc->bufsz / 2;
773 ch->fmt = AFMT_U8;
774 ch->spd = 8000;
775 ch->num = sc->rnum;
776 switch(sc->rnum) {
777 case 0:
778 ch->idxreg = ADCIDX;
779 ch->basereg = ADCBA;
780 ch->sizereg = ADCBS;
781 ch->setupreg = ADCCR;
782 ch->irqmask = INTE_ADCBUFENABLE;
783 break;
784
785 case 1:
786 ch->idxreg = FXIDX;
787 ch->basereg = FXBA;
788 ch->sizereg = FXBS;
789 ch->setupreg = FXWC;
790 ch->irqmask = INTE_EFXBUFENABLE;
791 break;
792
793 case 2:
794 ch->idxreg = MICIDX;
795 ch->basereg = MICBA;
796 ch->sizereg = MICBS;
797 ch->setupreg = 0;
798 ch->irqmask = INTE_MICBUFENABLE;
799 break;
800 }
801 sc->rnum++;
802 if (sndbuf_alloc(ch->buffer, sc->parent_dmat, sc->bufsz) == -1)
803 return NULL;
804 else {
805 snd_mtxlock(sc->lock);
806 emu_wrptr(sc, 0, ch->basereg, sndbuf_getbufaddr(ch->buffer));
807 emu_wrptr(sc, 0, ch->sizereg, 0); /* off */
808 snd_mtxunlock(sc->lock);
809 return ch;
810 }
811}
812
813static int
814emurchan_setformat(kobj_t obj, void *data, u_int32_t format)
815{
816 struct sc_rchinfo *ch = data;
817
818 ch->fmt = format;
819 return 0;
820}
821
822static int
823emurchan_setspeed(kobj_t obj, void *data, u_int32_t speed)
824{
825 struct sc_rchinfo *ch = data;
826
827 if (ch->num == 0)
828 speed = adcspeed[emu_recval(speed)];
829 if (ch->num == 1)
830 speed = 48000;
831 if (ch->num == 2)
832 speed = 8000;
833 ch->spd = speed;
834 return ch->spd;
835}
836
837static int
838emurchan_setblocksize(kobj_t obj, void *data, u_int32_t blocksize)
839{
840 struct sc_rchinfo *ch = data;
841 struct sc_info *sc = ch->parent;
842 int irqrate, blksz;
843
844 ch->blksz = blocksize;
845 snd_mtxlock(sc->lock);
846 emu_settimer(sc);
847 irqrate = 48000 / sc->timerinterval;
848 snd_mtxunlock(sc->lock);
849 blksz = (ch->spd * sndbuf_getbps(ch->buffer)) / irqrate;
850 return blocksize;
851}
852
853/* semantic note: must start at beginning of buffer */
854static int
855emurchan_trigger(kobj_t obj, void *data, int go)
856{
857 struct sc_rchinfo *ch = data;
858 struct sc_info *sc = ch->parent;
859 u_int32_t val, sz;
860
861 switch(sc->bufsz) {
862 case 4096:
863 sz = ADCBS_BUFSIZE_4096;
864 break;
865
866 case 8192:
867 sz = ADCBS_BUFSIZE_8192;
868 break;
869
870 case 16384:
871 sz = ADCBS_BUFSIZE_16384;
872 break;
873
874 case 32768:
875 sz = ADCBS_BUFSIZE_32768;
876 break;
877
878 case 65536:
879 sz = ADCBS_BUFSIZE_65536;
880 break;
881
882 default:
883 sz = ADCBS_BUFSIZE_4096;
884 }
885
886 snd_mtxlock(sc->lock);
887 switch(go) {
888 case PCMTRIG_START:
889 ch->run = 1;
890 emu_wrptr(sc, 0, ch->sizereg, sz);
891 if (ch->num == 0) {
892 val = ADCCR_LCHANENABLE;
893 if (ch->fmt & AFMT_STEREO)
894 val |= ADCCR_RCHANENABLE;
895 val |= emu_recval(ch->spd);
896 emu_wrptr(sc, 0, ch->setupreg, 0);
897 emu_wrptr(sc, 0, ch->setupreg, val);
898 }
899 val = emu_rd(sc, INTE, 4);
900 val |= ch->irqmask;
901 emu_wr(sc, INTE, val, 4);
902 break;
903
904 case PCMTRIG_STOP:
905 case PCMTRIG_ABORT:
906 ch->run = 0;
907 emu_wrptr(sc, 0, ch->sizereg, 0);
908 if (ch->setupreg)
909 emu_wrptr(sc, 0, ch->setupreg, 0);
910 val = emu_rd(sc, INTE, 4);
911 val &= ~ch->irqmask;
912 emu_wr(sc, INTE, val, 4);
913 break;
914
915 case PCMTRIG_EMLDMAWR:
916 case PCMTRIG_EMLDMARD:
917 default:
918 break;
919 }
920 snd_mtxunlock(sc->lock);
921
922 return 0;
923}
924
925static int
926emurchan_getptr(kobj_t obj, void *data)
927{
928 struct sc_rchinfo *ch = data;
929 struct sc_info *sc = ch->parent;
930 int r;
931
932 snd_mtxlock(sc->lock);
933 r = emu_rdptr(sc, 0, ch->idxreg) & 0x0000ffff;
934 snd_mtxunlock(sc->lock);
935
936 return r;
937}
938
939static struct pcmchan_caps *
940emurchan_getcaps(kobj_t obj, void *data)
941{
942 struct sc_rchinfo *ch = data;
943
944 return &emu_reccaps[ch->num];
945}
946
947static kobj_method_t emurchan_methods[] = {
948 KOBJMETHOD(channel_init, emurchan_init),
949 KOBJMETHOD(channel_setformat, emurchan_setformat),
950 KOBJMETHOD(channel_setspeed, emurchan_setspeed),
951 KOBJMETHOD(channel_setblocksize, emurchan_setblocksize),
952 KOBJMETHOD(channel_trigger, emurchan_trigger),
953 KOBJMETHOD(channel_getptr, emurchan_getptr),
954 KOBJMETHOD(channel_getcaps, emurchan_getcaps),
955 { 0, 0 }
956};
957CHANNEL_DECLARE(emurchan);
958
959/* -------------------------------------------------------------------- */
960/* The interrupt handler */
961static void
962emu_intr(void *p)
963{
964 struct sc_info *sc = (struct sc_info *)p;
965 u_int32_t stat, ack, i, x;
966
967 while (1) {
968 stat = emu_rd(sc, IPR, 4);
969 if (stat == 0)
970 break;
971 ack = 0;
972
973 /* process irq */
974 if (stat & IPR_INTERVALTIMER) {
975 ack |= IPR_INTERVALTIMER;
976 x = 0;
977 for (i = 0; i < EMU_CHANS; i++) {
978 if (sc->pch[i].run) {
979 x = 1;
980 chn_intr(sc->pch[i].channel);
981 }
982 }
983 if (x == 0)
984 emu_enatimer(sc, 0);
985 }
986
987
988 if (stat & (IPR_ADCBUFFULL | IPR_ADCBUFHALFFULL)) {
989 ack |= stat & (IPR_ADCBUFFULL | IPR_ADCBUFHALFFULL);
990 if (sc->rch[0].channel)
991 chn_intr(sc->rch[0].channel);
992 }
993 if (stat & (IPR_EFXBUFFULL | IPR_EFXBUFHALFFULL)) {
994 ack |= stat & (IPR_EFXBUFFULL | IPR_EFXBUFHALFFULL);
995 if (sc->rch[1].channel)
996 chn_intr(sc->rch[1].channel);
997 }
998 if (stat & (IPR_MICBUFFULL | IPR_MICBUFHALFFULL)) {
999 ack |= stat & (IPR_MICBUFFULL | IPR_MICBUFHALFFULL);
1000 if (sc->rch[2].channel)
1001 chn_intr(sc->rch[2].channel);
1002 }
1003 if (stat & IPR_PCIERROR) {
1004 ack |= IPR_PCIERROR;
1005 device_printf(sc->dev, "pci error\n");
1006 /* we still get an nmi with ecc ram even if we ack this */
1007 }
1008 if (stat & IPR_SAMPLERATETRACKER) {
1009 ack |= IPR_SAMPLERATETRACKER;
1010 /* device_printf(sc->dev, "sample rate tracker lock status change\n"); */
1011 }
1012
1013 if (stat & ~ack)
1014 device_printf(sc->dev, "dodgy irq: %x (harmless)\n", stat & ~ack);
1015
1016 emu_wr(sc, IPR, stat, 4);
1017 }
1018}
1019
1020/* -------------------------------------------------------------------- */
1021
1022static void
1023emu_setmap(void *arg, bus_dma_segment_t *segs, int nseg, int error)
1024{
1025 bus_addr_t *phys = arg;
1026
1027 *phys = error? 0 : (bus_addr_t)segs->ds_addr;
1028
1029 if (bootverbose) {
1030 printf("emu: setmap (%lx, %lx), nseg=%d, error=%d\n",
1031 (unsigned long)segs->ds_addr, (unsigned long)segs->ds_len,
1032 nseg, error);
1033 }
1034}
1035
1036static void *
1037emu_malloc(struct sc_info *sc, u_int32_t sz, bus_addr_t *addr)
1038{
1039 void *buf;
1040 bus_dmamap_t map;
1041
1042 *addr = 0;
1043 if (bus_dmamem_alloc(sc->parent_dmat, &buf, BUS_DMA_NOWAIT, &map))
1044 return NULL;
1045 if (bus_dmamap_load(sc->parent_dmat, map, buf, sz, emu_setmap, addr, 0)
1046 || !*addr)
1047 return NULL;
1048 return buf;
1049}
1050
1051static void
1052emu_free(struct sc_info *sc, void *buf)
1053{
1054 bus_dmamem_free(sc->parent_dmat, buf, NULL);
1055}
1056
1057static void *
1058emu_memalloc(struct sc_info *sc, u_int32_t sz, bus_addr_t *addr)
1059{
1060 u_int32_t blksz, start, idx, ofs, tmp, found;
1061 struct emu_mem *mem = &sc->mem;
1062 struct emu_memblk *blk;
1063 void *buf;
1064
1065 blksz = sz / EMUPAGESIZE;
1066 if (sz > (blksz * EMUPAGESIZE))
1067 blksz++;
1068 /* find a free block in the bitmap */
1069 found = 0;
1070 start = 1;
1071 while (!found && start + blksz < MAXPAGES) {
1072 found = 1;
1073 for (idx = start; idx < start + blksz; idx++)
1074 if (mem->bmap[idx >> 3] & (1 << (idx & 7)))
1075 found = 0;
1076 if (!found)
1077 start++;
1078 }
1079 if (!found)
1080 return NULL;
1081 blk = malloc(sizeof(*blk), M_DEVBUF, M_NOWAIT);
1082 if (blk == NULL)
1083 return NULL;
1084 buf = emu_malloc(sc, sz, &blk->buf_addr);
1085 *addr = blk->buf_addr;
1086 if (buf == NULL) {
1087 free(blk, M_DEVBUF);
1088 return NULL;
1089 }
1090 blk->buf = buf;
1091 blk->pte_start = start;
1092 blk->pte_size = blksz;
1093 /* printf("buf %p, pte_start %d, pte_size %d\n", blk->buf, blk->pte_start, blk->pte_size); */
1094 ofs = 0;
1095 for (idx = start; idx < start + blksz; idx++) {
1096 mem->bmap[idx >> 3] |= 1 << (idx & 7);
1097 tmp = (u_int32_t)(u_long)((u_int8_t *)blk->buf_addr + ofs);
1098 /* printf("pte[%d] -> %x phys, %x virt\n", idx, tmp, ((u_int32_t)buf) + ofs); */
1099 mem->ptb_pages[idx] = (tmp << 1) | idx;
1100 ofs += EMUPAGESIZE;
1101 }
1102 SLIST_INSERT_HEAD(&mem->blocks, blk, link);
1103 return buf;
1104}
1105
1106static int
1107emu_memfree(struct sc_info *sc, void *buf)
1108{
1109 u_int32_t idx, tmp;
1110 struct emu_mem *mem = &sc->mem;
1111 struct emu_memblk *blk, *i;
1112
1113 blk = NULL;
1114 SLIST_FOREACH(i, &mem->blocks, link) {
1115 if (i->buf == buf)
1116 blk = i;
1117 }
1118 if (blk == NULL)
1119 return EINVAL;
1120 SLIST_REMOVE(&mem->blocks, blk, emu_memblk, link);
1121 emu_free(sc, buf);
1122 tmp = (u_int32_t)(sc->mem.silent_page_addr) << 1;
1123 for (idx = blk->pte_start; idx < blk->pte_start + blk->pte_size; idx++) {
1124 mem->bmap[idx >> 3] &= ~(1 << (idx & 7));
1125 mem->ptb_pages[idx] = tmp | idx;
1126 }
1127 free(blk, M_DEVBUF);
1128 return 0;
1129}
1130
1131static int
1132emu_memstart(struct sc_info *sc, void *buf)
1133{
1134 struct emu_mem *mem = &sc->mem;
1135 struct emu_memblk *blk, *i;
1136
1137 blk = NULL;
1138 SLIST_FOREACH(i, &mem->blocks, link) {
1139 if (i->buf == buf)
1140 blk = i;
1141 }
1142 if (blk == NULL)
1143 return -EINVAL;
1144 return blk->pte_start;
1145}
1146
1147static void
1148emu_addefxop(struct sc_info *sc, int op, int z, int w, int x, int y, u_int32_t *pc)
1149{
1150 emu_wrefx(sc, (*pc) * 2, (x << 10) | y);
1151 emu_wrefx(sc, (*pc) * 2 + 1, (op << 20) | (z << 10) | w);
1152 (*pc)++;
1153}
1154
1155static void
1156emu_initefx(struct sc_info *sc)
1157{
1158 int i;
1159 u_int32_t pc = 16;
1160
1161 for (i = 0; i < 512; i++) {
1162 emu_wrefx(sc, i * 2, 0x10040);
1163 emu_wrefx(sc, i * 2 + 1, 0x610040);
1164 }
1165
1166 for (i = 0; i < 256; i++)
1167 emu_wrptr(sc, 0, FXGPREGBASE + i, 0);
1168
1169 /* FX-8010 DSP Registers:
1170 FX Bus
1171 0x000-0x00f : 16 registers
1172 Input
1173 0x010/0x011 : AC97 Codec (l/r)
1174 0x012/0x013 : ADC, S/PDIF (l/r)
1175 0x014/0x015 : Mic(left), Zoom (l/r)
1176 0x016/0x017 : APS S/PDIF?? (l/r)
1177 Output
1178 0x020/0x021 : AC97 Output (l/r)
1179 0x022/0x023 : TOS link out (l/r)
1180 0x024/0x025 : ??? (l/r)
1181 0x026/0x027 : LiveDrive Headphone (l/r)
1182 0x028/0x029 : Rear Channel (l/r)
1183 0x02a/0x02b : ADC Recording Buffer (l/r)
1184 Constants
1185 0x040 - 0x044 = 0 - 4
1186 0x045 = 0x8, 0x046 = 0x10, 0x047 = 0x20
1187 0x048 = 0x100, 0x049 = 0x10000, 0x04a = 0x80000
1188 0x04b = 0x10000000, 0x04c = 0x20000000, 0x04d = 0x40000000
1189 0x04e = 0x80000000, 0x04f = 0x7fffffff
1190 Temporary Values
1191 0x056 : Accumulator
1192 0x058 : Noise source?
1193 0x059 : Noise source?
1194 General Purpose Registers
1195 0x100 - 0x1ff
1196 Tank Memory Data Registers
1197 0x200 - 0x2ff
1198 Tank Memory Address Registers
1199 0x300 - 0x3ff
1200 */
1201
1202 /* Operators:
1203 0 : z := w + (x * y >> 31)
1204 4 : z := w + x * y
1205 6 : z := w + x + y
1206 */
1207
1208 /* Routing - this will be configurable in later version */
1209
1210 /* GPR[0/1] = FX * 4 + SPDIF-in */
1211 emu_addefxop(sc, 4, 0x100, 0x12, 0, 0x44, &pc);
1212 emu_addefxop(sc, 4, 0x101, 0x13, 1, 0x44, &pc);
1213 /* GPR[0/1] += APS-input */
1214 emu_addefxop(sc, 6, 0x100, 0x100, 0x40, sc->APS ? 0x16 : 0x40, &pc);
1215 emu_addefxop(sc, 6, 0x101, 0x101, 0x40, sc->APS ? 0x17 : 0x40, &pc);
1216 /* FrontOut (AC97) = GPR[0/1] */
1217 emu_addefxop(sc, 6, 0x20, 0x40, 0x40, 0x100, &pc);
1218 emu_addefxop(sc, 6, 0x21, 0x40, 0x41, 0x101, &pc);
1219 /* RearOut = (GPR[0/1] * RearVolume) >> 31 */
1220 /* RearVolume = GRP[0x10/0x11] */
1221 emu_addefxop(sc, 0, 0x28, 0x40, 0x110, 0x100, &pc);
1222 emu_addefxop(sc, 0, 0x29, 0x40, 0x111, 0x101, &pc);
1223 /* TOS out = GPR[0/1] */
1224 emu_addefxop(sc, 6, 0x22, 0x40, 0x40, 0x100, &pc);
1225 emu_addefxop(sc, 6, 0x23, 0x40, 0x40, 0x101, &pc);
1226 /* Mute Out2 */
1227 emu_addefxop(sc, 6, 0x24, 0x40, 0x40, 0x40, &pc);
1228 emu_addefxop(sc, 6, 0x25, 0x40, 0x40, 0x40, &pc);
1229 /* Mute Out3 */
1230 emu_addefxop(sc, 6, 0x26, 0x40, 0x40, 0x40, &pc);
1231 emu_addefxop(sc, 6, 0x27, 0x40, 0x40, 0x40, &pc);
1232 /* Input0 (AC97) -> Record */
1233 emu_addefxop(sc, 6, 0x2a, 0x40, 0x40, 0x10, &pc);
1234 emu_addefxop(sc, 6, 0x2b, 0x40, 0x40, 0x11, &pc);
1235
1236 emu_wrptr(sc, 0, DBG, 0);
1237}
1238
1239/* Probe and attach the card */
1240static int
1241emu_init(struct sc_info *sc)
1242{
1243 u_int32_t spcs, ch, tmp, i;
1244
1245 /* disable audio and lock cache */
1246 emu_wr(sc, HCFG, HCFG_LOCKSOUNDCACHE | HCFG_LOCKTANKCACHE | HCFG_MUTEBUTTONENABLE, 4);
1247
1248 /* reset recording buffers */
1249 emu_wrptr(sc, 0, MICBS, ADCBS_BUFSIZE_NONE);
1250 emu_wrptr(sc, 0, MICBA, 0);
1251 emu_wrptr(sc, 0, FXBS, ADCBS_BUFSIZE_NONE);
1252 emu_wrptr(sc, 0, FXBA, 0);
1253 emu_wrptr(sc, 0, ADCBS, ADCBS_BUFSIZE_NONE);
1254 emu_wrptr(sc, 0, ADCBA, 0);
1255
1256 /* disable channel interrupt */
1257 emu_wr(sc, INTE, INTE_INTERVALTIMERENB | INTE_SAMPLERATETRACKER | INTE_PCIERRORENABLE, 4);
1258 emu_wrptr(sc, 0, CLIEL, 0);
1259 emu_wrptr(sc, 0, CLIEH, 0);
1260 emu_wrptr(sc, 0, SOLEL, 0);
1261 emu_wrptr(sc, 0, SOLEH, 0);
1262
1263 /* init envelope engine */
1264 for (ch = 0; ch < NUM_G; ch++) {
1265 emu_wrptr(sc, ch, DCYSUSV, ENV_OFF);
1266 emu_wrptr(sc, ch, IP, 0);
1267 emu_wrptr(sc, ch, VTFT, 0xffff);
1268 emu_wrptr(sc, ch, CVCF, 0xffff);
1269 emu_wrptr(sc, ch, PTRX, 0);
1270 emu_wrptr(sc, ch, CPF, 0);
1271 emu_wrptr(sc, ch, CCR, 0);
1272
1273 emu_wrptr(sc, ch, PSST, 0);
1274 emu_wrptr(sc, ch, DSL, 0x10);
1275 emu_wrptr(sc, ch, CCCA, 0);
1276 emu_wrptr(sc, ch, Z1, 0);
1277 emu_wrptr(sc, ch, Z2, 0);
1278 emu_wrptr(sc, ch, FXRT, 0xd01c0000);
1279
1280 emu_wrptr(sc, ch, ATKHLDM, 0);
1281 emu_wrptr(sc, ch, DCYSUSM, 0);
1282 emu_wrptr(sc, ch, IFATN, 0xffff);
1283 emu_wrptr(sc, ch, PEFE, 0);
1284 emu_wrptr(sc, ch, FMMOD, 0);
1285 emu_wrptr(sc, ch, TREMFRQ, 24); /* 1 Hz */
1286 emu_wrptr(sc, ch, FM2FRQ2, 24); /* 1 Hz */
1287 emu_wrptr(sc, ch, TEMPENV, 0);
1288
1289 /*** these are last so OFF prevents writing ***/
1290 emu_wrptr(sc, ch, LFOVAL2, 0);
1291 emu_wrptr(sc, ch, LFOVAL1, 0);
1292 emu_wrptr(sc, ch, ATKHLDV, 0);
1293 emu_wrptr(sc, ch, ENVVOL, 0);
1294 emu_wrptr(sc, ch, ENVVAL, 0);
1295
1296 sc->voice[ch].vnum = ch;
1297 sc->voice[ch].slave = NULL;
1298 sc->voice[ch].busy = 0;
1299 sc->voice[ch].ismaster = 0;
1300 sc->voice[ch].running = 0;
1301 sc->voice[ch].b16 = 0;
1302 sc->voice[ch].stereo = 0;
1303 sc->voice[ch].speed = 0;
1304 sc->voice[ch].start = 0;
1305 sc->voice[ch].end = 0;
1306 sc->voice[ch].channel = NULL;
1307 }
1308 sc->pnum = sc->rnum = 0;
1309
1310 /*
1311 * Init to 0x02109204 :
1312 * Clock accuracy = 0 (1000ppm)
1313 * Sample Rate = 2 (48kHz)
1314 * Audio Channel = 1 (Left of 2)
1315 * Source Number = 0 (Unspecified)
1316 * Generation Status = 1 (Original for Cat Code 12)
1317 * Cat Code = 12 (Digital Signal Mixer)
1318 * Mode = 0 (Mode 0)
1319 * Emphasis = 0 (None)
1320 * CP = 1 (Copyright unasserted)
1321 * AN = 0 (Audio data)
1322 * P = 0 (Consumer)
1323 */
1324 spcs = SPCS_CLKACCY_1000PPM | SPCS_SAMPLERATE_48 |
1325 SPCS_CHANNELNUM_LEFT | SPCS_SOURCENUM_UNSPEC |
1326 SPCS_GENERATIONSTATUS | 0x00001200 | 0x00000000 |
1327 SPCS_EMPHASIS_NONE | SPCS_COPYRIGHT;
1328 emu_wrptr(sc, 0, SPCS0, spcs);
1329 emu_wrptr(sc, 0, SPCS1, spcs);
1330 emu_wrptr(sc, 0, SPCS2, spcs);
1331
1332 emu_initefx(sc);
1333
1334 SLIST_INIT(&sc->mem.blocks);
1335 sc->mem.ptb_pages = emu_malloc(sc, MAXPAGES * sizeof(u_int32_t), &sc->mem.ptb_pages_addr);
1336 if (sc->mem.ptb_pages == NULL)
1337 return -1;
1338
1339 sc->mem.silent_page = emu_malloc(sc, EMUPAGESIZE, &sc->mem.silent_page_addr);
1340 if (sc->mem.silent_page == NULL) {
1341 emu_free(sc, sc->mem.ptb_pages);
1342 return -1;
1343 }
1344 /* Clear page with silence & setup all pointers to this page */
1345 bzero(sc->mem.silent_page, EMUPAGESIZE);
1346 tmp = (u_int32_t)(sc->mem.silent_page_addr) << 1;
1347 for (i = 0; i < MAXPAGES; i++)
1348 sc->mem.ptb_pages[i] = tmp | i;
1349
1350 emu_wrptr(sc, 0, PTB, (sc->mem.ptb_pages_addr));
1351 emu_wrptr(sc, 0, TCB, 0); /* taken from original driver */
1352 emu_wrptr(sc, 0, TCBS, 0); /* taken from original driver */
1353
1354 for (ch = 0; ch < NUM_G; ch++) {
1355 emu_wrptr(sc, ch, MAPA, tmp | MAP_PTI_MASK);
1356 emu_wrptr(sc, ch, MAPB, tmp | MAP_PTI_MASK);
1357 }
1358
1359 /* emu_memalloc(sc, EMUPAGESIZE); */
1360 /*
1361 * Hokay, now enable the AUD bit
1362 * Enable Audio = 1
1363 * Mute Disable Audio = 0
1364 * Lock Tank Memory = 1
1365 * Lock Sound Memory = 0
1366 * Auto Mute = 1
1367 */
1368 tmp = HCFG_AUDIOENABLE | HCFG_LOCKTANKCACHE | HCFG_AUTOMUTE;
1369 if (sc->rev >= 6)
1370 tmp |= HCFG_JOYENABLE;
1371 emu_wr(sc, HCFG, tmp, 4);
1372
1373 /* TOSLink detection */
1374 sc->tos_link = 0;
1375 tmp = emu_rd(sc, HCFG, 4);
1376 if (tmp & (HCFG_GPINPUT0 | HCFG_GPINPUT1)) {
1377 emu_wr(sc, HCFG, tmp | 0x800, 4);
1378 DELAY(50);
1379 if (tmp != (emu_rd(sc, HCFG, 4) & ~0x800)) {
1380 sc->tos_link = 1;
1381 emu_wr(sc, HCFG, tmp, 4);
1382 }
1383 }
1384
1385 return 0;
1386}
1387
1388static int
1389emu_uninit(struct sc_info *sc)
1390{
1391 u_int32_t ch;
1392
1393 emu_wr(sc, INTE, 0, 4);
1394 for (ch = 0; ch < NUM_G; ch++)
1395 emu_wrptr(sc, ch, DCYSUSV, ENV_OFF);
1396 for (ch = 0; ch < NUM_G; ch++) {
1397 emu_wrptr(sc, ch, VTFT, 0);
1398 emu_wrptr(sc, ch, CVCF, 0);
1399 emu_wrptr(sc, ch, PTRX, 0);
1400 emu_wrptr(sc, ch, CPF, 0);
1401 }
1402
1403 /* disable audio and lock cache */
1404 emu_wr(sc, HCFG, HCFG_LOCKSOUNDCACHE | HCFG_LOCKTANKCACHE | HCFG_MUTEBUTTONENABLE, 4);
1405
1406 emu_wrptr(sc, 0, PTB, 0);
1407 /* reset recording buffers */
1408 emu_wrptr(sc, 0, MICBS, ADCBS_BUFSIZE_NONE);
1409 emu_wrptr(sc, 0, MICBA, 0);
1410 emu_wrptr(sc, 0, FXBS, ADCBS_BUFSIZE_NONE);
1411 emu_wrptr(sc, 0, FXBA, 0);
1412 emu_wrptr(sc, 0, FXWC, 0);
1413 emu_wrptr(sc, 0, ADCBS, ADCBS_BUFSIZE_NONE);
1414 emu_wrptr(sc, 0, ADCBA, 0);
1415 emu_wrptr(sc, 0, TCB, 0);
1416 emu_wrptr(sc, 0, TCBS, 0);
1417
1418 /* disable channel interrupt */
1419 emu_wrptr(sc, 0, CLIEL, 0);
1420 emu_wrptr(sc, 0, CLIEH, 0);
1421 emu_wrptr(sc, 0, SOLEL, 0);
1422 emu_wrptr(sc, 0, SOLEH, 0);
1423
1424 /* init envelope engine */
1425 if (!SLIST_EMPTY(&sc->mem.blocks))
1426 device_printf(sc->dev, "warning: memblock list not empty\n");
1427 emu_free(sc, sc->mem.ptb_pages);
1428 emu_free(sc, sc->mem.silent_page);
1429
1430 return 0;
1431}
1432
1433static int
1434emu_pci_probe(device_t dev)
1435{
1436 char *s = NULL;
1437
1438 switch (pci_get_devid(dev)) {
1439 case EMU10K1_PCI_ID:
1440 s = "Creative EMU10K1";
1441 break;
1442/*
1443 case EMU10K2_PCI_ID:
1444 s = "Creative EMU10K2";
1445 break;
1446*/
1447 default:
1448 return ENXIO;
1449 }
1450
1451 device_set_desc(dev, s);
1452 return 0;
1453}
1454
1455static int
1456emu_pci_attach(device_t dev)
1457{
1458 struct ac97_info *codec = NULL;
1459 struct sc_info *sc;
1460 u_int32_t data;
1461 int i, gotmic;
1462 char status[SND_STATUSLEN];
1463
1464 if ((sc = malloc(sizeof(*sc), M_DEVBUF, M_WAITOK | M_ZERO)) == NULL) {
1465 device_printf(dev, "cannot allocate softc\n");
1466 return ENXIO;
1467 }
1468
1469 sc->lock = snd_mtxcreate(device_get_nameunit(dev), "sound softc");
1470 sc->dev = dev;
1471 sc->type = pci_get_devid(dev);
1472 sc->rev = pci_get_revid(dev);
1473
1474 data = pci_read_config(dev, PCIR_COMMAND, 2);
1475 data |= (PCIM_CMD_PORTEN | PCIM_CMD_BUSMASTEREN);
1476 pci_write_config(dev, PCIR_COMMAND, data, 2);
1477 data = pci_read_config(dev, PCIR_COMMAND, 2);
1478
1479 i = PCIR_MAPS;
1480 sc->reg = bus_alloc_resource(dev, SYS_RES_IOPORT, &i, 0, ~0, 1, RF_ACTIVE);
1481 if (sc->reg == NULL) {
1482 device_printf(dev, "unable to map register space\n");
1483 goto bad;
1484 }
1485 sc->st = rman_get_bustag(sc->reg);
1486 sc->sh = rman_get_bushandle(sc->reg);
1487
1488 sc->bufsz = pcm_getbuffersize(dev, 4096, EMU_DEFAULT_BUFSZ, 65536);
1489
1490 if (bus_dma_tag_create(/*parent*/NULL, /*alignment*/2, /*boundary*/0,
1491 /*lowaddr*/1 << 31, /* can only access 0-2gb */
1492 /*highaddr*/BUS_SPACE_MAXADDR,
1493 /*filter*/NULL, /*filterarg*/NULL,
1494 /*maxsize*/sc->bufsz, /*nsegments*/1, /*maxsegz*/0x3ffff,
1495 /*flags*/0, &sc->parent_dmat) != 0) {
1496 device_printf(dev, "unable to create dma tag\n");
1497 goto bad;
1498 }
1499
1500 if (emu_init(sc) == -1) {
1501 device_printf(dev, "unable to initialize the card\n");
1502 goto bad;
1503 }
1504
1505 codec = AC97_CREATE(dev, sc, emu_ac97);
1506 if (codec == NULL) goto bad;
1507 gotmic = (ac97_getcaps(codec) & AC97_CAP_MICCHANNEL)? 1 : 0;
1508 if (mixer_init(dev, ac97_getmixerclass(), codec) == -1) goto bad;
1509
1510 i = 0;
1511 sc->irq = bus_alloc_resource(dev, SYS_RES_IRQ, &i, 0, ~0, 1, RF_ACTIVE | RF_SHAREABLE);
1512 if (!sc->irq || snd_setup_intr(dev, sc->irq, INTR_MPSAFE, emu_intr, sc, &sc->ih)) {
1513 device_printf(dev, "unable to map interrupt\n");
1514 goto bad;
1515 }
1516
1517 snprintf(status, SND_STATUSLEN, "at io 0x%lx irq %ld", rman_get_start(sc->reg), rman_get_start(sc->irq));
1518
1519 if (pcm_register(dev, sc, EMU_CHANS, gotmic? 3 : 2)) goto bad;
1520 for (i = 0; i < EMU_CHANS; i++)
1521 pcm_addchan(dev, PCMDIR_PLAY, &emupchan_class, sc);
1522 for (i = 0; i < (gotmic? 3 : 2); i++)
1523 pcm_addchan(dev, PCMDIR_REC, &emurchan_class, sc);
1524
1525 pcm_setstatus(dev, status);
1526
1527 return 0;
1528
1529bad:
1530 if (codec) ac97_destroy(codec);
1531 if (sc->reg) bus_release_resource(dev, SYS_RES_IOPORT, PCIR_MAPS, sc->reg);
1532 if (sc->ih) bus_teardown_intr(dev, sc->irq, sc->ih);
1533 if (sc->irq) bus_release_resource(dev, SYS_RES_IRQ, 0, sc->irq);
1534 if (sc->parent_dmat) bus_dma_tag_destroy(sc->parent_dmat);
1535 if (sc->lock) snd_mtxfree(sc->lock);
1536 free(sc, M_DEVBUF);
1537 return ENXIO;
1538}
1539
1540static int
1541emu_pci_detach(device_t dev)
1542{
1543 int r;
1544 struct sc_info *sc;
1545
1546 r = pcm_unregister(dev);
1547 if (r)
1548 return r;
1549
1550 sc = pcm_getdevinfo(dev);
1551 /* shutdown chip */
1552 emu_uninit(sc);
1553
1554 bus_release_resource(dev, SYS_RES_IOPORT, PCIR_MAPS, sc->reg);
1555 bus_teardown_intr(dev, sc->irq, sc->ih);
1556 bus_release_resource(dev, SYS_RES_IRQ, 0, sc->irq);
1557 bus_dma_tag_destroy(sc->parent_dmat);
1558 snd_mtxfree(sc->lock);
1559 free(sc, M_DEVBUF);
1560
1561 return 0;
1562}
1563
1564/* add suspend, resume */
1565static device_method_t emu_methods[] = {
1566 /* Device interface */
1567 DEVMETHOD(device_probe, emu_pci_probe),
1568 DEVMETHOD(device_attach, emu_pci_attach),
1569 DEVMETHOD(device_detach, emu_pci_detach),
1570
1571 { 0, 0 }
1572};
1573
1574static driver_t emu_driver = {
1575 "pcm",
1576 emu_methods,
1577 PCM_SOFTC_SIZE,
1578};
1579
1580DRIVER_MODULE(snd_emu10k1, pci, emu_driver, pcm_devclass, 0, 0);
1581MODULE_DEPEND(snd_emu10k1, snd_pcm, PCM_MINVER, PCM_PREFVER, PCM_MAXVER);
1582MODULE_VERSION(snd_emu10k1, 1);
1583
1584/* dummy driver to silence the joystick device */
1585static int
1586emujoy_pci_probe(device_t dev)
1587{
1588 char *s = NULL;
1589
1590 switch (pci_get_devid(dev)) {
1591 case 0x70021102:
1592 s = "Creative EMU10K1 Joystick";
1593 device_quiet(dev);
1594 break;
1595 case 0x70031102:
1596 s = "Creative EMU10K2 Joystick";
1597 device_quiet(dev);
1598 break;
1599 }
1600
1601 if (s) device_set_desc(dev, s);
1602 return s? -1000 : ENXIO;
1603}
1604
1605static int
1606emujoy_pci_attach(device_t dev)
1607{
1608 return 0;
1609}
1610
1611static int
1612emujoy_pci_detach(device_t dev)
1613{
1614 return 0;
1615}
1616
1617static device_method_t emujoy_methods[] = {
1618 DEVMETHOD(device_probe, emujoy_pci_probe),
1619 DEVMETHOD(device_attach, emujoy_pci_attach),
1620 DEVMETHOD(device_detach, emujoy_pci_detach),
1621
1622 { 0, 0 }
1623};
1624
1625static driver_t emujoy_driver = {
1626 "emujoy",
1627 emujoy_methods,
1628 8,
1629};
1630
1631static devclass_t emujoy_devclass;
1632
1633DRIVER_MODULE(emujoy, pci, emujoy_driver, emujoy_devclass, 0, 0);
1634