Deleted Added
sdiff udiff text old ( 119287 ) new ( 119690 )
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 <dev/pci/pcireg.h>
32#include <dev/pci/pcivar.h>
33#include <sys/queue.h>
34
35SND_DECLARE_FILE("$FreeBSD: head/sys/dev/sound/pci/emu10k1.c 119690 2003-09-02 17:30:40Z jhb $");
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[] = {
603 "cpf", "ptrx", "cvcf", "vtft", "z2", "z1", "psst", "dsl",
604 "ccca", "ccr", "clp", "fxrt", "mapa", "mapb", NULL, NULL,
605 "envvol", "atkhldv", "dcysusv", "lfoval1",
606 "envval", "atkhldm", "dcysusm", "lfoval2",
607 "ip", "ifatn", "pefe", "fmmod", "tremfrq", "fmfrq2",
608 "tempenv"
609 };
610 int i, x;
611
612 printf("voice number %d\n", v->vnum);
613 for (i = 0, x = 0; i <= 0x1e; i++) {
614 if (regname[i] == NULL)
615 continue;
616 printf("%s\t[%08x]", regname[i], emu_rdptr(sc, v->vnum, i));
617 printf("%s", (x == 2) ? "\n" : "\t");
618 x++;
619 if (x > 2)
620 x = 0;
621 }
622 printf("\n\n");
623}
624#endif
625
626/* channel interface */
627static void *
628emupchan_init(kobj_t obj, void *devinfo, struct snd_dbuf *b, struct pcm_channel *c, int dir)
629{
630 struct sc_info *sc = devinfo;
631 struct sc_pchinfo *ch;
632 void *r;
633
634 KASSERT(dir == PCMDIR_PLAY, ("emupchan_init: bad direction"));
635 ch = &sc->pch[sc->pnum++];
636 ch->buffer = b;
637 ch->parent = sc;
638 ch->channel = c;
639 ch->blksz = sc->bufsz / 2;
640 ch->fmt = AFMT_U8;
641 ch->spd = 8000;
642 snd_mtxlock(sc->lock);
643 ch->master = emu_valloc(sc);
644 ch->slave = emu_valloc(sc);
645 snd_mtxunlock(sc->lock);
646 r = (emu_vinit(sc, ch->master, ch->slave, sc->bufsz, ch->buffer)) ? NULL : ch;
647
648 return r;
649}
650
651static int
652emupchan_free(kobj_t obj, void *data)
653{
654 struct sc_pchinfo *ch = data;
655 struct sc_info *sc = ch->parent;
656 int r;
657
658 snd_mtxlock(sc->lock);
659 r = emu_memfree(sc, sndbuf_getbuf(ch->buffer));
660 snd_mtxunlock(sc->lock);
661
662 return r;
663}
664
665static int
666emupchan_setformat(kobj_t obj, void *data, u_int32_t format)
667{
668 struct sc_pchinfo *ch = data;
669
670 ch->fmt = format;
671 return 0;
672}
673
674static int
675emupchan_setspeed(kobj_t obj, void *data, u_int32_t speed)
676{
677 struct sc_pchinfo *ch = data;
678
679 ch->spd = speed;
680 return ch->spd;
681}
682
683static int
684emupchan_setblocksize(kobj_t obj, void *data, u_int32_t blocksize)
685{
686 struct sc_pchinfo *ch = data;
687 struct sc_info *sc = ch->parent;
688 int irqrate, blksz;
689
690 ch->blksz = blocksize;
691 snd_mtxlock(sc->lock);
692 emu_settimer(sc);
693 irqrate = 48000 / sc->timerinterval;
694 snd_mtxunlock(sc->lock);
695 blksz = (ch->spd * sndbuf_getbps(ch->buffer)) / irqrate;
696 return blocksize;
697}
698
699static int
700emupchan_trigger(kobj_t obj, void *data, int go)
701{
702 struct sc_pchinfo *ch = data;
703 struct sc_info *sc = ch->parent;
704
705 if (go == PCMTRIG_EMLDMAWR || go == PCMTRIG_EMLDMARD)
706 return 0;
707
708 snd_mtxlock(sc->lock);
709 if (go == PCMTRIG_START) {
710 emu_vsetup(ch);
711 emu_vwrite(sc, ch->master);
712 emu_settimer(sc);
713 emu_enatimer(sc, 1);
714#ifdef EMUDEBUG
715 printf("start [%d bit, %s, %d hz]\n",
716 ch->master->b16 ? 16 : 8,
717 ch->master->stereo ? "stereo" : "mono",
718 ch->master->speed);
719 emu_vdump(sc, ch->master);
720 emu_vdump(sc, ch->slave);
721#endif
722 }
723 ch->run = (go == PCMTRIG_START) ? 1 : 0;
724 emu_vtrigger(sc, ch->master, ch->run);
725 snd_mtxunlock(sc->lock);
726 return 0;
727}
728
729static int
730emupchan_getptr(kobj_t obj, void *data)
731{
732 struct sc_pchinfo *ch = data;
733 struct sc_info *sc = ch->parent;
734 int r;
735
736 snd_mtxlock(sc->lock);
737 r = emu_vpos(sc, ch->master);
738 snd_mtxunlock(sc->lock);
739
740 return r;
741}
742
743static struct pcmchan_caps *
744emupchan_getcaps(kobj_t obj, void *data)
745{
746 return &emu_playcaps;
747}
748
749static kobj_method_t emupchan_methods[] = {
750 KOBJMETHOD(channel_init, emupchan_init),
751 KOBJMETHOD(channel_free, emupchan_free),
752 KOBJMETHOD(channel_setformat, emupchan_setformat),
753 KOBJMETHOD(channel_setspeed, emupchan_setspeed),
754 KOBJMETHOD(channel_setblocksize, emupchan_setblocksize),
755 KOBJMETHOD(channel_trigger, emupchan_trigger),
756 KOBJMETHOD(channel_getptr, emupchan_getptr),
757 KOBJMETHOD(channel_getcaps, emupchan_getcaps),
758 { 0, 0 }
759};
760CHANNEL_DECLARE(emupchan);
761
762/* channel interface */
763static void *
764emurchan_init(kobj_t obj, void *devinfo, struct snd_dbuf *b, struct pcm_channel *c, int dir)
765{
766 struct sc_info *sc = devinfo;
767 struct sc_rchinfo *ch;
768
769 KASSERT(dir == PCMDIR_REC, ("emurchan_init: bad direction"));
770 ch = &sc->rch[sc->rnum];
771 ch->buffer = b;
772 ch->parent = sc;
773 ch->channel = c;
774 ch->blksz = sc->bufsz / 2;
775 ch->fmt = AFMT_U8;
776 ch->spd = 8000;
777 ch->num = sc->rnum;
778 switch(sc->rnum) {
779 case 0:
780 ch->idxreg = ADCIDX;
781 ch->basereg = ADCBA;
782 ch->sizereg = ADCBS;
783 ch->setupreg = ADCCR;
784 ch->irqmask = INTE_ADCBUFENABLE;
785 break;
786
787 case 1:
788 ch->idxreg = FXIDX;
789 ch->basereg = FXBA;
790 ch->sizereg = FXBS;
791 ch->setupreg = FXWC;
792 ch->irqmask = INTE_EFXBUFENABLE;
793 break;
794
795 case 2:
796 ch->idxreg = MICIDX;
797 ch->basereg = MICBA;
798 ch->sizereg = MICBS;
799 ch->setupreg = 0;
800 ch->irqmask = INTE_MICBUFENABLE;
801 break;
802 }
803 sc->rnum++;
804 if (sndbuf_alloc(ch->buffer, sc->parent_dmat, sc->bufsz) == -1)
805 return NULL;
806 else {
807 snd_mtxlock(sc->lock);
808 emu_wrptr(sc, 0, ch->basereg, sndbuf_getbufaddr(ch->buffer));
809 emu_wrptr(sc, 0, ch->sizereg, 0); /* off */
810 snd_mtxunlock(sc->lock);
811 return ch;
812 }
813}
814
815static int
816emurchan_setformat(kobj_t obj, void *data, u_int32_t format)
817{
818 struct sc_rchinfo *ch = data;
819
820 ch->fmt = format;
821 return 0;
822}
823
824static int
825emurchan_setspeed(kobj_t obj, void *data, u_int32_t speed)
826{
827 struct sc_rchinfo *ch = data;
828
829 if (ch->num == 0)
830 speed = adcspeed[emu_recval(speed)];
831 if (ch->num == 1)
832 speed = 48000;
833 if (ch->num == 2)
834 speed = 8000;
835 ch->spd = speed;
836 return ch->spd;
837}
838
839static int
840emurchan_setblocksize(kobj_t obj, void *data, u_int32_t blocksize)
841{
842 struct sc_rchinfo *ch = data;
843 struct sc_info *sc = ch->parent;
844 int irqrate, blksz;
845
846 ch->blksz = blocksize;
847 snd_mtxlock(sc->lock);
848 emu_settimer(sc);
849 irqrate = 48000 / sc->timerinterval;
850 snd_mtxunlock(sc->lock);
851 blksz = (ch->spd * sndbuf_getbps(ch->buffer)) / irqrate;
852 return blocksize;
853}
854
855/* semantic note: must start at beginning of buffer */
856static int
857emurchan_trigger(kobj_t obj, void *data, int go)
858{
859 struct sc_rchinfo *ch = data;
860 struct sc_info *sc = ch->parent;
861 u_int32_t val, sz;
862
863 switch(sc->bufsz) {
864 case 4096:
865 sz = ADCBS_BUFSIZE_4096;
866 break;
867
868 case 8192:
869 sz = ADCBS_BUFSIZE_8192;
870 break;
871
872 case 16384:
873 sz = ADCBS_BUFSIZE_16384;
874 break;
875
876 case 32768:
877 sz = ADCBS_BUFSIZE_32768;
878 break;
879
880 case 65536:
881 sz = ADCBS_BUFSIZE_65536;
882 break;
883
884 default:
885 sz = ADCBS_BUFSIZE_4096;
886 }
887
888 snd_mtxlock(sc->lock);
889 switch(go) {
890 case PCMTRIG_START:
891 ch->run = 1;
892 emu_wrptr(sc, 0, ch->sizereg, sz);
893 if (ch->num == 0) {
894 val = ADCCR_LCHANENABLE;
895 if (ch->fmt & AFMT_STEREO)
896 val |= ADCCR_RCHANENABLE;
897 val |= emu_recval(ch->spd);
898 emu_wrptr(sc, 0, ch->setupreg, 0);
899 emu_wrptr(sc, 0, ch->setupreg, val);
900 }
901 val = emu_rd(sc, INTE, 4);
902 val |= ch->irqmask;
903 emu_wr(sc, INTE, val, 4);
904 break;
905
906 case PCMTRIG_STOP:
907 case PCMTRIG_ABORT:
908 ch->run = 0;
909 emu_wrptr(sc, 0, ch->sizereg, 0);
910 if (ch->setupreg)
911 emu_wrptr(sc, 0, ch->setupreg, 0);
912 val = emu_rd(sc, INTE, 4);
913 val &= ~ch->irqmask;
914 emu_wr(sc, INTE, val, 4);
915 break;
916
917 case PCMTRIG_EMLDMAWR:
918 case PCMTRIG_EMLDMARD:
919 default:
920 break;
921 }
922 snd_mtxunlock(sc->lock);
923
924 return 0;
925}
926
927static int
928emurchan_getptr(kobj_t obj, void *data)
929{
930 struct sc_rchinfo *ch = data;
931 struct sc_info *sc = ch->parent;
932 int r;
933
934 snd_mtxlock(sc->lock);
935 r = emu_rdptr(sc, 0, ch->idxreg) & 0x0000ffff;
936 snd_mtxunlock(sc->lock);
937
938 return r;
939}
940
941static struct pcmchan_caps *
942emurchan_getcaps(kobj_t obj, void *data)
943{
944 struct sc_rchinfo *ch = data;
945
946 return &emu_reccaps[ch->num];
947}
948
949static kobj_method_t emurchan_methods[] = {
950 KOBJMETHOD(channel_init, emurchan_init),
951 KOBJMETHOD(channel_setformat, emurchan_setformat),
952 KOBJMETHOD(channel_setspeed, emurchan_setspeed),
953 KOBJMETHOD(channel_setblocksize, emurchan_setblocksize),
954 KOBJMETHOD(channel_trigger, emurchan_trigger),
955 KOBJMETHOD(channel_getptr, emurchan_getptr),
956 KOBJMETHOD(channel_getcaps, emurchan_getcaps),
957 { 0, 0 }
958};
959CHANNEL_DECLARE(emurchan);
960
961/* -------------------------------------------------------------------- */
962/* The interrupt handler */
963static void
964emu_intr(void *p)
965{
966 struct sc_info *sc = (struct sc_info *)p;
967 u_int32_t stat, ack, i, x;
968
969 while (1) {
970 stat = emu_rd(sc, IPR, 4);
971 if (stat == 0)
972 break;
973 ack = 0;
974
975 /* process irq */
976 if (stat & IPR_INTERVALTIMER) {
977 ack |= IPR_INTERVALTIMER;
978 x = 0;
979 for (i = 0; i < EMU_CHANS; i++) {
980 if (sc->pch[i].run) {
981 x = 1;
982 chn_intr(sc->pch[i].channel);
983 }
984 }
985 if (x == 0)
986 emu_enatimer(sc, 0);
987 }
988
989
990 if (stat & (IPR_ADCBUFFULL | IPR_ADCBUFHALFFULL)) {
991 ack |= stat & (IPR_ADCBUFFULL | IPR_ADCBUFHALFFULL);
992 if (sc->rch[0].channel)
993 chn_intr(sc->rch[0].channel);
994 }
995 if (stat & (IPR_EFXBUFFULL | IPR_EFXBUFHALFFULL)) {
996 ack |= stat & (IPR_EFXBUFFULL | IPR_EFXBUFHALFFULL);
997 if (sc->rch[1].channel)
998 chn_intr(sc->rch[1].channel);
999 }
1000 if (stat & (IPR_MICBUFFULL | IPR_MICBUFHALFFULL)) {
1001 ack |= stat & (IPR_MICBUFFULL | IPR_MICBUFHALFFULL);
1002 if (sc->rch[2].channel)
1003 chn_intr(sc->rch[2].channel);
1004 }
1005 if (stat & IPR_PCIERROR) {
1006 ack |= IPR_PCIERROR;
1007 device_printf(sc->dev, "pci error\n");
1008 /* we still get an nmi with ecc ram even if we ack this */
1009 }
1010 if (stat & IPR_SAMPLERATETRACKER) {
1011 ack |= IPR_SAMPLERATETRACKER;
1012 /* device_printf(sc->dev, "sample rate tracker lock status change\n"); */
1013 }
1014
1015 if (stat & ~ack)
1016 device_printf(sc->dev, "dodgy irq: %x (harmless)\n", stat & ~ack);
1017
1018 emu_wr(sc, IPR, stat, 4);
1019 }
1020}
1021
1022/* -------------------------------------------------------------------- */
1023
1024static void
1025emu_setmap(void *arg, bus_dma_segment_t *segs, int nseg, int error)
1026{
1027 bus_addr_t *phys = arg;
1028
1029 *phys = error ? 0 : (bus_addr_t)segs->ds_addr;
1030
1031 if (bootverbose) {
1032 printf("emu: setmap (%lx, %lx), nseg=%d, error=%d\n",
1033 (unsigned long)segs->ds_addr, (unsigned long)segs->ds_len,
1034 nseg, error);
1035 }
1036}
1037
1038static void *
1039emu_malloc(struct sc_info *sc, u_int32_t sz, bus_addr_t *addr)
1040{
1041 void *buf;
1042 bus_dmamap_t map;
1043
1044 *addr = 0;
1045 if (bus_dmamem_alloc(sc->parent_dmat, &buf, BUS_DMA_NOWAIT, &map))
1046 return NULL;
1047 if (bus_dmamap_load(sc->parent_dmat, map, buf, sz, emu_setmap, addr, 0)
1048 || !*addr)
1049 return NULL;
1050 return buf;
1051}
1052
1053static void
1054emu_free(struct sc_info *sc, void *buf)
1055{
1056 bus_dmamem_free(sc->parent_dmat, buf, NULL);
1057}
1058
1059static void *
1060emu_memalloc(struct sc_info *sc, u_int32_t sz, bus_addr_t *addr)
1061{
1062 u_int32_t blksz, start, idx, ofs, tmp, found;
1063 struct emu_mem *mem = &sc->mem;
1064 struct emu_memblk *blk;
1065 void *buf;
1066
1067 blksz = sz / EMUPAGESIZE;
1068 if (sz > (blksz * EMUPAGESIZE))
1069 blksz++;
1070 /* find a free block in the bitmap */
1071 found = 0;
1072 start = 1;
1073 while (!found && start + blksz < MAXPAGES) {
1074 found = 1;
1075 for (idx = start; idx < start + blksz; idx++)
1076 if (mem->bmap[idx >> 3] & (1 << (idx & 7)))
1077 found = 0;
1078 if (!found)
1079 start++;
1080 }
1081 if (!found)
1082 return NULL;
1083 blk = malloc(sizeof(*blk), M_DEVBUF, M_NOWAIT);
1084 if (blk == NULL)
1085 return NULL;
1086 buf = emu_malloc(sc, sz, &blk->buf_addr);
1087 *addr = blk->buf_addr;
1088 if (buf == NULL) {
1089 free(blk, M_DEVBUF);
1090 return NULL;
1091 }
1092 blk->buf = buf;
1093 blk->pte_start = start;
1094 blk->pte_size = blksz;
1095 /* printf("buf %p, pte_start %d, pte_size %d\n", blk->buf, blk->pte_start, blk->pte_size); */
1096 ofs = 0;
1097 for (idx = start; idx < start + blksz; idx++) {
1098 mem->bmap[idx >> 3] |= 1 << (idx & 7);
1099 tmp = (u_int32_t)(u_long)((u_int8_t *)blk->buf_addr + ofs);
1100 /* printf("pte[%d] -> %x phys, %x virt\n", idx, tmp, ((u_int32_t)buf) + ofs); */
1101 mem->ptb_pages[idx] = (tmp << 1) | idx;
1102 ofs += EMUPAGESIZE;
1103 }
1104 SLIST_INSERT_HEAD(&mem->blocks, blk, link);
1105 return buf;
1106}
1107
1108static int
1109emu_memfree(struct sc_info *sc, void *buf)
1110{
1111 u_int32_t idx, tmp;
1112 struct emu_mem *mem = &sc->mem;
1113 struct emu_memblk *blk, *i;
1114
1115 blk = NULL;
1116 SLIST_FOREACH(i, &mem->blocks, link) {
1117 if (i->buf == buf)
1118 blk = i;
1119 }
1120 if (blk == NULL)
1121 return EINVAL;
1122 SLIST_REMOVE(&mem->blocks, blk, emu_memblk, link);
1123 emu_free(sc, buf);
1124 tmp = (u_int32_t)(sc->mem.silent_page_addr) << 1;
1125 for (idx = blk->pte_start; idx < blk->pte_start + blk->pte_size; idx++) {
1126 mem->bmap[idx >> 3] &= ~(1 << (idx & 7));
1127 mem->ptb_pages[idx] = tmp | idx;
1128 }
1129 free(blk, M_DEVBUF);
1130 return 0;
1131}
1132
1133static int
1134emu_memstart(struct sc_info *sc, void *buf)
1135{
1136 struct emu_mem *mem = &sc->mem;
1137 struct emu_memblk *blk, *i;
1138
1139 blk = NULL;
1140 SLIST_FOREACH(i, &mem->blocks, link) {
1141 if (i->buf == buf)
1142 blk = i;
1143 }
1144 if (blk == NULL)
1145 return -EINVAL;
1146 return blk->pte_start;
1147}
1148
1149static void
1150emu_addefxop(struct sc_info *sc, int op, int z, int w, int x, int y, u_int32_t *pc)
1151{
1152 emu_wrefx(sc, (*pc) * 2, (x << 10) | y);
1153 emu_wrefx(sc, (*pc) * 2 + 1, (op << 20) | (z << 10) | w);
1154 (*pc)++;
1155}
1156
1157static void
1158emu_initefx(struct sc_info *sc)
1159{
1160 int i;
1161 u_int32_t pc = 16;
1162
1163 for (i = 0; i < 512; i++) {
1164 emu_wrefx(sc, i * 2, 0x10040);
1165 emu_wrefx(sc, i * 2 + 1, 0x610040);
1166 }
1167
1168 for (i = 0; i < 256; i++)
1169 emu_wrptr(sc, 0, FXGPREGBASE + i, 0);
1170
1171 /* FX-8010 DSP Registers:
1172 FX Bus
1173 0x000-0x00f : 16 registers
1174 Input
1175 0x010/0x011 : AC97 Codec (l/r)
1176 0x012/0x013 : ADC, S/PDIF (l/r)
1177 0x014/0x015 : Mic(left), Zoom (l/r)
1178 0x016/0x017 : APS S/PDIF?? (l/r)
1179 Output
1180 0x020/0x021 : AC97 Output (l/r)
1181 0x022/0x023 : TOS link out (l/r)
1182 0x024/0x025 : ??? (l/r)
1183 0x026/0x027 : LiveDrive Headphone (l/r)
1184 0x028/0x029 : Rear Channel (l/r)
1185 0x02a/0x02b : ADC Recording Buffer (l/r)
1186 Constants
1187 0x040 - 0x044 = 0 - 4
1188 0x045 = 0x8, 0x046 = 0x10, 0x047 = 0x20
1189 0x048 = 0x100, 0x049 = 0x10000, 0x04a = 0x80000
1190 0x04b = 0x10000000, 0x04c = 0x20000000, 0x04d = 0x40000000
1191 0x04e = 0x80000000, 0x04f = 0x7fffffff
1192 Temporary Values
1193 0x056 : Accumulator
1194 0x058 : Noise source?
1195 0x059 : Noise source?
1196 General Purpose Registers
1197 0x100 - 0x1ff
1198 Tank Memory Data Registers
1199 0x200 - 0x2ff
1200 Tank Memory Address Registers
1201 0x300 - 0x3ff
1202 */
1203
1204 /* Operators:
1205 0 : z := w + (x * y >> 31)
1206 4 : z := w + x * y
1207 6 : z := w + x + y
1208 */
1209
1210 /* Routing - this will be configurable in later version */
1211
1212 /* GPR[0/1] = FX * 4 + SPDIF-in */
1213 emu_addefxop(sc, 4, 0x100, 0x12, 0, 0x44, &pc);
1214 emu_addefxop(sc, 4, 0x101, 0x13, 1, 0x44, &pc);
1215 /* GPR[0/1] += APS-input */
1216 emu_addefxop(sc, 6, 0x100, 0x100, 0x40, sc->APS ? 0x16 : 0x40, &pc);
1217 emu_addefxop(sc, 6, 0x101, 0x101, 0x40, sc->APS ? 0x17 : 0x40, &pc);
1218 /* FrontOut (AC97) = GPR[0/1] */
1219 emu_addefxop(sc, 6, 0x20, 0x40, 0x40, 0x100, &pc);
1220 emu_addefxop(sc, 6, 0x21, 0x40, 0x41, 0x101, &pc);
1221 /* RearOut = (GPR[0/1] * RearVolume) >> 31 */
1222 /* RearVolume = GRP[0x10/0x11] */
1223 emu_addefxop(sc, 0, 0x28, 0x40, 0x110, 0x100, &pc);
1224 emu_addefxop(sc, 0, 0x29, 0x40, 0x111, 0x101, &pc);
1225 /* TOS out = GPR[0/1] */
1226 emu_addefxop(sc, 6, 0x22, 0x40, 0x40, 0x100, &pc);
1227 emu_addefxop(sc, 6, 0x23, 0x40, 0x40, 0x101, &pc);
1228 /* Mute Out2 */
1229 emu_addefxop(sc, 6, 0x24, 0x40, 0x40, 0x40, &pc);
1230 emu_addefxop(sc, 6, 0x25, 0x40, 0x40, 0x40, &pc);
1231 /* Mute Out3 */
1232 emu_addefxop(sc, 6, 0x26, 0x40, 0x40, 0x40, &pc);
1233 emu_addefxop(sc, 6, 0x27, 0x40, 0x40, 0x40, &pc);
1234 /* Input0 (AC97) -> Record */
1235 emu_addefxop(sc, 6, 0x2a, 0x40, 0x40, 0x10, &pc);
1236 emu_addefxop(sc, 6, 0x2b, 0x40, 0x40, 0x11, &pc);
1237
1238 emu_wrptr(sc, 0, DBG, 0);
1239}
1240
1241/* Probe and attach the card */
1242static int
1243emu_init(struct sc_info *sc)
1244{
1245 u_int32_t spcs, ch, tmp, i;
1246
1247 /* disable audio and lock cache */
1248 emu_wr(sc, HCFG, HCFG_LOCKSOUNDCACHE | HCFG_LOCKTANKCACHE_MASK | HCFG_MUTEBUTTONENABLE, 4);
1249
1250 /* reset recording buffers */
1251 emu_wrptr(sc, 0, MICBS, ADCBS_BUFSIZE_NONE);
1252 emu_wrptr(sc, 0, MICBA, 0);
1253 emu_wrptr(sc, 0, FXBS, ADCBS_BUFSIZE_NONE);
1254 emu_wrptr(sc, 0, FXBA, 0);
1255 emu_wrptr(sc, 0, ADCBS, ADCBS_BUFSIZE_NONE);
1256 emu_wrptr(sc, 0, ADCBA, 0);
1257
1258 /* disable channel interrupt */
1259 emu_wr(sc, INTE, INTE_INTERVALTIMERENB | INTE_SAMPLERATETRACKER | INTE_PCIERRORENABLE, 4);
1260 emu_wrptr(sc, 0, CLIEL, 0);
1261 emu_wrptr(sc, 0, CLIEH, 0);
1262 emu_wrptr(sc, 0, SOLEL, 0);
1263 emu_wrptr(sc, 0, SOLEH, 0);
1264
1265 /* init envelope engine */
1266 for (ch = 0; ch < NUM_G; ch++) {
1267 emu_wrptr(sc, ch, DCYSUSV, ENV_OFF);
1268 emu_wrptr(sc, ch, IP, 0);
1269 emu_wrptr(sc, ch, VTFT, 0xffff);
1270 emu_wrptr(sc, ch, CVCF, 0xffff);
1271 emu_wrptr(sc, ch, PTRX, 0);
1272 emu_wrptr(sc, ch, CPF, 0);
1273 emu_wrptr(sc, ch, CCR, 0);
1274
1275 emu_wrptr(sc, ch, PSST, 0);
1276 emu_wrptr(sc, ch, DSL, 0x10);
1277 emu_wrptr(sc, ch, CCCA, 0);
1278 emu_wrptr(sc, ch, Z1, 0);
1279 emu_wrptr(sc, ch, Z2, 0);
1280 emu_wrptr(sc, ch, FXRT, 0xd01c0000);
1281
1282 emu_wrptr(sc, ch, ATKHLDM, 0);
1283 emu_wrptr(sc, ch, DCYSUSM, 0);
1284 emu_wrptr(sc, ch, IFATN, 0xffff);
1285 emu_wrptr(sc, ch, PEFE, 0);
1286 emu_wrptr(sc, ch, FMMOD, 0);
1287 emu_wrptr(sc, ch, TREMFRQ, 24); /* 1 Hz */
1288 emu_wrptr(sc, ch, FM2FRQ2, 24); /* 1 Hz */
1289 emu_wrptr(sc, ch, TEMPENV, 0);
1290
1291 /*** these are last so OFF prevents writing ***/
1292 emu_wrptr(sc, ch, LFOVAL2, 0);
1293 emu_wrptr(sc, ch, LFOVAL1, 0);
1294 emu_wrptr(sc, ch, ATKHLDV, 0);
1295 emu_wrptr(sc, ch, ENVVOL, 0);
1296 emu_wrptr(sc, ch, ENVVAL, 0);
1297
1298 sc->voice[ch].vnum = ch;
1299 sc->voice[ch].slave = NULL;
1300 sc->voice[ch].busy = 0;
1301 sc->voice[ch].ismaster = 0;
1302 sc->voice[ch].running = 0;
1303 sc->voice[ch].b16 = 0;
1304 sc->voice[ch].stereo = 0;
1305 sc->voice[ch].speed = 0;
1306 sc->voice[ch].start = 0;
1307 sc->voice[ch].end = 0;
1308 sc->voice[ch].channel = NULL;
1309 }
1310 sc->pnum = sc->rnum = 0;
1311
1312 /*
1313 * Init to 0x02109204 :
1314 * Clock accuracy = 0 (1000ppm)
1315 * Sample Rate = 2 (48kHz)
1316 * Audio Channel = 1 (Left of 2)
1317 * Source Number = 0 (Unspecified)
1318 * Generation Status = 1 (Original for Cat Code 12)
1319 * Cat Code = 12 (Digital Signal Mixer)
1320 * Mode = 0 (Mode 0)
1321 * Emphasis = 0 (None)
1322 * CP = 1 (Copyright unasserted)
1323 * AN = 0 (Audio data)
1324 * P = 0 (Consumer)
1325 */
1326 spcs = SPCS_CLKACCY_1000PPM | SPCS_SAMPLERATE_48 |
1327 SPCS_CHANNELNUM_LEFT | SPCS_SOURCENUM_UNSPEC |
1328 SPCS_GENERATIONSTATUS | 0x00001200 | 0x00000000 |
1329 SPCS_EMPHASIS_NONE | SPCS_COPYRIGHT;
1330 emu_wrptr(sc, 0, SPCS0, spcs);
1331 emu_wrptr(sc, 0, SPCS1, spcs);
1332 emu_wrptr(sc, 0, SPCS2, spcs);
1333
1334 emu_initefx(sc);
1335
1336 SLIST_INIT(&sc->mem.blocks);
1337 sc->mem.ptb_pages = emu_malloc(sc, MAXPAGES * sizeof(u_int32_t), &sc->mem.ptb_pages_addr);
1338 if (sc->mem.ptb_pages == NULL)
1339 return -1;
1340
1341 sc->mem.silent_page = emu_malloc(sc, EMUPAGESIZE, &sc->mem.silent_page_addr);
1342 if (sc->mem.silent_page == NULL) {
1343 emu_free(sc, sc->mem.ptb_pages);
1344 return -1;
1345 }
1346 /* Clear page with silence & setup all pointers to this page */
1347 bzero(sc->mem.silent_page, EMUPAGESIZE);
1348 tmp = (u_int32_t)(sc->mem.silent_page_addr) << 1;
1349 for (i = 0; i < MAXPAGES; i++)
1350 sc->mem.ptb_pages[i] = tmp | i;
1351
1352 emu_wrptr(sc, 0, PTB, (sc->mem.ptb_pages_addr));
1353 emu_wrptr(sc, 0, TCB, 0); /* taken from original driver */
1354 emu_wrptr(sc, 0, TCBS, 0); /* taken from original driver */
1355
1356 for (ch = 0; ch < NUM_G; ch++) {
1357 emu_wrptr(sc, ch, MAPA, tmp | MAP_PTI_MASK);
1358 emu_wrptr(sc, ch, MAPB, tmp | MAP_PTI_MASK);
1359 }
1360
1361 /* emu_memalloc(sc, EMUPAGESIZE); */
1362 /*
1363 * Hokay, now enable the AUD bit
1364 * Enable Audio = 1
1365 * Mute Disable Audio = 0
1366 * Lock Tank Memory = 1
1367 * Lock Sound Memory = 0
1368 * Auto Mute = 1
1369 */
1370 tmp = HCFG_AUDIOENABLE | HCFG_LOCKTANKCACHE_MASK | HCFG_AUTOMUTE;
1371 if (sc->rev >= 6)
1372 tmp |= HCFG_JOYENABLE;
1373 emu_wr(sc, HCFG, tmp, 4);
1374
1375 /* TOSLink detection */
1376 sc->tos_link = 0;
1377 tmp = emu_rd(sc, HCFG, 4);
1378 if (tmp & (HCFG_GPINPUT0 | HCFG_GPINPUT1)) {
1379 emu_wr(sc, HCFG, tmp | 0x800, 4);
1380 DELAY(50);
1381 if (tmp != (emu_rd(sc, HCFG, 4) & ~0x800)) {
1382 sc->tos_link = 1;
1383 emu_wr(sc, HCFG, tmp, 4);
1384 }
1385 }
1386
1387 return 0;
1388}
1389
1390static int
1391emu_uninit(struct sc_info *sc)
1392{
1393 u_int32_t ch;
1394
1395 emu_wr(sc, INTE, 0, 4);
1396 for (ch = 0; ch < NUM_G; ch++)
1397 emu_wrptr(sc, ch, DCYSUSV, ENV_OFF);
1398 for (ch = 0; ch < NUM_G; ch++) {
1399 emu_wrptr(sc, ch, VTFT, 0);
1400 emu_wrptr(sc, ch, CVCF, 0);
1401 emu_wrptr(sc, ch, PTRX, 0);
1402 emu_wrptr(sc, ch, CPF, 0);
1403 }
1404
1405 /* disable audio and lock cache */
1406 emu_wr(sc, HCFG, HCFG_LOCKSOUNDCACHE | HCFG_LOCKTANKCACHE_MASK | HCFG_MUTEBUTTONENABLE, 4);
1407
1408 emu_wrptr(sc, 0, PTB, 0);
1409 /* reset recording buffers */
1410 emu_wrptr(sc, 0, MICBS, ADCBS_BUFSIZE_NONE);
1411 emu_wrptr(sc, 0, MICBA, 0);
1412 emu_wrptr(sc, 0, FXBS, ADCBS_BUFSIZE_NONE);
1413 emu_wrptr(sc, 0, FXBA, 0);
1414 emu_wrptr(sc, 0, FXWC, 0);
1415 emu_wrptr(sc, 0, ADCBS, ADCBS_BUFSIZE_NONE);
1416 emu_wrptr(sc, 0, ADCBA, 0);
1417 emu_wrptr(sc, 0, TCB, 0);
1418 emu_wrptr(sc, 0, TCBS, 0);
1419
1420 /* disable channel interrupt */
1421 emu_wrptr(sc, 0, CLIEL, 0);
1422 emu_wrptr(sc, 0, CLIEH, 0);
1423 emu_wrptr(sc, 0, SOLEL, 0);
1424 emu_wrptr(sc, 0, SOLEH, 0);
1425
1426 /* init envelope engine */
1427 if (!SLIST_EMPTY(&sc->mem.blocks))
1428 device_printf(sc->dev, "warning: memblock list not empty\n");
1429 emu_free(sc, sc->mem.ptb_pages);
1430 emu_free(sc, sc->mem.silent_page);
1431
1432 return 0;
1433}
1434
1435static int
1436emu_pci_probe(device_t dev)
1437{
1438 char *s = NULL;
1439
1440 switch (pci_get_devid(dev)) {
1441 case EMU10K1_PCI_ID:
1442 s = "Creative EMU10K1";
1443 break;
1444/*
1445 case EMU10K2_PCI_ID:
1446 s = "Creative EMU10K2";
1447 break;
1448*/
1449 default:
1450 return ENXIO;
1451 }
1452
1453 device_set_desc(dev, s);
1454 return 0;
1455}
1456
1457static int
1458emu_pci_attach(device_t dev)
1459{
1460 struct ac97_info *codec = NULL;
1461 struct sc_info *sc;
1462 u_int32_t data;
1463 int i, gotmic;
1464 char status[SND_STATUSLEN];
1465
1466 if ((sc = malloc(sizeof(*sc), M_DEVBUF, M_WAITOK | M_ZERO)) == NULL) {
1467 device_printf(dev, "cannot allocate softc\n");
1468 return ENXIO;
1469 }
1470
1471 sc->lock = snd_mtxcreate(device_get_nameunit(dev), "sound softc");
1472 sc->dev = dev;
1473 sc->type = pci_get_devid(dev);
1474 sc->rev = pci_get_revid(dev);
1475
1476 data = pci_read_config(dev, PCIR_COMMAND, 2);
1477 data |= (PCIM_CMD_PORTEN | PCIM_CMD_BUSMASTEREN);
1478 pci_write_config(dev, PCIR_COMMAND, data, 2);
1479 data = pci_read_config(dev, PCIR_COMMAND, 2);
1480
1481 i = PCIR_BAR(0);
1482 sc->reg = bus_alloc_resource(dev, SYS_RES_IOPORT, &i, 0, ~0, 1, RF_ACTIVE);
1483 if (sc->reg == NULL) {
1484 device_printf(dev, "unable to map register space\n");
1485 goto bad;
1486 }
1487 sc->st = rman_get_bustag(sc->reg);
1488 sc->sh = rman_get_bushandle(sc->reg);
1489
1490 sc->bufsz = pcm_getbuffersize(dev, 4096, EMU_DEFAULT_BUFSZ, 65536);
1491
1492 if (bus_dma_tag_create(/*parent*/NULL, /*alignment*/2, /*boundary*/0,
1493 /*lowaddr*/1 << 31, /* can only access 0-2gb */
1494 /*highaddr*/BUS_SPACE_MAXADDR,
1495 /*filter*/NULL, /*filterarg*/NULL,
1496 /*maxsize*/sc->bufsz, /*nsegments*/1, /*maxsegz*/0x3ffff,
1497 /*flags*/0, /*lockfunc*/busdma_lock_mutex,
1498 /*lockarg*/&Giant, &sc->parent_dmat) != 0) {
1499 device_printf(dev, "unable to create dma tag\n");
1500 goto bad;
1501 }
1502
1503 if (emu_init(sc) == -1) {
1504 device_printf(dev, "unable to initialize the card\n");
1505 goto bad;
1506 }
1507
1508 codec = AC97_CREATE(dev, sc, emu_ac97);
1509 if (codec == NULL) goto bad;
1510 gotmic = (ac97_getcaps(codec) & AC97_CAP_MICCHANNEL) ? 1 : 0;
1511 if (mixer_init(dev, ac97_getmixerclass(), codec) == -1) goto bad;
1512
1513 i = 0;
1514 sc->irq = bus_alloc_resource(dev, SYS_RES_IRQ, &i, 0, ~0, 1, RF_ACTIVE | RF_SHAREABLE);
1515 if (!sc->irq || snd_setup_intr(dev, sc->irq, INTR_MPSAFE, emu_intr, sc, &sc->ih)) {
1516 device_printf(dev, "unable to map interrupt\n");
1517 goto bad;
1518 }
1519
1520 snprintf(status, SND_STATUSLEN, "at io 0x%lx irq %ld", rman_get_start(sc->reg), rman_get_start(sc->irq));
1521
1522 if (pcm_register(dev, sc, EMU_CHANS, gotmic ? 3 : 2)) goto bad;
1523 for (i = 0; i < EMU_CHANS; i++)
1524 pcm_addchan(dev, PCMDIR_PLAY, &emupchan_class, sc);
1525 for (i = 0; i < (gotmic ? 3 : 2); i++)
1526 pcm_addchan(dev, PCMDIR_REC, &emurchan_class, sc);
1527
1528 pcm_setstatus(dev, status);
1529
1530 return 0;
1531
1532bad:
1533 if (codec) ac97_destroy(codec);
1534 if (sc->reg) bus_release_resource(dev, SYS_RES_IOPORT, PCIR_BAR(0), sc->reg);
1535 if (sc->ih) bus_teardown_intr(dev, sc->irq, sc->ih);
1536 if (sc->irq) bus_release_resource(dev, SYS_RES_IRQ, 0, sc->irq);
1537 if (sc->parent_dmat) bus_dma_tag_destroy(sc->parent_dmat);
1538 if (sc->lock) snd_mtxfree(sc->lock);
1539 free(sc, M_DEVBUF);
1540 return ENXIO;
1541}
1542
1543static int
1544emu_pci_detach(device_t dev)
1545{
1546 int r;
1547 struct sc_info *sc;
1548
1549 r = pcm_unregister(dev);
1550 if (r)
1551 return r;
1552
1553 sc = pcm_getdevinfo(dev);
1554 /* shutdown chip */
1555 emu_uninit(sc);
1556
1557 bus_release_resource(dev, SYS_RES_IOPORT, PCIR_BAR(0), sc->reg);
1558 bus_teardown_intr(dev, sc->irq, sc->ih);
1559 bus_release_resource(dev, SYS_RES_IRQ, 0, sc->irq);
1560 bus_dma_tag_destroy(sc->parent_dmat);
1561 snd_mtxfree(sc->lock);
1562 free(sc, M_DEVBUF);
1563
1564 return 0;
1565}
1566
1567/* add suspend, resume */
1568static device_method_t emu_methods[] = {
1569 /* Device interface */
1570 DEVMETHOD(device_probe, emu_pci_probe),
1571 DEVMETHOD(device_attach, emu_pci_attach),
1572 DEVMETHOD(device_detach, emu_pci_detach),
1573
1574 { 0, 0 }
1575};
1576
1577static driver_t emu_driver = {
1578 "pcm",
1579 emu_methods,
1580 PCM_SOFTC_SIZE,
1581};
1582
1583DRIVER_MODULE(snd_emu10k1, pci, emu_driver, pcm_devclass, 0, 0);
1584MODULE_DEPEND(snd_emu10k1, snd_pcm, PCM_MINVER, PCM_PREFVER, PCM_MAXVER);
1585MODULE_VERSION(snd_emu10k1, 1);
1586
1587/* dummy driver to silence the joystick device */
1588static int
1589emujoy_pci_probe(device_t dev)
1590{
1591 char *s = NULL;
1592
1593 switch (pci_get_devid(dev)) {
1594 case 0x70021102:
1595 s = "Creative EMU10K1 Joystick";
1596 device_quiet(dev);
1597 break;
1598 case 0x70031102:
1599 s = "Creative EMU10K2 Joystick";
1600 device_quiet(dev);
1601 break;
1602 }
1603
1604 if (s) device_set_desc(dev, s);
1605 return s ? -1000 : ENXIO;
1606}
1607
1608static int
1609emujoy_pci_attach(device_t dev)
1610{
1611 return 0;
1612}
1613
1614static int
1615emujoy_pci_detach(device_t dev)
1616{
1617 return 0;
1618}
1619
1620static device_method_t emujoy_methods[] = {
1621 DEVMETHOD(device_probe, emujoy_pci_probe),
1622 DEVMETHOD(device_attach, emujoy_pci_attach),
1623 DEVMETHOD(device_detach, emujoy_pci_detach),
1624
1625 { 0, 0 }
1626};
1627
1628static driver_t emujoy_driver = {
1629 "emujoy",
1630 emujoy_methods,
1631 8,
1632};
1633
1634static devclass_t emujoy_devclass;
1635
1636DRIVER_MODULE(emujoy, pci, emujoy_driver, emujoy_devclass, 0, 0);
1637