Annotation of sys/dev/pci/emuxki.c, Revision 1.1.1.1
1.1 nbrk 1: /* $OpenBSD: emuxki.c,v 1.24 2007/07/10 22:04:28 jakemsr Exp $ */
2: /* $NetBSD: emuxki.c,v 1.1 2001/10/17 18:39:41 jdolecek Exp $ */
3:
4: /*-
5: * Copyright (c) 2001 The NetBSD Foundation, Inc.
6: * All rights reserved.
7: *
8: * This code is derived from software contributed to The NetBSD Foundation
9: * by Yannick Montulet.
10: *
11: * Redistribution and use in source and binary forms, with or without
12: * modification, are permitted provided that the following conditions
13: * are met:
14: * 1. Redistributions of source code must retain the above copyright
15: * notice, this list of conditions and the following disclaimer.
16: * 2. Redistributions in binary form must reproduce the above copyright
17: * notice, this list of conditions and the following disclaimer in the
18: * documentation and/or other materials provided with the distribution.
19: * 3. All advertising materials mentioning features or use of this software
20: * must display the following acknowledgement:
21: * This product includes software developed by the NetBSD
22: * Foundation, Inc. and its contributors.
23: * 4. Neither the name of The NetBSD Foundation nor the names of its
24: * contributors may be used to endorse or promote products derived
25: * from this software without specific prior written permission.
26: *
27: * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
28: * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
29: * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
30: * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
31: * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
32: * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
33: * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
34: * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
35: * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
36: * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
37: * POSSIBILITY OF SUCH DAMAGE.
38: */
39:
40: /*
41: * Driver for Creative Labs SBLive! series and probably PCI512.
42: *
43: * Known bugs:
44: * - inversed stereo at ac97 codec level
45: * (XXX jdolecek - don't see the problem? maybe because auvia(4) has
46: * it swapped too?)
47: * - bass disappear when you plug rear jack-in on Cambridge FPS2000 speakers
48: * (and presumably all speakers that support front and rear jack-in)
49: *
50: * TODO:
51: * - Digital Outputs
52: * - (midi/mpu),joystick support
53: * - Multiple voices play (problem with /dev/audio architecture)
54: * - Multiple sources recording (Pb with audio(4))
55: * - Independent modification of each channel's parameters (via mixer ?)
56: * - DSP FX patches (to make fx like chipmunk)
57: */
58:
59: #include <sys/types.h>
60: #include <sys/device.h>
61: #include <sys/errno.h>
62: #include <sys/malloc.h>
63: #include <sys/systm.h>
64: #include <sys/param.h>
65: #include <sys/audioio.h>
66: #include <sys/selinfo.h>
67:
68: #include <dev/pci/pcireg.h>
69: #include <dev/pci/pcivar.h>
70: #include <dev/pci/pcidevs.h>
71:
72: #include <dev/audio_if.h>
73: #include <dev/audiovar.h>
74: #include <dev/auconv.h>
75: #include <dev/mulaw.h>
76: #include <dev/ic/ac97.h>
77:
78: #include <dev/pci/emuxkireg.h>
79: #include <dev/pci/emuxkivar.h>
80:
81: #define slinear16_to_ulinear8_le linear16_to_ulinear8_le;
82:
83: /* autconf goo */
84: int emuxki_match(struct device *, void *, void *);
85: void emuxki_attach(struct device *, struct device *, void *);
86: int emuxki_detach(struct device *, int);
87: int emuxki_scinit(struct emuxki_softc *sc);
88: void emuxki_pci_shutdown(struct emuxki_softc *sc);
89:
90: /* dma mem mgmt */
91: struct dmamem *emuxki_dmamem_alloc(bus_dma_tag_t, size_t, bus_size_t,
92: int, int, int);
93: void emuxki_dmamem_free(struct dmamem *, int);
94: void emuxki_dmamem_delete(struct dmamem *mem, int type);
95:
96: struct emuxki_mem *emuxki_mem_new(struct emuxki_softc *sc, int ptbidx,
97: size_t size, int type, int flags);
98: void emuxki_mem_delete(struct emuxki_mem *mem, int type);
99:
100: /* Emu10k1 init & shutdown */
101: int emuxki_init(struct emuxki_softc *);
102: void emuxki_shutdown(struct emuxki_softc *);
103:
104: /* Emu10k1 mem mgmt */
105: void *emuxki_pmem_alloc(struct emuxki_softc *, size_t,int,int);
106: void *emuxki_rmem_alloc(struct emuxki_softc *, size_t,int,int);
107:
108: /*
109: * Emu10k1 channels funcs : There is no direct access to channels, everything
110: * is done through voices I will at least provide channel based fx params
111: * modification, later...
112: */
113:
114: /* Emu10k1 voice mgmt */
115: struct emuxki_voice *emuxki_voice_new(struct emuxki_softc *, u_int8_t);
116: void emuxki_voice_delete(struct emuxki_voice *);
117: int emuxki_voice_set_audioparms(struct emuxki_voice *, u_int8_t, u_int8_t, u_int32_t);
118: /* emuxki_voice_set_fxparms will come later, it'll need channel distinction */
119: int emuxki_voice_set_bufparms(struct emuxki_voice *, void *, u_int32_t, u_int16_t);
120: int emuxki_voice_set_stereo(struct emuxki_voice *voice, u_int8_t stereo);
121: int emuxki_voice_dataloc_create(struct emuxki_voice *voice);
122: void emuxki_voice_dataloc_destroy(struct emuxki_voice *voice);
123: void emuxki_voice_commit_parms(struct emuxki_voice *);
124: void emuxki_voice_recsrc_release(struct emuxki_softc *sc, emuxki_recsrc_t source);
125: int emuxki_recsrc_reserve(struct emuxki_voice *voice, emuxki_recsrc_t source);
126: int emuxki_voice_adc_rate(struct emuxki_voice *);
127: u_int32_t emuxki_voice_curaddr(struct emuxki_voice *);
128: int emuxki_set_vparms(struct emuxki_voice *voice, struct audio_params *p);
129: int emuxki_voice_set_srate(struct emuxki_voice *voice, u_int32_t srate);
130: void emuxki_voice_start(struct emuxki_voice *, void (*) (void *), void *);
131: void emuxki_voice_halt(struct emuxki_voice *);
132: int emuxki_voice_channel_create(struct emuxki_voice *voice);
133: void emuxki_voice_channel_destroy(struct emuxki_voice *voice);
134:
135: struct emuxki_channel *emuxki_channel_new(struct emuxki_voice *voice, u_int8_t num);
136: void emuxki_channel_delete(struct emuxki_channel *chan);
137: void emuxki_channel_start(struct emuxki_channel *chan);
138: void emuxki_channel_stop(struct emuxki_channel *chan);
139: void emuxki_channel_commit_fx(struct emuxki_channel *chan);
140: void emuxki_channel_commit_parms(struct emuxki_channel *chan);
141: void emuxki_channel_set_bufparms(struct emuxki_channel *chan, u_int32_t start, u_int32_t end);
142: void emuxki_channel_set_srate(struct emuxki_channel *chan, u_int32_t srate);
143: void emuxki_channel_set_fxsend(struct emuxki_channel *chan,
144: struct emuxki_chanparms_fxsend *fxsend);
145: void emuxki_chanparms_set_defaults(struct emuxki_channel *chan);
146:
147: void emuxki_resched_timer(struct emuxki_softc *sc);
148:
149: /*
150: * Emu10k1 stream mgmt : not done yet
151: */
152: #if 0
153: struct emuxki_stream *emuxki_stream_new(struct emu10k1 *);
154: void emuxki_stream_delete(struct emuxki_stream *);
155: int emuxki_stream_set_audio_params(struct emuxki_stream *, u_int8_t,
156: u_int8_t, u_int8_t, u_int16_t);
157: void emuxki_stream_start(struct emuxki_stream *);
158: void emuxki_stream_halt(struct emuxki_stream *);
159: #endif
160:
161: /* fx interface */
162: void emuxki_initfx(struct emuxki_softc *sc);
163: void emuxki_dsp_addop(struct emuxki_softc *sc, u_int16_t *pc, u_int8_t op,
164: u_int16_t r, u_int16_t a, u_int16_t x, u_int16_t y);
165: void emuxki_write_micro(struct emuxki_softc *sc, u_int32_t pc, u_int32_t data);
166:
167: /* audio interface callbacks */
168:
169: int emuxki_open(void *, int);
170: void emuxki_close(void *);
171:
172: int emuxki_query_encoding(void *, struct audio_encoding *);
173: int emuxki_set_params(void *, int, int,
174: struct audio_params *,
175: struct audio_params *);
176:
177: int emuxki_round_blocksize(void *, int);
178: size_t emuxki_round_buffersize(void *, int, size_t);
179:
180: int emuxki_trigger_output(void *, void *, void *, int, void (*)(void *),
181: void *, struct audio_params *);
182: int emuxki_trigger_input(void *, void *, void *, int, void (*) (void *),
183: void *, struct audio_params *);
184: int emuxki_halt_output(void *);
185: int emuxki_halt_input(void *);
186:
187: int emuxki_getdev(void *, struct audio_device *);
188: int emuxki_set_port(void *, mixer_ctrl_t *);
189: int emuxki_get_port(void *, mixer_ctrl_t *);
190: int emuxki_query_devinfo(void *, mixer_devinfo_t *);
191:
192: void *emuxki_allocm(void *, int, size_t, int, int);
193: void emuxki_freem(void *, void *, int);
194:
195: paddr_t emuxki_mappage(void *, void *, off_t, int);
196: int emuxki_get_props(void *);
197:
198: /* Interrupt handler */
199: int emuxki_intr(void *);
200:
201: /* Emu10k1 AC97 interface callbacks */
202: int emuxki_ac97_init(struct emuxki_softc *sc);
203: int emuxki_ac97_attach(void *, struct ac97_codec_if *);
204: int emuxki_ac97_read(void *, u_int8_t, u_int16_t *);
205: int emuxki_ac97_write(void *, u_int8_t, u_int16_t);
206: void emuxki_ac97_reset(void *);
207:
208: const struct pci_matchid emuxki_devices[] = {
209: { PCI_VENDOR_CREATIVELABS, PCI_PRODUCT_CREATIVELABS_SBLIVE },
210: { PCI_VENDOR_CREATIVELABS, PCI_PRODUCT_CREATIVELABS_SBLIVE2 },
211: { PCI_VENDOR_CREATIVELABS, PCI_PRODUCT_CREATIVELABS_AUDIGY },
212: { PCI_VENDOR_CREATIVELABS, PCI_PRODUCT_CREATIVELABS_AUDIGY2 },
213: };
214:
215: /*
216: * Autoconfig goo.
217: */
218: struct cfdriver emu_cd = {
219: NULL, "emu", DV_DULL
220: };
221:
222: struct cfattach emu_ca = {
223: sizeof(struct emuxki_softc),
224: emuxki_match,
225: emuxki_attach,
226: emuxki_detach,
227: NULL /* config activate */
228: };
229:
230: struct audio_hw_if emuxki_hw_if = {
231: emuxki_open,
232: emuxki_close,
233: NULL, /* drain */
234: emuxki_query_encoding,
235: emuxki_set_params,
236: emuxki_round_blocksize,
237: NULL, /* commit settings */
238: NULL, /* init_output */
239: NULL, /* init_input */
240: NULL, /* start_output */
241: NULL, /* start_input */
242: emuxki_halt_output,
243: emuxki_halt_input,
244: NULL, /* speaker_ctl */
245: emuxki_getdev,
246: NULL, /* setfd */
247: emuxki_set_port,
248: emuxki_get_port,
249: emuxki_query_devinfo,
250: emuxki_allocm,
251: emuxki_freem,
252: emuxki_round_buffersize,
253: emuxki_mappage,
254: emuxki_get_props,
255: emuxki_trigger_output,
256: emuxki_trigger_input,
257: };
258:
259: #if 0
260: static const int emuxki_recsrc_intrmasks[EMU_NUMRECSRCS] =
261: { EMU_INTE_MICBUFENABLE, EMU_INTE_ADCBUFENABLE, EMU_INTE_EFXBUFENABLE };
262: #endif
263: static const u_int32_t emuxki_recsrc_bufaddrreg[EMU_NUMRECSRCS] =
264: { EMU_MICBA, EMU_ADCBA, EMU_FXBA };
265: static const u_int32_t emuxki_recsrc_szreg[EMU_NUMRECSRCS] =
266: { EMU_MICBS, EMU_ADCBS, EMU_FXBS };
267: static const int emuxki_recbuf_sz[] = {
268: 0, 384, 448, 512, 640, 768, 896, 1024, 1280, 1536, 1792,
269: 2048, 2560, 3072, 3584, 4096, 5120, 6144, 7168, 8192, 10240,
270: 12288, 14366, 16384, 20480, 24576, 28672, 32768, 40960, 49152,
271: 57344, 65536
272: };
273:
274: /*
275: * DMA memory mgmt
276: */
277:
278: void
279: emuxki_dmamem_delete(struct dmamem *mem, int type)
280: {
281: free(mem->segs, type);
282: free(mem, type);
283: }
284:
285: struct dmamem *
286: emuxki_dmamem_alloc(bus_dma_tag_t dmat, size_t size, bus_size_t align,
287: int nsegs, int type, int flags)
288: {
289: struct dmamem *mem;
290: int bus_dma_flags;
291:
292: /* Allocate memory for structure */
293: if ((mem = malloc(sizeof(*mem), type, flags)) == NULL)
294: return (NULL);
295: mem->dmat = dmat;
296: mem->size = size;
297: mem->align = align;
298: mem->nsegs = nsegs;
299: mem->bound = 0;
300:
301: mem->segs = malloc(mem->nsegs * sizeof(*(mem->segs)), type, flags);
302: if (mem->segs == NULL) {
303: free(mem, type);
304: return (NULL);
305: }
306:
307: bus_dma_flags = (flags & M_NOWAIT) ? BUS_DMA_NOWAIT : BUS_DMA_WAITOK;
308: if (bus_dmamem_alloc(dmat, mem->size, mem->align, mem->bound,
309: mem->segs, mem->nsegs, &(mem->rsegs),
310: bus_dma_flags)) {
311: emuxki_dmamem_delete(mem, type);
312: return (NULL);
313: }
314:
315: if (bus_dmamem_map(dmat, mem->segs, mem->nsegs, mem->size,
316: &(mem->kaddr), bus_dma_flags | BUS_DMA_COHERENT)) {
317: bus_dmamem_free(dmat, mem->segs, mem->nsegs);
318: emuxki_dmamem_delete(mem, type);
319: return (NULL);
320: }
321:
322: if (bus_dmamap_create(dmat, mem->size, mem->nsegs, mem->size,
323: mem->bound, bus_dma_flags, &(mem->map))) {
324: bus_dmamem_unmap(dmat, mem->kaddr, mem->size);
325: bus_dmamem_free(dmat, mem->segs, mem->nsegs);
326: emuxki_dmamem_delete(mem, type);
327: return (NULL);
328: }
329:
330: if (bus_dmamap_load(dmat, mem->map, mem->kaddr,
331: mem->size, NULL, bus_dma_flags)) {
332: bus_dmamap_destroy(dmat, mem->map);
333: bus_dmamem_unmap(dmat, mem->kaddr, mem->size);
334: bus_dmamem_free(dmat, mem->segs, mem->nsegs);
335: emuxki_dmamem_delete(mem, type);
336: return (NULL);
337: }
338:
339: return (mem);
340: }
341:
342: void
343: emuxki_dmamem_free(struct dmamem *mem, int type)
344: {
345: bus_dmamap_unload(mem->dmat, mem->map);
346: bus_dmamap_destroy(mem->dmat, mem->map);
347: bus_dmamem_unmap(mem->dmat, mem->kaddr, mem->size);
348: bus_dmamem_free(mem->dmat, mem->segs, mem->nsegs);
349: emuxki_dmamem_delete(mem, type);
350: }
351:
352:
353: /*
354: * Autoconf device callbacks : attach and detach
355: */
356:
357: void
358: emuxki_pci_shutdown(struct emuxki_softc *sc)
359: {
360: if (sc->sc_ih != NULL)
361: pci_intr_disestablish(sc->sc_pc, sc->sc_ih);
362: if (sc->sc_ios)
363: bus_space_unmap(sc->sc_iot, sc->sc_ioh, sc->sc_ios);
364: }
365:
366: int
367: emuxki_scinit(struct emuxki_softc *sc)
368: {
369: int err;
370:
371: bus_space_write_4(sc->sc_iot, sc->sc_ioh, EMU_HCFG,
372: /* enable spdif(?) output on non-APS */
373: (sc->sc_type == EMUXKI_APS? 0 : EMU_HCFG_GPOUTPUT0) |
374: EMU_HCFG_LOCKSOUNDCACHE | EMU_HCFG_LOCKTANKCACHE_MASK |
375: EMU_HCFG_MUTEBUTTONENABLE);
376: bus_space_write_4(sc->sc_iot, sc->sc_ioh, EMU_INTE,
377: EMU_INTE_SAMPLERATER | EMU_INTE_PCIERRENABLE);
378:
379: if ((err = emuxki_init(sc)))
380: return (err);
381:
382: if (sc->sc_type & EMUXKI_AUDIGY2) {
383: bus_space_write_4(sc->sc_iot, sc->sc_ioh, EMU_HCFG,
384: EMU_HCFG_AUDIOENABLE | EMU_HCFG_AC3ENABLE_CDSPDIF |
385: EMU_HCFG_AC3ENABLE_GPSPDIF | EMU_HCFG_AUTOMUTE);
386: } else if (sc->sc_type & EMUXKI_AUDIGY) {
387: bus_space_write_4(sc->sc_iot, sc->sc_ioh, EMU_HCFG,
388: EMU_HCFG_AUDIOENABLE | EMU_HCFG_AUTOMUTE);
389: } else {
390: bus_space_write_4(sc->sc_iot, sc->sc_ioh, EMU_HCFG,
391: EMU_HCFG_AUDIOENABLE | EMU_HCFG_JOYENABLE |
392: EMU_HCFG_LOCKTANKCACHE_MASK | EMU_HCFG_AUTOMUTE);
393: }
394: bus_space_write_4(sc->sc_iot, sc->sc_ioh, EMU_INTE,
395: bus_space_read_4(sc->sc_iot, sc->sc_ioh, EMU_INTE) |
396: EMU_INTE_VOLINCRENABLE | EMU_INTE_VOLDECRENABLE |
397: EMU_INTE_MUTEENABLE);
398:
399: if (sc->sc_type & EMUXKI_AUDIGY2) {
400: bus_space_write_4(sc->sc_iot, sc->sc_ioh, EMU_A_IOCFG,
401: EMU_A_IOCFG_GPOUT0 |
402: bus_space_read_4(sc->sc_iot, sc->sc_ioh, EMU_A_IOCFG));
403: }
404:
405: /* No multiple voice support for now */
406: sc->pvoice = sc->rvoice = NULL;
407:
408: return (0);
409: }
410:
411: int
412: emuxki_ac97_init(struct emuxki_softc *sc)
413: {
414: sc->hostif.arg = sc;
415: sc->hostif.attach = emuxki_ac97_attach;
416: sc->hostif.read = emuxki_ac97_read;
417: sc->hostif.write = emuxki_ac97_write;
418: sc->hostif.reset = emuxki_ac97_reset;
419: sc->hostif.flags = NULL;
420: return (ac97_attach(&(sc->hostif)));
421: }
422:
423: int
424: emuxki_match(struct device *parent, void *match, void *aux)
425: {
426: return (pci_matchbyid((struct pci_attach_args *)aux, emuxki_devices,
427: sizeof(emuxki_devices)/sizeof(emuxki_devices[0])));
428: }
429:
430: void
431: emuxki_attach(struct device *parent, struct device *self, void *aux)
432: {
433: struct emuxki_softc *sc = (struct emuxki_softc *) self;
434: struct pci_attach_args *pa = aux;
435: pci_intr_handle_t ih;
436: const char *intrstr;
437:
438: if (pci_mapreg_map(pa, EMU_PCI_CBIO, PCI_MAPREG_TYPE_IO, 0,
439: &(sc->sc_iot), &(sc->sc_ioh), &(sc->sc_iob), &(sc->sc_ios), 0)) {
440: printf(": can't map iospace\n");
441: return;
442: }
443:
444: sc->sc_pc = pa->pa_pc;
445: sc->sc_dmat = pa->pa_dmat;
446:
447: if (pci_intr_map(pa, &ih)) {
448: printf(": couldn't map interrupt\n");
449: bus_space_unmap(sc->sc_iot, sc->sc_ioh, sc->sc_ios);
450: return;
451: }
452:
453: intrstr = pci_intr_string(pa->pa_pc, ih);
454: sc->sc_ih = pci_intr_establish(pa->pa_pc, ih, IPL_AUDIO, emuxki_intr,
455: sc, sc->sc_dev.dv_xname);
456: if (sc->sc_ih == NULL) {
457: printf(": couldn't establish interrupt");
458: if (intrstr != NULL)
459: printf(" at %s", intrstr);
460: printf("\n");
461: bus_space_unmap(sc->sc_iot, sc->sc_ioh, sc->sc_ios);
462: return;
463: }
464: printf(": %s\n", intrstr);
465:
466: /* XXX it's unknown whether APS is made from Audigy as well */
467: if (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_CREATIVELABS_AUDIGY) {
468: sc->sc_type = EMUXKI_AUDIGY;
469: if (PCI_REVISION(pa->pa_class) == 0x04 ||
470: PCI_REVISION(pa->pa_class) == 0x08) {
471: sc->sc_type |= EMUXKI_AUDIGY2;
472: strlcpy(sc->sc_audv.name, "Audigy2", sizeof sc->sc_audv.name);
473: } else {
474: strlcpy(sc->sc_audv.name, "Audigy", sizeof sc->sc_audv.name);
475: }
476: } else if (pci_conf_read(pa->pa_pc, pa->pa_tag,
477: PCI_SUBSYS_ID_REG) == EMU_SUBSYS_APS) {
478: sc->sc_type = EMUXKI_APS;
479: strlcpy(sc->sc_audv.name, "E-mu APS", sizeof sc->sc_audv.name);
480: } else {
481: sc->sc_type = EMUXKI_SBLIVE;
482: strlcpy(sc->sc_audv.name, "SB Live!", sizeof sc->sc_audv.name);
483: }
484: snprintf(sc->sc_audv.version, sizeof sc->sc_audv.version, "0x%02x",
485: PCI_REVISION(pa->pa_class));
486: strlcpy(sc->sc_audv.config, "emuxki", sizeof sc->sc_audv.config);
487:
488: if (emuxki_scinit(sc) ||
489: /* APS has no ac97 XXX */
490: (sc->sc_type == EMUXKI_APS || emuxki_ac97_init(sc)) ||
491: (sc->sc_audev = audio_attach_mi(&emuxki_hw_if, sc, self)) == NULL) {
492: emuxki_pci_shutdown(sc);
493: return;
494: }
495: }
496:
497: int
498: emuxki_detach(struct device *self, int flags)
499: {
500: struct emuxki_softc *sc = (struct emuxki_softc *) self;
501:
502: if (sc->sc_audev != NULL) /* Test in case audio didn't attach */
503: config_detach(sc->sc_audev, 0);
504:
505: /* All voices should be stopped now but add some code here if not */
506:
507: bus_space_write_4(sc->sc_iot, sc->sc_ioh, EMU_HCFG,
508: EMU_HCFG_LOCKSOUNDCACHE | EMU_HCFG_LOCKTANKCACHE_MASK |
509: EMU_HCFG_MUTEBUTTONENABLE);
510: bus_space_write_4(sc->sc_iot, sc->sc_ioh, EMU_INTE, 0);
511:
512: emuxki_shutdown(sc);
513:
514: emuxki_pci_shutdown(sc);
515:
516: return (0);
517: }
518:
519:
520: /* Misc stuff relative to emu10k1 */
521:
522: static __inline u_int32_t
523: emuxki_rate_to_pitch(u_int32_t rate)
524: {
525: static const u_int32_t logMagTable[128] = {
526: 0x00000, 0x02dfc, 0x05b9e, 0x088e6, 0x0b5d6, 0x0e26f, 0x10eb3,
527: 0x13aa2, 0x1663f, 0x1918a, 0x1bc84, 0x1e72e, 0x2118b, 0x23b9a,
528: 0x2655d, 0x28ed5, 0x2b803, 0x2e0e8, 0x30985, 0x331db, 0x359eb,
529: 0x381b6, 0x3a93d, 0x3d081, 0x3f782, 0x41e42, 0x444c1, 0x46b01,
530: 0x49101, 0x4b6c4, 0x4dc49, 0x50191, 0x5269e, 0x54b6f, 0x57006,
531: 0x59463, 0x5b888, 0x5dc74, 0x60029, 0x623a7, 0x646ee, 0x66a00,
532: 0x68cdd, 0x6af86, 0x6d1fa, 0x6f43c, 0x7164b, 0x73829, 0x759d4,
533: 0x77b4f, 0x79c9a, 0x7bdb5, 0x7dea1, 0x7ff5e, 0x81fed, 0x8404e,
534: 0x86082, 0x88089, 0x8a064, 0x8c014, 0x8df98, 0x8fef1, 0x91e20,
535: 0x93d26, 0x95c01, 0x97ab4, 0x9993e, 0x9b79f, 0x9d5d9, 0x9f3ec,
536: 0xa11d8, 0xa2f9d, 0xa4d3c, 0xa6ab5, 0xa8808, 0xaa537, 0xac241,
537: 0xadf26, 0xafbe7, 0xb1885, 0xb3500, 0xb5157, 0xb6d8c, 0xb899f,
538: 0xba58f, 0xbc15e, 0xbdd0c, 0xbf899, 0xc1404, 0xc2f50, 0xc4a7b,
539: 0xc6587, 0xc8073, 0xc9b3f, 0xcb5ed, 0xcd07c, 0xceaec, 0xd053f,
540: 0xd1f73, 0xd398a, 0xd5384, 0xd6d60, 0xd8720, 0xda0c3, 0xdba4a,
541: 0xdd3b4, 0xded03, 0xe0636, 0xe1f4e, 0xe384a, 0xe512c, 0xe69f3,
542: 0xe829f, 0xe9b31, 0xeb3a9, 0xecc08, 0xee44c, 0xefc78, 0xf148a,
543: 0xf2c83, 0xf4463, 0xf5c2a, 0xf73da, 0xf8b71, 0xfa2f0, 0xfba57,
544: 0xfd1a7, 0xfe8df
545: };
546: static const u_int8_t logSlopeTable[128] = {
547: 0x5c, 0x5c, 0x5b, 0x5a, 0x5a, 0x59, 0x58, 0x58,
548: 0x57, 0x56, 0x56, 0x55, 0x55, 0x54, 0x53, 0x53,
549: 0x52, 0x52, 0x51, 0x51, 0x50, 0x50, 0x4f, 0x4f,
550: 0x4e, 0x4d, 0x4d, 0x4d, 0x4c, 0x4c, 0x4b, 0x4b,
551: 0x4a, 0x4a, 0x49, 0x49, 0x48, 0x48, 0x47, 0x47,
552: 0x47, 0x46, 0x46, 0x45, 0x45, 0x45, 0x44, 0x44,
553: 0x43, 0x43, 0x43, 0x42, 0x42, 0x42, 0x41, 0x41,
554: 0x41, 0x40, 0x40, 0x40, 0x3f, 0x3f, 0x3f, 0x3e,
555: 0x3e, 0x3e, 0x3d, 0x3d, 0x3d, 0x3c, 0x3c, 0x3c,
556: 0x3b, 0x3b, 0x3b, 0x3b, 0x3a, 0x3a, 0x3a, 0x39,
557: 0x39, 0x39, 0x39, 0x38, 0x38, 0x38, 0x38, 0x37,
558: 0x37, 0x37, 0x37, 0x36, 0x36, 0x36, 0x36, 0x35,
559: 0x35, 0x35, 0x35, 0x34, 0x34, 0x34, 0x34, 0x34,
560: 0x33, 0x33, 0x33, 0x33, 0x32, 0x32, 0x32, 0x32,
561: 0x32, 0x31, 0x31, 0x31, 0x31, 0x31, 0x30, 0x30,
562: 0x30, 0x30, 0x30, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f
563: };
564: int8_t i;
565:
566: if (rate == 0)
567: return 0; /* Bail out if no leading "1" */
568: rate *= 11185; /* Scale 48000 to 0x20002380 */
569: for (i = 31; i > 0; i--) {
570: if (rate & 0x80000000) { /* Detect leading "1" */
571: return (((u_int32_t) (i - 15) << 20) +
572: logMagTable[0x7f & (rate >> 24)] +
573: (0x7f & (rate >> 17)) *
574: logSlopeTable[0x7f & (rate >> 24)]);
575: }
576: rate <<= 1;
577: }
578:
579: return 0; /* Should never reach this point */
580: }
581:
582: /* Emu10k1 Low level */
583:
584: static __inline u_int32_t
585: emuxki_read(struct emuxki_softc *sc, u_int16_t chano, u_int32_t reg)
586: {
587: u_int32_t ptr, mask = 0xffffffff;
588: u_int8_t size, offset = 0;
589: int s;
590:
591: ptr = ((((u_int32_t) reg) << 16) &
592: (sc->sc_type & EMUXKI_AUDIGY ?
593: EMU_A_PTR_ADDR_MASK : EMU_PTR_ADDR_MASK)) |
594: (chano & EMU_PTR_CHNO_MASK);
595: if (reg & 0xff000000) {
596: size = (reg >> 24) & 0x3f;
597: offset = (reg >> 16) & 0x1f;
598: mask = ((1 << size) - 1) << offset;
599: }
600:
601: s = splaudio();
602: bus_space_write_4(sc->sc_iot, sc->sc_ioh, EMU_PTR, ptr);
603: ptr = (bus_space_read_4(sc->sc_iot, sc->sc_ioh, EMU_DATA) & mask)
604: >> offset;
605: splx(s);
606:
607: return (ptr);
608: }
609:
610: static __inline void
611: emuxki_write(struct emuxki_softc *sc, u_int16_t chano,
612: u_int32_t reg, u_int32_t data)
613: {
614: u_int32_t ptr, mask;
615: u_int8_t size, offset;
616: int s;
617:
618: ptr = ((((u_int32_t) reg) << 16) &
619: (sc->sc_type & EMUXKI_AUDIGY ?
620: EMU_A_PTR_ADDR_MASK : EMU_PTR_ADDR_MASK)) |
621: (chano & EMU_PTR_CHNO_MASK);
622:
623: /* BE CAREFUL WITH THAT AXE, EUGENE */
624: if (ptr == 0x52 || ptr == 0x53)
625: return;
626:
627: if (reg & 0xff000000) {
628: size = (reg >> 24) & 0x3f;
629: offset = (reg >> 16) & 0x1f;
630: mask = ((1 << size) - 1) << offset;
631: data = ((data << offset) & mask) |
632: (emuxki_read(sc, chano, reg & 0xffff) & ~mask);
633: }
634:
635: s = splaudio();
636: bus_space_write_4(sc->sc_iot, sc->sc_ioh, EMU_PTR, ptr);
637: bus_space_write_4(sc->sc_iot, sc->sc_ioh, EMU_DATA, data);
638: splx(s);
639: }
640:
641: /* Microcode should this go in /sys/dev/microcode ? */
642:
643: void
644: emuxki_write_micro(struct emuxki_softc *sc, u_int32_t pc, u_int32_t data)
645: {
646: emuxki_write(sc, 0,
647: (sc->sc_type & EMUXKI_AUDIGY ?
648: EMU_A_MICROCODEBASE : EMU_MICROCODEBASE) + pc,
649: data);
650: }
651:
652: void
653: emuxki_dsp_addop(struct emuxki_softc *sc, u_int16_t *pc, u_int8_t op,
654: u_int16_t r, u_int16_t a, u_int16_t x, u_int16_t y)
655: {
656: if (sc->sc_type & EMUXKI_AUDIGY) {
657: emuxki_write_micro(sc, *pc << 1,
658: ((x << 12) & EMU_A_DSP_LOWORD_OPX_MASK) |
659: (y & EMU_A_DSP_LOWORD_OPY_MASK));
660: emuxki_write_micro(sc, (*pc << 1) + 1,
661: ((op << 24) & EMU_A_DSP_HIWORD_OPCODE_MASK) |
662: ((r << 12) & EMU_A_DSP_HIWORD_RESULT_MASK) |
663: (a & EMU_A_DSP_HIWORD_OPA_MASK));
664: } else {
665: emuxki_write_micro(sc, *pc << 1,
666: ((x << 10) & EMU_DSP_LOWORD_OPX_MASK) |
667: (y & EMU_DSP_LOWORD_OPY_MASK));
668: emuxki_write_micro(sc, (*pc << 1) + 1,
669: ((op << 20) & EMU_DSP_HIWORD_OPCODE_MASK) |
670: ((r << 10) & EMU_DSP_HIWORD_RESULT_MASK) |
671: (a & EMU_DSP_HIWORD_OPA_MASK));
672: }
673: (*pc)++;
674: }
675:
676: /* init and shutdown */
677:
678: void
679: emuxki_initfx(struct emuxki_softc *sc)
680: {
681: u_int16_t pc;
682:
683: /* Set all GPRs to 0 */
684: for (pc = 0; pc < 256; pc++)
685: emuxki_write(sc, 0, EMU_DSP_GPR(pc), 0);
686: for (pc = 0; pc < 160; pc++) {
687: emuxki_write(sc, 0, EMU_TANKMEMDATAREGBASE + pc, 0);
688: emuxki_write(sc, 0, EMU_TANKMEMADDRREGBASE + pc, 0);
689: }
690: pc = 0;
691:
692: if (sc->sc_type & EMUXKI_AUDIGY) {
693: /* AC97 Out (l/r) = AC97 In (l/r) + FX[0/1] * 4 */
694: emuxki_dsp_addop(sc, &pc, EMU_DSP_OP_MACINTS,
695: EMU_A_DSP_OUTL(EMU_A_DSP_OUT_A_FRONT),
696: EMU_A_DSP_CST(0),
697: EMU_DSP_FX(0), EMU_A_DSP_CST(4));
698: emuxki_dsp_addop(sc, &pc, EMU_DSP_OP_MACINTS,
699: EMU_A_DSP_OUTR(EMU_A_DSP_OUT_A_FRONT),
700: EMU_A_DSP_CST(0),
701: EMU_DSP_FX(1), EMU_A_DSP_CST(4));
702:
703: /* Rear channel OUT (l/r) = FX[2/3] * 4 */
704: #if 0
705: emuxki_dsp_addop(sc, &pc, EMU_DSP_OP_MACINTS,
706: EMU_A_DSP_OUTL(EMU_A_DSP_OUT_A_REAR),
707: EMU_A_DSP_OUTL(EMU_A_DSP_OUT_A_FRONT),
708: EMU_DSP_FX(0), EMU_A_DSP_CST(4));
709: emuxki_dsp_addop(sc, &pc, EMU_DSP_OP_MACINTS,
710: EMU_A_DSP_OUTR(EMU_A_DSP_OUT_A_REAR),
711: EMU_A_DSP_OUTR(EMU_A_DSP_OUT_A_FRONT),
712: EMU_DSP_FX(1), EMU_A_DSP_CST(4));
713: #endif
714: /* ADC recording (l/r) = AC97 In (l/r) */
715: emuxki_dsp_addop(sc, &pc, EMU_DSP_OP_ACC3,
716: EMU_A_DSP_OUTL(EMU_A_DSP_OUT_ADC),
717: EMU_A_DSP_INL(EMU_DSP_IN_AC97),
718: EMU_A_DSP_CST(0), EMU_A_DSP_CST(0));
719: emuxki_dsp_addop(sc, &pc, EMU_DSP_OP_ACC3,
720: EMU_A_DSP_OUTR(EMU_A_DSP_OUT_ADC),
721: EMU_A_DSP_INR(EMU_DSP_IN_AC97),
722: EMU_A_DSP_CST(0), EMU_A_DSP_CST(0));
723:
724: /* zero out the rest of the microcode */
725: while (pc < 512)
726: emuxki_dsp_addop(sc, &pc, EMU_DSP_OP_ACC3,
727: EMU_A_DSP_CST(0), EMU_A_DSP_CST(0),
728: EMU_A_DSP_CST(0), EMU_A_DSP_CST(0));
729:
730: emuxki_write(sc, 0, EMU_A_DBG, 0); /* Is it really necessary ? */
731: } else {
732: /* AC97 Out (l/r) = AC97 In (l/r) + FX[0/1] * 4 */
733: emuxki_dsp_addop(sc, &pc, EMU_DSP_OP_MACINTS,
734: EMU_DSP_OUTL(EMU_DSP_OUT_A_FRONT),
735: EMU_DSP_CST(0),
736: EMU_DSP_FX(0), EMU_DSP_CST(4));
737: emuxki_dsp_addop(sc, &pc, EMU_DSP_OP_MACINTS,
738: EMU_DSP_OUTR(EMU_DSP_OUT_A_FRONT),
739: EMU_DSP_CST(0),
740: EMU_DSP_FX(1), EMU_DSP_CST(4));
741:
742: /* Rear channel OUT (l/r) = FX[2/3] * 4 */
743: #if 0
744: emuxki_dsp_addop(sc, &pc, EMU_DSP_OP_MACINTS,
745: EMU_DSP_OUTL(EMU_DSP_OUT_AD_REAR),
746: EMU_DSP_OUTL(EMU_DSP_OUT_A_FRONT),
747: EMU_DSP_FX(0), EMU_DSP_CST(4));
748: emuxki_dsp_addop(sc, &pc, EMU_DSP_OP_MACINTS,
749: EMU_DSP_OUTR(EMU_DSP_OUT_AD_REAR),
750: EMU_DSP_OUTR(EMU_DSP_OUT_A_FRONT),
751: EMU_DSP_FX(1), EMU_DSP_CST(4));
752: #endif
753: /* ADC recording (l/r) = AC97 In (l/r) */
754: emuxki_dsp_addop(sc, &pc, EMU_DSP_OP_ACC3,
755: EMU_DSP_OUTL(EMU_DSP_OUT_ADC),
756: EMU_DSP_INL(EMU_DSP_IN_AC97),
757: EMU_DSP_CST(0), EMU_DSP_CST(0));
758: emuxki_dsp_addop(sc, &pc, EMU_DSP_OP_ACC3,
759: EMU_DSP_OUTR(EMU_DSP_OUT_ADC),
760: EMU_DSP_INR(EMU_DSP_IN_AC97),
761: EMU_DSP_CST(0), EMU_DSP_CST(0));
762:
763: /* zero out the rest of the microcode */
764: while (pc < 512)
765: emuxki_dsp_addop(sc, &pc, EMU_DSP_OP_ACC3,
766: EMU_DSP_CST(0), EMU_DSP_CST(0),
767: EMU_DSP_CST(0), EMU_DSP_CST(0));
768:
769: emuxki_write(sc, 0, EMU_DBG, 0); /* Is it really necessary ? */
770: }
771: }
772:
773: int
774: emuxki_init(struct emuxki_softc *sc)
775: {
776: u_int16_t i;
777: u_int32_t spcs, *ptb;
778: bus_addr_t silentpage;
779:
780: /* disable any channel interrupt */
781: emuxki_write(sc, 0, EMU_CLIEL, 0);
782: emuxki_write(sc, 0, EMU_CLIEH, 0);
783: emuxki_write(sc, 0, EMU_SOLEL, 0);
784: emuxki_write(sc, 0, EMU_SOLEH, 0);
785:
786: /* Set recording buffers sizes to zero */
787: emuxki_write(sc, 0, EMU_MICBS, EMU_RECBS_BUFSIZE_NONE);
788: emuxki_write(sc, 0, EMU_MICBA, 0);
789: emuxki_write(sc, 0, EMU_FXBS, EMU_RECBS_BUFSIZE_NONE);
790: emuxki_write(sc, 0, EMU_FXBA, 0);
791: emuxki_write(sc, 0, EMU_ADCBS, EMU_RECBS_BUFSIZE_NONE);
792: emuxki_write(sc, 0, EMU_ADCBA, 0);
793:
794: if(sc->sc_type & EMUXKI_AUDIGY) {
795: emuxki_write(sc, 0, EMU_SPBYPASS, EMU_SPBYPASS_24_BITS);
796: emuxki_write(sc, 0, EMU_AC97SLOT, EMU_AC97SLOT_CENTER | EMU_AC97SLOT_LFE);
797: }
798:
799: /* Initialize all channels to stopped and no effects */
800: for (i = 0; i < EMU_NUMCHAN; i++) {
801: emuxki_write(sc, i, EMU_CHAN_DCYSUSV, 0);
802: emuxki_write(sc, i, EMU_CHAN_IP, 0);
803: emuxki_write(sc, i, EMU_CHAN_VTFT, 0xffff);
804: emuxki_write(sc, i, EMU_CHAN_CVCF, 0xffff);
805: emuxki_write(sc, i, EMU_CHAN_PTRX, 0);
806: emuxki_write(sc, i, EMU_CHAN_CPF, 0);
807: emuxki_write(sc, i, EMU_CHAN_CCR, 0);
808: emuxki_write(sc, i, EMU_CHAN_PSST, 0);
809: emuxki_write(sc, i, EMU_CHAN_DSL, 0x10); /* Why 16 ? */
810: emuxki_write(sc, i, EMU_CHAN_CCCA, 0);
811: emuxki_write(sc, i, EMU_CHAN_Z1, 0);
812: emuxki_write(sc, i, EMU_CHAN_Z2, 0);
813: emuxki_write(sc, i, EMU_CHAN_FXRT, 0x32100000);
814: emuxki_write(sc, i, EMU_CHAN_ATKHLDM, 0);
815: emuxki_write(sc, i, EMU_CHAN_DCYSUSM, 0);
816: emuxki_write(sc, i, EMU_CHAN_IFATN, 0xffff);
817: emuxki_write(sc, i, EMU_CHAN_PEFE, 0);
818: emuxki_write(sc, i, EMU_CHAN_FMMOD, 0);
819: emuxki_write(sc, i, EMU_CHAN_TREMFRQ, 24);
820: emuxki_write(sc, i, EMU_CHAN_FM2FRQ2, 24);
821: emuxki_write(sc, i, EMU_CHAN_TEMPENV, 0);
822:
823: /* these are last so OFF prevents writing */
824: emuxki_write(sc, i, EMU_CHAN_LFOVAL2, 0);
825: emuxki_write(sc, i, EMU_CHAN_LFOVAL1, 0);
826: emuxki_write(sc, i, EMU_CHAN_ATKHLDV, 0);
827: emuxki_write(sc, i, EMU_CHAN_ENVVOL, 0);
828: emuxki_write(sc, i, EMU_CHAN_ENVVAL, 0);
829: }
830:
831: /* set digital outputs format */
832: spcs = (EMU_SPCS_CLKACCY_1000PPM | EMU_SPCS_SAMPLERATE_48 |
833: EMU_SPCS_CHANNELNUM_LEFT | EMU_SPCS_SOURCENUM_UNSPEC |
834: EMU_SPCS_GENERATIONSTATUS | 0x00001200 /* Cat code. */ |
835: 0x00000000 /* IEC-958 Mode */ | EMU_SPCS_EMPHASIS_NONE |
836: EMU_SPCS_COPYRIGHT);
837: emuxki_write(sc, 0, EMU_SPCS0, spcs);
838: emuxki_write(sc, 0, EMU_SPCS1, spcs);
839: emuxki_write(sc, 0, EMU_SPCS2, spcs);
840:
841: if(sc->sc_type & EMUXKI_AUDIGY2) {
842: emuxki_write(sc, 0, EMU_A2_SPDIF_SAMPLERATE, EMU_A2_SPDIF_UNKNOWN);
843:
844: bus_space_write_4(sc->sc_iot, sc->sc_ioh, EMU_A2_PTR, EMU_A2_SRCSEL);
845: bus_space_write_4(sc->sc_iot, sc->sc_ioh, EMU_A2_DATA,
846: EMU_A2_SRCSEL_ENABLE_SPDIF | EMU_A2_SRCSEL_ENABLE_SRCMULTI);
847:
848: bus_space_write_4(sc->sc_iot, sc->sc_ioh, EMU_A2_PTR, EMU_A2_SRCMULTI);
849: bus_space_write_4(sc->sc_iot, sc->sc_ioh, EMU_A2_DATA, EMU_A2_SRCMULTI_ENABLE_INPUT);
850: }
851:
852:
853: /* Let's play with sound processor */
854: emuxki_initfx(sc);
855:
856: /* Here is our Page Table */
857: if ((sc->ptb = emuxki_dmamem_alloc(sc->sc_dmat,
858: EMU_MAXPTE * sizeof(u_int32_t),
859: EMU_DMA_ALIGN, EMU_DMAMEM_NSEG,
860: M_DEVBUF, M_WAITOK)) == NULL)
861: return (ENOMEM);
862:
863: /* This is necessary unless you like Metallic noise... */
864: if ((sc->silentpage = emuxki_dmamem_alloc(sc->sc_dmat, EMU_PTESIZE,
865: EMU_DMA_ALIGN, EMU_DMAMEM_NSEG, M_DEVBUF, M_WAITOK))==NULL){
866: emuxki_dmamem_free(sc->ptb, M_DEVBUF);
867: return (ENOMEM);
868: }
869:
870: /* Zero out the silent page */
871: /* This might not be always true, it might be 128 for 8bit channels */
872: memset(KERNADDR(sc->silentpage), 0, DMASIZE(sc->silentpage));
873:
874: /*
875: * Set all the PTB Entries to the silent page We shift the physical
876: * address by one and OR it with the page number. I don't know what
877: * the ORed index is for, might be a very useful unused feature...
878: */
879: silentpage = DMAADDR(sc->silentpage) << 1;
880: ptb = KERNADDR(sc->ptb);
881: for (i = 0; i < EMU_MAXPTE; i++)
882: ptb[i] = htole32(silentpage | i);
883:
884: /* Write PTB address and set TCB to none */
885: emuxki_write(sc, 0, EMU_PTB, DMAADDR(sc->ptb));
886: emuxki_write(sc, 0, EMU_TCBS, 0); /* This means 16K TCB */
887: emuxki_write(sc, 0, EMU_TCB, 0); /* No TCB use for now */
888:
889: /*
890: * Set channels MAPs to the silent page.
891: * I don't know what MAPs are for.
892: */
893: silentpage |= EMU_CHAN_MAP_PTI_MASK;
894: for (i = 0; i < EMU_NUMCHAN; i++) {
895: emuxki_write(sc, i, EMU_CHAN_MAPA, silentpage);
896: emuxki_write(sc, i, EMU_CHAN_MAPB, silentpage);
897: sc->channel[i] = NULL;
898: }
899:
900: /* Init voices list */
901: LIST_INIT(&(sc->voices));
902:
903: /* Timer is stopped */
904: sc->timerstate &= ~EMU_TIMER_STATE_ENABLED;
905: return (0);
906: }
907:
908: void
909: emuxki_shutdown(struct emuxki_softc *sc)
910: {
911: u_int32_t i;
912:
913: /* Disable any Channels interrupts */
914: emuxki_write(sc, 0, EMU_CLIEL, 0);
915: emuxki_write(sc, 0, EMU_CLIEH, 0);
916: emuxki_write(sc, 0, EMU_SOLEL, 0);
917: emuxki_write(sc, 0, EMU_SOLEH, 0);
918:
919: /*
920: * Should do some voice(stream) stopping stuff here, that's what will
921: * stop and deallocate all channels.
922: */
923:
924: /* Stop all channels */
925: /* XXX This shouldn't be necessary, I'll remove once everything works */
926: for (i = 0; i < EMU_NUMCHAN; i++)
927: emuxki_write(sc, i, EMU_CHAN_DCYSUSV, 0);
928: for (i = 0; i < EMU_NUMCHAN; i++) {
929: emuxki_write(sc, i, EMU_CHAN_VTFT, 0);
930: emuxki_write(sc, i, EMU_CHAN_CVCF, 0);
931: emuxki_write(sc, i, EMU_CHAN_PTRX, 0);
932: emuxki_write(sc, i, EMU_CHAN_CPF, 0);
933: }
934:
935: /*
936: * Deallocate Emu10k1 caches and recording buffers. Again it will be
937: * removed because it will be done in voice shutdown.
938: */
939: emuxki_write(sc, 0, EMU_MICBS, EMU_RECBS_BUFSIZE_NONE);
940: emuxki_write(sc, 0, EMU_MICBA, 0);
941: emuxki_write(sc, 0, EMU_FXBS, EMU_RECBS_BUFSIZE_NONE);
942: emuxki_write(sc, 0, EMU_FXBA, 0);
943: if(sc->sc_type & EMUXKI_AUDIGY) {
944: emuxki_write(sc, 0, EMU_A_FXWC1, 0);
945: emuxki_write(sc, 0, EMU_A_FXWC2, 0);
946: } else {
947: emuxki_write(sc, 0, EMU_FXWC, 0);
948: }
949: emuxki_write(sc, 0, EMU_ADCBS, EMU_RECBS_BUFSIZE_NONE);
950: emuxki_write(sc, 0, EMU_ADCBA, 0);
951:
952: /*
953: * XXX I don't know yet how I will handle tank cache buffer,
954: * I don't even clearly know what it is for.
955: */
956: emuxki_write(sc, 0, EMU_TCB, 0); /* 16K again */
957: emuxki_write(sc, 0, EMU_TCBS, 0);
958:
959: emuxki_write(sc, 0, EMU_DBG, 0x8000); /* necessary ? */
960:
961: emuxki_dmamem_free(sc->silentpage, M_DEVBUF);
962: emuxki_dmamem_free(sc->ptb, M_DEVBUF);
963: }
964:
965: /* Emu10k1 Memory management */
966:
967: struct emuxki_mem *
968: emuxki_mem_new(struct emuxki_softc *sc, int ptbidx,
969: size_t size, int type, int flags)
970: {
971: struct emuxki_mem *mem;
972:
973: if ((mem = malloc(sizeof(*mem), type, flags)) == NULL)
974: return (NULL);
975:
976: mem->ptbidx = ptbidx;
977: if ((mem->dmamem = emuxki_dmamem_alloc(sc->sc_dmat, size,
978: EMU_DMA_ALIGN, EMU_DMAMEM_NSEG, type, flags)) == NULL) {
979: free(mem, type);
980: return (NULL);
981: }
982: return (mem);
983: }
984:
985: void
986: emuxki_mem_delete(struct emuxki_mem *mem, int type)
987: {
988: emuxki_dmamem_free(mem->dmamem, type);
989: free(mem, type);
990: }
991:
992: void *
993: emuxki_pmem_alloc(struct emuxki_softc *sc, size_t size, int type, int flags)
994: {
995: int i, j, s;
996: size_t numblocks;
997: struct emuxki_mem *mem;
998: u_int32_t *ptb, silentpage;
999:
1000: ptb = KERNADDR(sc->ptb);
1001: silentpage = DMAADDR(sc->silentpage) << 1;
1002: numblocks = size / EMU_PTESIZE;
1003: if (size % EMU_PTESIZE)
1004: numblocks++;
1005:
1006: for (i = 0; i < EMU_MAXPTE; i++)
1007: if ((letoh32(ptb[i]) & EMU_CHAN_MAP_PTE_MASK) == silentpage) {
1008: /* We look for a free PTE */
1009: s = splaudio();
1010: for (j = 0; j < numblocks; j++)
1011: if ((letoh32(ptb[i + j])
1012: & EMU_CHAN_MAP_PTE_MASK)
1013: != silentpage)
1014: break;
1015: if (j == numblocks) {
1016: if ((mem = emuxki_mem_new(sc, i,
1017: size, type, flags)) == NULL) {
1018: splx(s);
1019: return (NULL);
1020: }
1021: for (j = 0; j < numblocks; j++)
1022: ptb[i + j] =
1023: htole32((((DMAADDR(mem->dmamem) +
1024: j * EMU_PTESIZE)) << 1) | (i + j));
1025: LIST_INSERT_HEAD(&(sc->mem), mem, next);
1026: splx(s);
1027: return (KERNADDR(mem->dmamem));
1028: } else
1029: i += j;
1030: splx(s);
1031: }
1032: return (NULL);
1033: }
1034:
1035: void *
1036: emuxki_rmem_alloc(struct emuxki_softc *sc, size_t size, int type, int flags)
1037: {
1038: struct emuxki_mem *mem;
1039: int s;
1040:
1041: mem = emuxki_mem_new(sc, EMU_RMEM, size, type, flags);
1042: if (mem == NULL)
1043: return (NULL);
1044:
1045: s = splaudio();
1046: LIST_INSERT_HEAD(&(sc->mem), mem, next);
1047: splx(s);
1048:
1049: return (KERNADDR(mem->dmamem));
1050: }
1051:
1052: /*
1053: * emuxki_channel_* : Channel management functions
1054: * emuxki_chanparms_* : Channel parameters modification functions
1055: */
1056:
1057: /*
1058: * is splaudio necessary here, can the same voice be manipulated by two
1059: * different threads at a time ?
1060: */
1061: void
1062: emuxki_chanparms_set_defaults(struct emuxki_channel *chan)
1063: {
1064: chan->fxsend.a.level = chan->fxsend.b.level =
1065: chan->fxsend.c.level = chan->fxsend.d.level =
1066: /* for audigy */
1067: chan->fxsend.e.level = chan->fxsend.f.level =
1068: chan->fxsend.g.level = chan->fxsend.h.level =
1069: chan->voice->sc->sc_type & EMUXKI_AUDIGY ?
1070: 0xc0 : 0xff; /* not max */
1071:
1072: chan->fxsend.a.dest = 0x0;
1073: chan->fxsend.b.dest = 0x1;
1074: chan->fxsend.c.dest = 0x2;
1075: chan->fxsend.d.dest = 0x3;
1076: /* for audigy */
1077: chan->fxsend.e.dest = 0x4;
1078: chan->fxsend.f.dest = 0x5;
1079: chan->fxsend.g.dest = 0x6;
1080: chan->fxsend.h.dest = 0x7;
1081:
1082: chan->pitch.initial = 0x0000; /* shouldn't it be 0xE000 ? */
1083: chan->pitch.current = 0x0000; /* should it be 0x0400 */
1084: chan->pitch.target = 0x0000; /* the unity pitch shift ? */
1085: chan->pitch.envelope_amount = 0x00; /* none */
1086:
1087: chan->initial_attenuation = 0x00; /* no attenuation */
1088: chan->volume.current = 0x0000; /* no volume */
1089: chan->volume.target = 0xffff;
1090: chan->volume.envelope.current_state = 0x8000; /* 0 msec delay */
1091: chan->volume.envelope.hold_time = 0x7f; /* 0 msec */
1092: chan->volume.envelope.attack_time = 0x7F; /* 5.5msec */
1093: chan->volume.envelope.sustain_level = 0x7F; /* full */
1094: chan->volume.envelope.decay_time = 0x7F; /* 22msec */
1095:
1096: chan->filter.initial_cutoff_frequency = 0xff; /* no filter */
1097: chan->filter.current_cutoff_frequency = 0xffff; /* no filtering */
1098: chan->filter.target_cutoff_frequency = 0xffff; /* no filtering */
1099: chan->filter.lowpass_resonance_height = 0x0;
1100: chan->filter.interpolation_ROM = 0x1; /* full band */
1101: chan->filter.envelope_amount = 0x7f; /* none */
1102: chan->filter.LFO_modulation_depth = 0x00; /* none */
1103:
1104: chan->loop.start = 0x000000;
1105: chan->loop.end = 0x000010; /* Why ? */
1106:
1107: chan->modulation.envelope.current_state = 0x8000;
1108: chan->modulation.envelope.hold_time = 0x00; /* 127 better ? */
1109: chan->modulation.envelope.attack_time = 0x00; /* infinite */
1110: chan->modulation.envelope.sustain_level = 0x00; /* off */
1111: chan->modulation.envelope.decay_time = 0x7f; /* 22 msec */
1112: chan->modulation.LFO_state = 0x8000;
1113:
1114: chan->vibrato_LFO.state = 0x8000;
1115: chan->vibrato_LFO.modulation_depth = 0x00; /* none */
1116: chan->vibrato_LFO.vibrato_depth = 0x00;
1117: chan->vibrato_LFO.frequency = 0x00; /* Why set to 24 when
1118: * initialized ? */
1119:
1120: chan->tremolo_depth = 0x00;
1121: }
1122:
1123: /* only call it at splaudio */
1124: struct emuxki_channel *
1125: emuxki_channel_new(struct emuxki_voice *voice, u_int8_t num)
1126: {
1127: struct emuxki_channel *chan;
1128:
1129: chan = malloc(sizeof(struct emuxki_channel), M_DEVBUF, M_WAITOK);
1130: if (chan == NULL)
1131: return (NULL);
1132:
1133: chan->voice = voice;
1134: chan->num = num;
1135: emuxki_chanparms_set_defaults(chan);
1136: chan->voice->sc->channel[num] = chan;
1137: return (chan);
1138: }
1139:
1140: /* only call it at splaudio */
1141: void
1142: emuxki_channel_delete(struct emuxki_channel *chan)
1143: {
1144: chan->voice->sc->channel[chan->num] = NULL;
1145: free(chan, M_DEVBUF);
1146: }
1147:
1148: void
1149: emuxki_channel_set_fxsend(struct emuxki_channel *chan,
1150: struct emuxki_chanparms_fxsend *fxsend)
1151: {
1152: /* Could do a memcpy ...*/
1153: chan->fxsend.a.level = fxsend->a.level;
1154: chan->fxsend.b.level = fxsend->b.level;
1155: chan->fxsend.c.level = fxsend->c.level;
1156: chan->fxsend.d.level = fxsend->d.level;
1157: chan->fxsend.a.dest = fxsend->a.dest;
1158: chan->fxsend.b.dest = fxsend->b.dest;
1159: chan->fxsend.c.dest = fxsend->c.dest;
1160: chan->fxsend.d.dest = fxsend->d.dest;
1161:
1162: /* for audigy */
1163: chan->fxsend.e.level = fxsend->e.level;
1164: chan->fxsend.f.level = fxsend->f.level;
1165: chan->fxsend.g.level = fxsend->g.level;
1166: chan->fxsend.h.level = fxsend->h.level;
1167: chan->fxsend.e.dest = fxsend->e.dest;
1168: chan->fxsend.f.dest = fxsend->f.dest;
1169: chan->fxsend.g.dest = fxsend->g.dest;
1170: chan->fxsend.h.dest = fxsend->h.dest;
1171: }
1172:
1173: void
1174: emuxki_channel_set_srate(struct emuxki_channel *chan, u_int32_t srate)
1175: {
1176: chan->pitch.target = (srate << 8) / 375;
1177: chan->pitch.target = (chan->pitch.target >> 1) +
1178: (chan->pitch.target & 1);
1179: chan->pitch.target &= 0xffff;
1180: chan->pitch.current = chan->pitch.target;
1181: chan->pitch.initial =
1182: (emuxki_rate_to_pitch(srate) >> 8) & EMU_CHAN_IP_MASK;
1183: }
1184:
1185: /* voice params must be set before calling this */
1186: void
1187: emuxki_channel_set_bufparms(struct emuxki_channel *chan,
1188: u_int32_t start, u_int32_t end)
1189: {
1190: chan->loop.start = start & EMU_CHAN_PSST_LOOPSTARTADDR_MASK;
1191: chan->loop.end = end & EMU_CHAN_DSL_LOOPENDADDR_MASK;
1192: }
1193:
1194: void
1195: emuxki_channel_commit_fx(struct emuxki_channel *chan)
1196: {
1197: struct emuxki_softc *sc = chan->voice->sc;
1198: u_int8_t chano = chan->num;
1199:
1200: if(sc->sc_type & EMUXKI_AUDIGY) {
1201: emuxki_write(sc, chano, EMU_A_CHAN_FXRT1,
1202: (chan->fxsend.d.dest << 24) |
1203: (chan->fxsend.c.dest << 16) |
1204: (chan->fxsend.b.dest << 8) |
1205: (chan->fxsend.a.dest));
1206: emuxki_write(sc, chano, EMU_A_CHAN_FXRT2,
1207: (chan->fxsend.h.dest << 24) |
1208: (chan->fxsend.g.dest << 16) |
1209: (chan->fxsend.f.dest << 8) |
1210: (chan->fxsend.e.dest));
1211: emuxki_write(sc, chano, EMU_A_CHAN_SENDAMOUNTS,
1212: (chan->fxsend.e.level << 24) |
1213: (chan->fxsend.f.level << 16) |
1214: (chan->fxsend.g.level << 8) |
1215: (chan->fxsend.h.level));
1216: } else {
1217: emuxki_write(sc, chano, EMU_CHAN_FXRT,
1218: (chan->fxsend.d.dest << 28) |
1219: (chan->fxsend.c.dest << 24) |
1220: (chan->fxsend.b.dest << 20) |
1221: (chan->fxsend.a.dest << 16));
1222: }
1223:
1224: emuxki_write(sc, chano, 0x10000000 | EMU_CHAN_PTRX,
1225: (chan->fxsend.a.level << 8) | chan->fxsend.b.level);
1226: emuxki_write(sc, chano, EMU_CHAN_DSL,
1227: (chan->fxsend.d.level << 24) | chan->loop.end);
1228: emuxki_write(sc, chano, EMU_CHAN_PSST,
1229: (chan->fxsend.c.level << 24) | chan->loop.start);
1230: }
1231:
1232: void
1233: emuxki_channel_commit_parms(struct emuxki_channel *chan)
1234: {
1235: struct emuxki_voice *voice = chan->voice;
1236: struct emuxki_softc *sc = voice->sc;
1237: u_int32_t start, mapval;
1238: u_int8_t chano = chan->num;
1239: int s;
1240:
1241: start = chan->loop.start +
1242: (voice->stereo ? 28 : 30) * (voice->b16 + 1);
1243: mapval = DMAADDR(sc->silentpage) << 1 | EMU_CHAN_MAP_PTI_MASK;
1244:
1245: s = splaudio();
1246: emuxki_write(sc, chano, EMU_CHAN_CPF_STEREO, voice->stereo);
1247:
1248: emuxki_channel_commit_fx(chan);
1249:
1250: emuxki_write(sc, chano, EMU_CHAN_CCCA,
1251: (chan->filter.lowpass_resonance_height << 28) |
1252: (chan->filter.interpolation_ROM << 25) |
1253: (voice->b16 ? 0 : EMU_CHAN_CCCA_8BITSELECT) | start);
1254: emuxki_write(sc, chano, EMU_CHAN_Z1, 0);
1255: emuxki_write(sc, chano, EMU_CHAN_Z2, 0);
1256: emuxki_write(sc, chano, EMU_CHAN_MAPA, mapval);
1257: emuxki_write(sc, chano, EMU_CHAN_MAPB, mapval);
1258: emuxki_write(sc, chano, EMU_CHAN_CVCF_CURRFILTER,
1259: chan->filter.current_cutoff_frequency);
1260: emuxki_write(sc, chano, EMU_CHAN_VTFT_FILTERTARGET,
1261: chan->filter.target_cutoff_frequency);
1262: emuxki_write(sc, chano, EMU_CHAN_ATKHLDM,
1263: (chan->modulation.envelope.hold_time << 8) |
1264: chan->modulation.envelope.attack_time);
1265: emuxki_write(sc, chano, EMU_CHAN_DCYSUSM,
1266: (chan->modulation.envelope.sustain_level << 8) |
1267: chan->modulation.envelope.decay_time);
1268: emuxki_write(sc, chano, EMU_CHAN_LFOVAL1,
1269: chan->modulation.LFO_state);
1270: emuxki_write(sc, chano, EMU_CHAN_LFOVAL2,
1271: chan->vibrato_LFO.state);
1272: emuxki_write(sc, chano, EMU_CHAN_FMMOD,
1273: (chan->vibrato_LFO.modulation_depth << 8) |
1274: chan->filter.LFO_modulation_depth);
1275: emuxki_write(sc, chano, EMU_CHAN_TREMFRQ,
1276: (chan->tremolo_depth << 8));
1277: emuxki_write(sc, chano, EMU_CHAN_FM2FRQ2,
1278: (chan->vibrato_LFO.vibrato_depth << 8) |
1279: chan->vibrato_LFO.frequency);
1280: emuxki_write(sc, chano, EMU_CHAN_ENVVAL,
1281: chan->modulation.envelope.current_state);
1282: emuxki_write(sc, chano, EMU_CHAN_ATKHLDV,
1283: (chan->volume.envelope.hold_time << 8) |
1284: chan->volume.envelope.attack_time);
1285: emuxki_write(sc, chano, EMU_CHAN_ENVVOL,
1286: chan->volume.envelope.current_state);
1287: emuxki_write(sc, chano, EMU_CHAN_PEFE,
1288: (chan->pitch.envelope_amount << 8) |
1289: chan->filter.envelope_amount);
1290: splx(s);
1291: }
1292:
1293: void
1294: emuxki_channel_start(struct emuxki_channel *chan)
1295: {
1296: struct emuxki_voice *voice = chan->voice;
1297: struct emuxki_softc *sc = voice->sc;
1298: u_int8_t cache_sample, cache_invalid_size, chano = chan->num;
1299: u_int32_t sample;
1300: int s;
1301:
1302: cache_sample = voice->stereo ? 4 : 2;
1303: sample = voice->b16 ? 0x00000000 : 0x80808080;
1304: cache_invalid_size = (voice->stereo ? 28 : 30) * (voice->b16 + 1);
1305:
1306: s = splaudio();
1307: while (cache_sample--) {
1308: emuxki_write(sc, chano, EMU_CHAN_CD0 + cache_sample,
1309: sample);
1310: }
1311: emuxki_write(sc, chano, EMU_CHAN_CCR_CACHEINVALIDSIZE, 0);
1312: emuxki_write(sc, chano, EMU_CHAN_CCR_READADDRESS, 64);
1313: emuxki_write(sc, chano, EMU_CHAN_CCR_CACHEINVALIDSIZE,
1314: cache_invalid_size);
1315: emuxki_write(sc, chano, EMU_CHAN_IFATN,
1316: (chan->filter.target_cutoff_frequency << 8) |
1317: chan->initial_attenuation);
1318: emuxki_write(sc, chano, EMU_CHAN_VTFT_VOLUMETARGET,
1319: chan->volume.target);
1320: emuxki_write(sc, chano, EMU_CHAN_CVCF_CURRVOL,
1321: chan->volume.current);
1322: emuxki_write(sc, 0,
1323: EMU_MKSUBREG(1, chano, EMU_SOLEL + (chano >> 5)),
1324: 0); /* Clear stop on loop */
1325: emuxki_write(sc, 0,
1326: EMU_MKSUBREG(1, chano, EMU_CLIEL + (chano >> 5)),
1327: 0); /* Clear loop interrupt */
1328: emuxki_write(sc, chano, EMU_CHAN_DCYSUSV,
1329: (chan->volume.envelope.sustain_level << 8) |
1330: chan->volume.envelope.decay_time);
1331: emuxki_write(sc, chano, EMU_CHAN_PTRX_PITCHTARGET,
1332: chan->pitch.target);
1333: emuxki_write(sc, chano, EMU_CHAN_CPF_PITCH,
1334: chan->pitch.current);
1335: emuxki_write(sc, chano, EMU_CHAN_IP, chan->pitch.initial);
1336:
1337: splx(s);
1338: }
1339:
1340: void
1341: emuxki_channel_stop(struct emuxki_channel *chan)
1342: {
1343: int s;
1344: u_int8_t chano = chan->num;
1345: struct emuxki_softc *sc = chan->voice->sc;
1346:
1347: s = splaudio();
1348: emuxki_write(sc, chano, EMU_CHAN_PTRX_PITCHTARGET, 0);
1349: emuxki_write(sc, chano, EMU_CHAN_CPF_PITCH, 0);
1350: emuxki_write(sc, chano, EMU_CHAN_IFATN_ATTENUATION, 0xff);
1351: emuxki_write(sc, chano, EMU_CHAN_VTFT_VOLUMETARGET, 0);
1352: emuxki_write(sc, chano, EMU_CHAN_CVCF_CURRVOL, 0);
1353: emuxki_write(sc, chano, EMU_CHAN_IP, 0);
1354: splx(s);
1355: }
1356:
1357: /*
1358: * Voices management
1359: * emuxki_voice_dataloc : use(play or rec) independent dataloc union helpers
1360: * emuxki_voice_channel_* : play part of dataloc union helpers
1361: * emuxki_voice_recsrc_* : rec part of dataloc union helpers
1362: */
1363:
1364: /* Allocate channels for voice in case of play voice */
1365: int
1366: emuxki_voice_channel_create(struct emuxki_voice *voice)
1367: {
1368: struct emuxki_channel **channel = voice->sc->channel;
1369: u_int8_t i, stereo = voice->stereo;
1370: int s;
1371:
1372: for (i = 0; i < EMU_NUMCHAN; i += stereo + 1) {
1373: if ((stereo && (channel[i + 1] != NULL)) ||
1374: (channel[i] != NULL)) /* Looking for free channels */
1375: continue;
1376: s = splaudio();
1377: if (stereo) {
1378: voice->dataloc.chan[1] =
1379: emuxki_channel_new(voice, i + 1);
1380: if (voice->dataloc.chan[1] == NULL) {
1381: splx(s);
1382: return (ENOMEM);
1383: }
1384: }
1385: voice->dataloc.chan[0] = emuxki_channel_new(voice, i);
1386: if (voice->dataloc.chan[0] == NULL) {
1387: if (stereo) {
1388: emuxki_channel_delete(voice->dataloc.chan[1]);
1389: voice->dataloc.chan[1] = NULL;
1390: }
1391: splx(s);
1392: return (ENOMEM);
1393: }
1394: splx(s);
1395: return (0);
1396: }
1397: return (EAGAIN);
1398: }
1399:
1400: /* When calling this function we assume no one can access the voice */
1401: void
1402: emuxki_voice_channel_destroy(struct emuxki_voice *voice)
1403: {
1404: emuxki_channel_delete(voice->dataloc.chan[0]);
1405: voice->dataloc.chan[0] = NULL;
1406: if (voice->stereo)
1407: emuxki_channel_delete(voice->dataloc.chan[1]);
1408: voice->dataloc.chan[1] = NULL;
1409: }
1410:
1411: /*
1412: * Will come back when used in voice_dataloc_create
1413: */
1414: int
1415: emuxki_recsrc_reserve(struct emuxki_voice *voice, emuxki_recsrc_t source)
1416: {
1417: if (source < 0 || source >= EMU_NUMRECSRCS) {
1418: #ifdef EMUXKI_DEBUG
1419: printf("Tried to reserve invalid source: %d\n", source);
1420: #endif
1421: return (EINVAL);
1422: }
1423: if (voice->sc->recsrc[source] == voice)
1424: return (0); /* XXX */
1425: if (voice->sc->recsrc[source] != NULL)
1426: return (EBUSY);
1427: voice->sc->recsrc[source] = voice;
1428: return (0);
1429: }
1430:
1431: /* When calling this function we assume the voice is stopped */
1432: void
1433: emuxki_voice_recsrc_release(struct emuxki_softc *sc, emuxki_recsrc_t source)
1434: {
1435: sc->recsrc[source] = NULL;
1436: }
1437:
1438: int
1439: emuxki_voice_dataloc_create(struct emuxki_voice *voice)
1440: {
1441: int error;
1442:
1443: if (voice->use & EMU_VOICE_USE_PLAY) {
1444: if ((error = emuxki_voice_channel_create(voice)))
1445: return (error);
1446: } else {
1447: if ((error =
1448: emuxki_recsrc_reserve(voice, voice->dataloc.source)))
1449: return (error);
1450: }
1451: return (0);
1452: }
1453:
1454: void
1455: emuxki_voice_dataloc_destroy(struct emuxki_voice *voice)
1456: {
1457: if (voice->use & EMU_VOICE_USE_PLAY) {
1458: if (voice->dataloc.chan[0] != NULL)
1459: emuxki_voice_channel_destroy(voice);
1460: } else {
1461: if (voice->dataloc.source != EMU_RECSRC_NOTSET) {
1462: emuxki_voice_recsrc_release(voice->sc,
1463: voice->dataloc.source);
1464: voice->dataloc.source = EMU_RECSRC_NOTSET;
1465: }
1466: }
1467: }
1468:
1469: struct emuxki_voice *
1470: emuxki_voice_new(struct emuxki_softc *sc, u_int8_t use)
1471: {
1472: struct emuxki_voice *voice;
1473: int s;
1474:
1475: s = splaudio();
1476: voice = sc->lvoice;
1477: sc->lvoice = NULL;
1478: splx(s);
1479:
1480: if (!voice) {
1481: if (!(voice = malloc(sizeof(*voice), M_DEVBUF, M_WAITOK)))
1482: return (NULL);
1483: } else if (voice->use != use)
1484: emuxki_voice_dataloc_destroy(voice);
1485: else
1486: goto skip_initialize;
1487:
1488: voice->sc = sc;
1489: voice->state = !EMU_VOICE_STATE_STARTED;
1490: voice->stereo = EMU_VOICE_STEREO_NOTSET;
1491: voice->b16 = 0;
1492: voice->sample_rate = 0;
1493: if (use & EMU_VOICE_USE_PLAY)
1494: voice->dataloc.chan[0] = voice->dataloc.chan[1] = NULL;
1495: else
1496: voice->dataloc.source = EMU_RECSRC_NOTSET;
1497: voice->buffer = NULL;
1498: voice->blksize = 0;
1499: voice->trigblk = 0;
1500: voice->blkmod = 0;
1501: voice->inth = NULL;
1502: voice->inthparam = NULL;
1503: voice->use = use;
1504:
1505: skip_initialize:
1506: s = splaudio();
1507: LIST_INSERT_HEAD((&sc->voices), voice, next);
1508: splx(s);
1509:
1510: return (voice);
1511: }
1512:
1513: void
1514: emuxki_voice_delete(struct emuxki_voice *voice)
1515: {
1516: struct emuxki_softc *sc = voice->sc;
1517: struct emuxki_voice *lvoice;
1518: int s;
1519:
1520: if (voice->state & EMU_VOICE_STATE_STARTED)
1521: emuxki_voice_halt(voice);
1522:
1523: s = splaudio();
1524: LIST_REMOVE(voice, next);
1525: lvoice = sc->lvoice;
1526: sc->lvoice = voice;
1527: splx(s);
1528:
1529: if (lvoice) {
1530: emuxki_voice_dataloc_destroy(lvoice);
1531: free(lvoice, M_DEVBUF);
1532: }
1533: }
1534:
1535: int
1536: emuxki_voice_set_stereo(struct emuxki_voice *voice, u_int8_t stereo)
1537: {
1538: int error;
1539: emuxki_recsrc_t source = 0; /* XXX: gcc */
1540: struct emuxki_chanparms_fxsend fxsend;
1541:
1542: if (! (voice->use & EMU_VOICE_USE_PLAY))
1543: source = voice->dataloc.source;
1544: emuxki_voice_dataloc_destroy(voice);
1545: if (! (voice->use & EMU_VOICE_USE_PLAY))
1546: voice->dataloc.source = source;
1547: voice->stereo = stereo;
1548: if ((error = emuxki_voice_dataloc_create(voice)))
1549: return (error);
1550: if (voice->use & EMU_VOICE_USE_PLAY) {
1551: fxsend.a.dest = 0x0;
1552: fxsend.b.dest = 0x1;
1553: fxsend.c.dest = 0x2;
1554: fxsend.d.dest = 0x3;
1555: /* for audigy */
1556: fxsend.e.dest = 0x4;
1557: fxsend.f.dest = 0x5;
1558: fxsend.g.dest = 0x6;
1559: fxsend.h.dest = 0x7;
1560: if (voice->stereo) {
1561: fxsend.a.level = fxsend.c.level = 0xc0;
1562: fxsend.b.level = fxsend.d.level = 0x00;
1563: fxsend.e.level = fxsend.g.level = 0xc0;
1564: fxsend.f.level = fxsend.h.level = 0x00;
1565: emuxki_channel_set_fxsend(voice->dataloc.chan[0],
1566: &fxsend);
1567: fxsend.a.level = fxsend.c.level = 0x00;
1568: fxsend.b.level = fxsend.d.level = 0xc0;
1569: fxsend.e.level = fxsend.g.level = 0x00;
1570: fxsend.f.level = fxsend.h.level = 0xc0;
1571: emuxki_channel_set_fxsend(voice->dataloc.chan[1],
1572: &fxsend);
1573: } /* No else : default is good for mono */
1574: }
1575: return (0);
1576: }
1577:
1578: int
1579: emuxki_voice_set_srate(struct emuxki_voice *voice, u_int32_t srate)
1580: {
1581: if (voice->use & EMU_VOICE_USE_PLAY) {
1582: if ((srate < 4000) || (srate > 48000))
1583: return (EINVAL);
1584: voice->sample_rate = srate;
1585: emuxki_channel_set_srate(voice->dataloc.chan[0], srate);
1586: if (voice->stereo)
1587: emuxki_channel_set_srate(voice->dataloc.chan[1],
1588: srate);
1589: } else {
1590: if ((srate < 8000) || (srate > 48000))
1591: return (EINVAL);
1592: voice->sample_rate = srate;
1593: if (emuxki_voice_adc_rate(voice) < 0) {
1594: voice->sample_rate = 0;
1595: return (EINVAL);
1596: }
1597: }
1598: return (0);
1599: }
1600:
1601: int
1602: emuxki_voice_set_audioparms(struct emuxki_voice *voice, u_int8_t stereo,
1603: u_int8_t b16, u_int32_t srate)
1604: {
1605: int error = 0;
1606:
1607: /*
1608: * Audio driver tried to set recording AND playing params even if
1609: * device opened in play or record only mode ==>
1610: * modified emuxki_set_params.
1611: * Stays here for now just in case ...
1612: */
1613: if (voice == NULL) {
1614: #ifdef EMUXKI_DEBUG
1615: printf("warning: tried to set unallocated voice params !!\n");
1616: #endif
1617: return (0);
1618: }
1619:
1620: if (voice->stereo == stereo && voice->b16 == b16 &&
1621: voice->sample_rate == srate)
1622: return (0);
1623:
1624: #ifdef EMUXKI_DEBUG
1625: printf("Setting %s voice params : %s, %u bits, %u hz\n",
1626: (voice->use & EMU_VOICE_USE_PLAY) ? "play" : "record",
1627: stereo ? "stereo" : "mono", (b16 + 1) * 8, srate);
1628: #endif
1629:
1630: if (voice->stereo != stereo) {
1631: if ((error = emuxki_voice_set_stereo(voice, stereo)))
1632: return (error);
1633: }
1634: voice->b16 = b16;
1635: if (voice->sample_rate != srate)
1636: error = emuxki_voice_set_srate(voice, srate);
1637: return error;
1638: }
1639:
1640: /* voice audio parms (see just before) must be set prior to this */
1641: int
1642: emuxki_voice_set_bufparms(struct emuxki_voice *voice, void *ptr,
1643: u_int32_t bufsize, u_int16_t blksize)
1644: {
1645: struct emuxki_mem *mem;
1646: struct emuxki_channel **chan;
1647: u_int32_t start, end;
1648: u_int8_t sample_size;
1649: int idx;
1650: int error = EFAULT;
1651:
1652: LIST_FOREACH(mem, &voice->sc->mem, next) {
1653: if (KERNADDR(mem->dmamem) != ptr)
1654: continue;
1655:
1656: voice->buffer = mem;
1657: sample_size = (voice->b16 + 1) * (voice->stereo + 1);
1658: voice->trigblk = 0; /* This shouldn't be needed */
1659: voice->blkmod = bufsize / blksize;
1660: if (bufsize % blksize) /* This should not happen */
1661: voice->blkmod++;
1662: error = 0;
1663:
1664: if (voice->use & EMU_VOICE_USE_PLAY) {
1665: voice->blksize = blksize / sample_size;
1666: chan = voice->dataloc.chan;
1667: start = (mem->ptbidx << 12) / sample_size;
1668: end = start + bufsize / sample_size;
1669: emuxki_channel_set_bufparms(chan[0],
1670: start, end);
1671: if (voice->stereo)
1672: emuxki_channel_set_bufparms(chan[1],
1673: start, end);
1674: voice->timerate = (u_int32_t) 48000 *
1675: voice->blksize / voice->sample_rate;
1676: if (voice->timerate < 5)
1677: error = EINVAL;
1678: } else {
1679: voice->blksize = blksize;
1680: for(idx = sizeof(emuxki_recbuf_sz) /
1681: sizeof(emuxki_recbuf_sz[0]); --idx >= 0;)
1682: if (emuxki_recbuf_sz[idx] == bufsize)
1683: break;
1684: if (idx < 0) {
1685: #ifdef EMUXKI_DEBUG
1686: printf("Invalid bufsize: %d\n", bufsize);
1687: #endif
1688: return (EINVAL);
1689: }
1690: emuxki_write(voice->sc, 0,
1691: emuxki_recsrc_szreg[voice->dataloc.source], idx);
1692: emuxki_write(voice->sc, 0,
1693: emuxki_recsrc_bufaddrreg[voice->dataloc.source],
1694: DMAADDR(mem->dmamem));
1695:
1696: /* Use timer to emulate DMA completion interrupt */
1697: voice->timerate = (u_int32_t) 48000 * blksize /
1698: (voice->sample_rate * sample_size);
1699: if (voice->timerate < 5) {
1700: #ifdef EMUXKI_DEBUG
1701: printf("Invalid timerate: %d, blksize %d\n",
1702: voice->timerate, blksize);
1703: #endif
1704: error = EINVAL;
1705: }
1706: }
1707:
1708: break;
1709: }
1710:
1711: return (error);
1712: }
1713:
1714: void
1715: emuxki_voice_commit_parms(struct emuxki_voice *voice)
1716: {
1717: if (voice->use & EMU_VOICE_USE_PLAY) {
1718: emuxki_channel_commit_parms(voice->dataloc.chan[0]);
1719: if (voice->stereo)
1720: emuxki_channel_commit_parms(voice->dataloc.chan[1]);
1721: }
1722: }
1723:
1724: u_int32_t
1725: emuxki_voice_curaddr(struct emuxki_voice *voice)
1726: {
1727: int idxreg = 0;
1728:
1729: /* XXX different semantics in these cases */
1730: if (voice->use & EMU_VOICE_USE_PLAY) {
1731: /* returns number of samples (an l/r pair counts 1) */
1732: return (emuxki_read(voice->sc,
1733: voice->dataloc.chan[0]->num,
1734: EMU_CHAN_CCCA_CURRADDR) -
1735: voice->dataloc.chan[0]->loop.start);
1736: } else {
1737: /* returns number of bytes */
1738: switch (voice->dataloc.source) {
1739: case EMU_RECSRC_MIC:
1740: idxreg = (voice->sc->sc_type & EMUXKI_AUDIGY) ?
1741: EMU_A_MICIDX : EMU_MICIDX;
1742: break;
1743: case EMU_RECSRC_ADC:
1744: idxreg = (voice->sc->sc_type & EMUXKI_AUDIGY) ?
1745: EMU_A_ADCIDX : EMU_ADCIDX;
1746: break;
1747: case EMU_RECSRC_FX:
1748: idxreg = EMU_FXIDX;
1749: break;
1750: default:
1751: #ifdef EMUXKI_DEBUG
1752: printf("emu: bad recording source!\n");
1753: #endif
1754: break;
1755: }
1756: return (emuxki_read(voice->sc, 0, EMU_RECIDX(idxreg))
1757: & EMU_RECIDX_MASK);
1758: }
1759: return (0);
1760: }
1761:
1762: void
1763: emuxki_resched_timer(struct emuxki_softc *sc)
1764: {
1765: struct emuxki_voice *voice;
1766: u_int16_t timerate = 1024;
1767: u_int8_t active = 0;
1768: int s;
1769:
1770: s = splaudio();
1771: LIST_FOREACH(voice, &sc->voices, next) {
1772: if ((voice->state & EMU_VOICE_STATE_STARTED) == 0)
1773: continue;
1774: active = 1;
1775: if (voice->timerate < timerate)
1776: timerate = voice->timerate;
1777: }
1778:
1779: if (timerate & ~EMU_TIMER_RATE_MASK)
1780: timerate = 0;
1781: bus_space_write_2(sc->sc_iot, sc->sc_ioh, EMU_TIMER, timerate);
1782: if (!active && (sc->timerstate & EMU_TIMER_STATE_ENABLED)) {
1783: bus_space_write_4(sc->sc_iot, sc->sc_ioh, EMU_INTE,
1784: bus_space_read_4(sc->sc_iot, sc->sc_ioh, EMU_INTE) &
1785: ~EMU_INTE_INTERTIMERENB);
1786: sc->timerstate &= ~EMU_TIMER_STATE_ENABLED;
1787: } else if (active && !(sc->timerstate & EMU_TIMER_STATE_ENABLED)) {
1788: bus_space_write_4(sc->sc_iot, sc->sc_ioh, EMU_INTE,
1789: bus_space_read_4(sc->sc_iot, sc->sc_ioh, EMU_INTE) |
1790: EMU_INTE_INTERTIMERENB);
1791: sc->timerstate |= EMU_TIMER_STATE_ENABLED;
1792: }
1793: splx(s);
1794: }
1795:
1796: int
1797: emuxki_voice_adc_rate(struct emuxki_voice *voice)
1798: {
1799: switch(voice->sample_rate) {
1800: case 48000:
1801: return EMU_ADCCR_SAMPLERATE_48;
1802: break;
1803: case 44100:
1804: return EMU_ADCCR_SAMPLERATE_44;
1805: break;
1806: case 32000:
1807: return EMU_ADCCR_SAMPLERATE_32;
1808: break;
1809: case 24000:
1810: return EMU_ADCCR_SAMPLERATE_24;
1811: break;
1812: case 22050:
1813: return EMU_ADCCR_SAMPLERATE_22;
1814: break;
1815: case 16000:
1816: return EMU_ADCCR_SAMPLERATE_16;
1817: break;
1818: case 12000:
1819: if(voice->sc->sc_type & EMUXKI_AUDIGY)
1820: return EMU_A_ADCCR_SAMPLERATE_12;
1821: else {
1822: #ifdef EMUXKI_DEBUG
1823: printf("recording sample_rate not supported : %u\n", voice->sample_rate);
1824: #endif
1825: return (-1);
1826: }
1827: break;
1828: case 11000:
1829: if(voice->sc->sc_type & EMUXKI_AUDIGY)
1830: return EMU_A_ADCCR_SAMPLERATE_11;
1831: else
1832: return EMU_ADCCR_SAMPLERATE_11;
1833: break;
1834: case 8000:
1835: if(voice->sc->sc_type & EMUXKI_AUDIGY)
1836: return EMU_A_ADCCR_SAMPLERATE_8;
1837: else
1838: return EMU_ADCCR_SAMPLERATE_8;
1839: break;
1840: default:
1841: #ifdef EMUXKI_DEBUG
1842: printf("recording sample_rate not supported : %u\n", voice->sample_rate);
1843: #endif
1844: return (-1);
1845: }
1846: return (-1); /* shouldn't get here */
1847: }
1848:
1849: void
1850: emuxki_voice_start(struct emuxki_voice *voice,
1851: void (*inth) (void *), void *inthparam)
1852: {
1853: u_int32_t val;
1854:
1855: voice->inth = inth;
1856: voice->inthparam = inthparam;
1857: if (voice->use & EMU_VOICE_USE_PLAY) {
1858: voice->trigblk = 1;
1859: emuxki_channel_start(voice->dataloc.chan[0]);
1860: if (voice->stereo)
1861: emuxki_channel_start(voice->dataloc.chan[1]);
1862: } else {
1863: voice->trigblk = 1;
1864: switch (voice->dataloc.source) {
1865: case EMU_RECSRC_ADC:
1866: /* XXX need to program DSP to output L+R
1867: * XXX in monaural case? */
1868: if (voice->sc->sc_type & EMUXKI_AUDIGY) {
1869: val = EMU_A_ADCCR_LCHANENABLE;
1870: if (voice->stereo)
1871: val |= EMU_A_ADCCR_RCHANENABLE;
1872: } else {
1873: val = EMU_ADCCR_LCHANENABLE;
1874: if (voice->stereo)
1875: val |= EMU_ADCCR_RCHANENABLE;
1876: }
1877: val |= emuxki_voice_adc_rate(voice);
1878: emuxki_write(voice->sc, 0, EMU_ADCCR, 0);
1879: emuxki_write(voice->sc, 0, EMU_ADCCR, val);
1880: break;
1881: case EMU_RECSRC_MIC:
1882: case EMU_RECSRC_FX:
1883: printf("unimplemented\n");
1884: break;
1885: case EMU_RECSRC_NOTSET:
1886: default:
1887: break;
1888: }
1889: #if 0
1890: /* DMA completion interrupt is useless; use timer */
1891: int s;
1892: s = splaudio();
1893: val = emu_rd(sc, INTE, 4);
1894: val |= emuxki_recsrc_intrmasks[voice->dataloc.source];
1895: emu_wr(sc, INTE, val, 4);
1896: splx(s);
1897: #endif
1898: }
1899: voice->state |= EMU_VOICE_STATE_STARTED;
1900: emuxki_resched_timer(voice->sc);
1901: }
1902:
1903: void
1904: emuxki_voice_halt(struct emuxki_voice *voice)
1905: {
1906: if (voice->use & EMU_VOICE_USE_PLAY) {
1907: emuxki_channel_stop(voice->dataloc.chan[0]);
1908: if (voice->stereo)
1909: emuxki_channel_stop(voice->dataloc.chan[1]);
1910: } else {
1911: switch (voice->dataloc.source) {
1912: case EMU_RECSRC_ADC:
1913: emuxki_write(voice->sc, 0, EMU_ADCCR, 0);
1914: break;
1915: case EMU_RECSRC_FX:
1916: case EMU_RECSRC_MIC:
1917: printf("unimplemented\n");
1918: break;
1919: case EMU_RECSRC_NOTSET:
1920: printf("Bad dataloc.source\n");
1921: }
1922: /* This should reset buffer pointer */
1923: emuxki_write(voice->sc, 0,
1924: emuxki_recsrc_szreg[voice->dataloc.source],
1925: EMU_RECBS_BUFSIZE_NONE);
1926: #if 0
1927: int s;
1928: s = splaudio();
1929: val = emu_rd(sc, INTE, 4);
1930: val &= ~emuxki_recsrc_intrmasks[voice->dataloc.source];
1931: emu_wr(sc, INTE, val, 4);
1932: splx(s);
1933: #endif
1934: }
1935: voice->state &= ~EMU_VOICE_STATE_STARTED;
1936: emuxki_resched_timer(voice->sc);
1937: }
1938:
1939: /*
1940: * The interrupt handler
1941: */
1942: int
1943: emuxki_intr(void *arg)
1944: {
1945: struct emuxki_softc *sc = arg;
1946: u_int32_t ipr, curblk, us = 0;
1947: struct emuxki_voice *voice;
1948:
1949: while ((ipr = bus_space_read_4(sc->sc_iot, sc->sc_ioh, EMU_IPR))) {
1950: if (ipr & EMU_IPR_INTERVALTIMER) {
1951: LIST_FOREACH(voice, &sc->voices, next) {
1952: if ((voice->state &
1953: EMU_VOICE_STATE_STARTED) == 0)
1954: continue;
1955:
1956: curblk = emuxki_voice_curaddr(voice) /
1957: voice->blksize;
1958: #if 0
1959: if (curblk == voice->trigblk) {
1960: voice->inth(voice->inthparam);
1961: voice->trigblk++;
1962: voice->trigblk %= voice->blkmod;
1963: }
1964: #else
1965: while ((curblk >= voice->trigblk &&
1966: curblk < (voice->trigblk + voice->blkmod / 2)) ||
1967: ((int)voice->trigblk - (int)curblk) >
1968: (voice->blkmod / 2 + 1)) {
1969: voice->inth(voice->inthparam);
1970: voice->trigblk++;
1971: voice->trigblk %= voice->blkmod;
1972: }
1973: #endif
1974: }
1975: us = 1;
1976: }
1977:
1978: /* Got interrupt */
1979: bus_space_write_4(sc->sc_iot, sc->sc_ioh, EMU_IPR, ipr);
1980: }
1981:
1982: return (us);
1983: }
1984:
1985:
1986: /*
1987: * Audio Architecture callbacks
1988: */
1989:
1990: int
1991: emuxki_open(void *addr, int flags)
1992: {
1993: struct emuxki_softc *sc = addr;
1994:
1995: #ifdef EMUXKI_DEBUG
1996: printf("%s: emuxki_open called\n", sc->sc_dev.dv_xname);
1997: #endif
1998:
1999: /*
2000: * Multiple voice support would be added as soon as I find a way to
2001: * trick the audio arch into supporting multiple voices.
2002: * Or I might integrate a modified audio arch supporting
2003: * multiple voices.
2004: */
2005:
2006: /*
2007: * I did this because i have problems identifying the selected
2008: * recording source(s) which is necessary when setting recording
2009: * params. This will be addressed very soon.
2010: */
2011: if (flags & AUOPEN_READ) {
2012: sc->rvoice = emuxki_voice_new(sc, 0 /* EMU_VOICE_USE_RECORD */);
2013: if (sc->rvoice == NULL)
2014: return (EBUSY);
2015:
2016: /* XXX Hardcode RECSRC_ADC for now */
2017: sc->rvoice->dataloc.source = EMU_RECSRC_ADC;
2018: }
2019:
2020: if (flags & AUOPEN_WRITE) {
2021: sc->pvoice = emuxki_voice_new(sc, EMU_VOICE_USE_PLAY);
2022: if (sc->pvoice == NULL) {
2023: if (flags & AUOPEN_READ)
2024: emuxki_voice_delete(sc->rvoice);
2025: return (EBUSY);
2026: }
2027: }
2028:
2029: return (0);
2030: }
2031:
2032: void
2033: emuxki_close(void *addr)
2034: {
2035: struct emuxki_softc *sc = addr;
2036:
2037: #ifdef EMUXKI_DEBUG
2038: printf("%s: emu10K1_close called\n", sc->sc_dev.dv_xname);
2039: #endif
2040:
2041: /* No multiple voice support for now */
2042: if (sc->rvoice != NULL)
2043: emuxki_voice_delete(sc->rvoice);
2044: sc->rvoice = NULL;
2045: if (sc->pvoice != NULL)
2046: emuxki_voice_delete(sc->pvoice);
2047: sc->pvoice = NULL;
2048: }
2049:
2050: int
2051: emuxki_query_encoding(void *addr, struct audio_encoding *fp)
2052: {
2053: #ifdef EMUXKI_DEBUG
2054: struct emuxki_softc *sc = addr;
2055:
2056: printf("%s: emuxki_query_encoding called\n", sc->sc_dev.dv_xname);
2057: #endif
2058:
2059: switch (fp->index) {
2060: case 0:
2061: strlcpy(fp->name, AudioEulinear, sizeof fp->name);
2062: fp->encoding = AUDIO_ENCODING_ULINEAR;
2063: fp->precision = 8;
2064: fp->flags = 0;
2065: break;
2066: case 1:
2067: strlcpy(fp->name, AudioEmulaw, sizeof fp->name);
2068: fp->encoding = AUDIO_ENCODING_ULAW;
2069: fp->precision = 8;
2070: fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
2071: break;
2072: case 2:
2073: strlcpy(fp->name, AudioEalaw, sizeof fp->name);
2074: fp->encoding = AUDIO_ENCODING_ALAW;
2075: fp->precision = 8;
2076: fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
2077: break;
2078: case 3:
2079: strlcpy(fp->name, AudioEslinear, sizeof fp->name);
2080: fp->encoding = AUDIO_ENCODING_SLINEAR;
2081: fp->precision = 8;
2082: fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
2083: break;
2084: case 4:
2085: strlcpy(fp->name, AudioEslinear_le, sizeof fp->name);
2086: fp->encoding = AUDIO_ENCODING_SLINEAR_LE;
2087: fp->precision = 16;
2088: fp->flags = 0;
2089: break;
2090: case 5:
2091: strlcpy(fp->name, AudioEulinear_le, sizeof fp->name);
2092: fp->encoding = AUDIO_ENCODING_ULINEAR_LE;
2093: fp->precision = 16;
2094: fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
2095: break;
2096: case 6:
2097: strlcpy(fp->name, AudioEslinear_be, sizeof fp->name);
2098: fp->encoding = AUDIO_ENCODING_SLINEAR_BE;
2099: fp->precision = 16;
2100: fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
2101: break;
2102: case 7:
2103: strlcpy(fp->name, AudioEulinear_be, sizeof fp->name);
2104: fp->encoding = AUDIO_ENCODING_ULINEAR_BE;
2105: fp->precision = 16;
2106: fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
2107: break;
2108: default:
2109: return (EINVAL);
2110: }
2111: return (0);
2112: }
2113:
2114: int
2115: emuxki_set_vparms(struct emuxki_voice *voice, struct audio_params *p)
2116: {
2117: u_int8_t b16, mode;
2118:
2119: mode = (voice->use & EMU_VOICE_USE_PLAY) ?
2120: AUMODE_PLAY : AUMODE_RECORD;
2121: p->factor = 1;
2122: p->sw_code = NULL;
2123: if (p->channels != 1 && p->channels != 2)
2124: return (EINVAL);/* Will change when streams come in use */
2125:
2126: /*
2127: * Always use slinear_le for recording, as how to set otherwise
2128: * isn't known.
2129: */
2130: if (mode == AUMODE_PLAY)
2131: b16 = (p->precision == 16);
2132: else {
2133: b16 = 1;
2134: if (p->precision == 8)
2135: p->factor *= 2;
2136: }
2137:
2138: switch (p->encoding) {
2139: case AUDIO_ENCODING_ULAW:
2140: if (mode == AUMODE_PLAY) {
2141: p->factor = 2;
2142: p->sw_code = mulaw_to_slinear16_le;
2143: b16 = 1;
2144: } else
2145: p->sw_code = slinear16_to_mulaw_le;
2146: break;
2147:
2148: case AUDIO_ENCODING_ALAW:
2149: if (mode == AUMODE_PLAY) {
2150: p->factor = 2;
2151: p->sw_code = alaw_to_slinear16_le;
2152: b16 = 1;
2153: } else
2154: p->sw_code = slinear16_to_alaw_le;
2155: break;
2156:
2157: case AUDIO_ENCODING_SLINEAR_LE:
2158: if (p->precision == 8) {
2159: if (mode == AUMODE_PLAY)
2160: p->sw_code = change_sign8;
2161: else
2162: p->sw_code = linear16_to_linear8_le;
2163: }
2164: break;
2165:
2166: case AUDIO_ENCODING_ULINEAR_LE:
2167: if (p->precision == 16)
2168: p->sw_code = change_sign16_le;
2169: else if (mode == AUMODE_RECORD)
2170: p->sw_code = slinear16_to_ulinear8_le;
2171: break;
2172:
2173: case AUDIO_ENCODING_SLINEAR_BE:
2174: if (p->precision == 16)
2175: p->sw_code = swap_bytes;
2176: else {
2177: if (mode == AUMODE_PLAY)
2178: p->sw_code = change_sign8;
2179: else
2180: p->sw_code = linear16_to_linear8_le;
2181: }
2182: break;
2183:
2184: case AUDIO_ENCODING_ULINEAR_BE:
2185: if (p->precision == 16) {
2186: if (mode == AUMODE_PLAY)
2187: p->sw_code = swap_bytes_change_sign16_le;
2188: else
2189: p->sw_code = change_sign16_swap_bytes_le;
2190: } else if (mode == AUMODE_RECORD)
2191: p->sw_code = slinear16_to_ulinear8_le;
2192: break;
2193:
2194: default:
2195: return (EINVAL);
2196: }
2197:
2198: return (emuxki_voice_set_audioparms(voice, p->channels == 2,
2199: b16, p->sample_rate));
2200: }
2201:
2202: int
2203: emuxki_set_params(void *addr, int setmode, int usemode,
2204: struct audio_params *play, struct audio_params *rec)
2205: {
2206: struct emuxki_softc *sc = addr;
2207: int mode, error;
2208: struct audio_params *p;
2209:
2210: for (mode = AUMODE_RECORD; mode != -1;
2211: mode = mode == AUMODE_RECORD ? AUMODE_PLAY : -1) {
2212: if ((usemode & setmode & mode) == 0)
2213: continue;
2214:
2215: p = (mode == AUMODE_PLAY) ? play : rec;
2216:
2217: /* No multiple voice support for now */
2218: if ((error = emuxki_set_vparms((mode == AUMODE_PLAY) ?
2219: sc->pvoice : sc->rvoice, p)))
2220: return (error);
2221: }
2222:
2223: return (0);
2224: }
2225:
2226: int
2227: emuxki_halt_output(void *addr)
2228: {
2229: struct emuxki_softc *sc = addr;
2230:
2231: /* No multiple voice support for now */
2232: if (sc->pvoice == NULL)
2233: return (ENXIO);
2234:
2235: emuxki_voice_halt(sc->pvoice);
2236: return (0);
2237: }
2238:
2239: int
2240: emuxki_halt_input(void *addr)
2241: {
2242: struct emuxki_softc *sc = addr;
2243:
2244: #ifdef EMUXKI_DEBUG
2245: printf("%s: emuxki_halt_input called\n", sc->sc_dev.dv_xname);
2246: #endif
2247:
2248: /* No multiple voice support for now */
2249: if (sc->rvoice == NULL)
2250: return (ENXIO);
2251: emuxki_voice_halt(sc->rvoice);
2252: return (0);
2253: }
2254:
2255: int
2256: emuxki_getdev(void *v, struct audio_device *adp)
2257: {
2258: struct emuxki_softc *sc = v;
2259: *adp = sc->sc_audv;
2260: return 0;
2261: }
2262:
2263: int
2264: emuxki_set_port(void *addr, mixer_ctrl_t *mctl)
2265: {
2266: struct emuxki_softc *sc = addr;
2267:
2268: return sc->codecif->vtbl->mixer_set_port(sc->codecif, mctl);
2269: }
2270:
2271: int
2272: emuxki_get_port(void *addr, mixer_ctrl_t *mctl)
2273: {
2274: struct emuxki_softc *sc = addr;
2275:
2276: return sc->codecif->vtbl->mixer_get_port(sc->codecif, mctl);
2277: }
2278:
2279: int
2280: emuxki_query_devinfo(void *addr, mixer_devinfo_t *minfo)
2281: {
2282: struct emuxki_softc *sc = addr;
2283:
2284: return sc->codecif->vtbl->query_devinfo(sc->codecif, minfo);
2285: }
2286:
2287: void *
2288: emuxki_allocm(void *addr, int direction, size_t size, int type, int flags)
2289: {
2290: struct emuxki_softc *sc = addr;
2291:
2292: if (direction == AUMODE_PLAY)
2293: return emuxki_pmem_alloc(sc, size, type, flags);
2294: else
2295: return emuxki_rmem_alloc(sc, size, type, flags);
2296: }
2297:
2298: void
2299: emuxki_freem(void *addr, void *ptr, int type)
2300: {
2301: struct emuxki_softc *sc = addr;
2302: int i, s;
2303: struct emuxki_mem *mem;
2304: size_t numblocks;
2305: u_int32_t *ptb, silentpage;
2306:
2307: ptb = KERNADDR(sc->ptb);
2308: silentpage = DMAADDR(sc->silentpage) << 1;
2309: LIST_FOREACH(mem, &sc->mem, next) {
2310: if (KERNADDR(mem->dmamem) != ptr)
2311: continue;
2312:
2313: s = splaudio();
2314: if (mem->ptbidx != EMU_RMEM) {
2315: numblocks = DMASIZE(mem->dmamem) / EMU_PTESIZE;
2316: if (DMASIZE(mem->dmamem) % EMU_PTESIZE)
2317: numblocks++;
2318: for (i = 0; i < numblocks; i++)
2319: ptb[mem->ptbidx + i] =
2320: htole32(silentpage | (mem->ptbidx + i));
2321: }
2322: LIST_REMOVE(mem, next);
2323: splx(s);
2324:
2325: emuxki_mem_delete(mem, type);
2326: break;
2327: }
2328: }
2329:
2330: /* blocksize should be a divisor of allowable buffersize */
2331: /* XXX probably this could be done better */
2332: int
2333: emuxki_round_blocksize(void *addr, int blksize)
2334: {
2335: int bufsize = 65536;
2336:
2337: while (bufsize > blksize)
2338: bufsize /= 2;
2339:
2340: return bufsize;
2341: }
2342:
2343: size_t
2344: emuxki_round_buffersize(void *addr, int direction, size_t bsize)
2345: {
2346:
2347: if (direction == AUMODE_PLAY) {
2348: if (bsize < EMU_PTESIZE)
2349: bsize = EMU_PTESIZE;
2350: else if (bsize > (EMU_PTESIZE * EMU_MAXPTE))
2351: bsize = EMU_PTESIZE * EMU_MAXPTE;
2352: /* Would be better if set to max available */
2353: else if (bsize % EMU_PTESIZE)
2354: bsize = bsize -
2355: (bsize % EMU_PTESIZE) +
2356: EMU_PTESIZE;
2357: } else {
2358: int idx;
2359:
2360: /* find nearest lower recbuf size */
2361: for(idx = sizeof(emuxki_recbuf_sz) /
2362: sizeof(emuxki_recbuf_sz[0]); --idx >= 0; ) {
2363: if (bsize >= emuxki_recbuf_sz[idx]) {
2364: bsize = emuxki_recbuf_sz[idx];
2365: break;
2366: }
2367: }
2368:
2369: if (bsize == 0)
2370: bsize = 384;
2371: }
2372:
2373: return (bsize);
2374: }
2375:
2376: paddr_t
2377: emuxki_mappage(void *addr, void *ptr, off_t off, int prot)
2378: {
2379: struct emuxki_softc *sc = addr;
2380: struct emuxki_mem *mem;
2381:
2382: LIST_FOREACH(mem, &sc->mem, next) {
2383: if (KERNADDR(mem->dmamem) == ptr) {
2384: struct dmamem *dm = mem->dmamem;
2385:
2386: return bus_dmamem_mmap(dm->dmat, dm->segs, dm->nsegs,
2387: off, prot, BUS_DMA_WAITOK);
2388: }
2389: }
2390:
2391: return (-1);
2392: }
2393:
2394: int
2395: emuxki_get_props(void *addr)
2396: {
2397: return (AUDIO_PROP_MMAP | AUDIO_PROP_INDEPENDENT |
2398: AUDIO_PROP_FULLDUPLEX);
2399: }
2400:
2401: int
2402: emuxki_trigger_output(void *addr, void *start, void *end, int blksize,
2403: void (*inth) (void *), void *inthparam,
2404: struct audio_params *params)
2405: {
2406: struct emuxki_softc *sc = addr;
2407: /* No multiple voice support for now */
2408: struct emuxki_voice *voice = sc->pvoice;
2409: int error;
2410:
2411: if (voice == NULL)
2412: return (ENXIO);
2413: if ((error = emuxki_set_vparms(voice, params)))
2414: return (error);
2415: if ((error = emuxki_voice_set_bufparms(voice, start,
2416: (caddr_t)end - (caddr_t)start, blksize)))
2417: return (error);
2418: emuxki_voice_commit_parms(voice);
2419: emuxki_voice_start(voice, inth, inthparam);
2420:
2421: return (0);
2422: }
2423:
2424: int
2425: emuxki_trigger_input(void *addr, void *start, void *end, int blksize,
2426: void (*inth) (void *), void *inthparam,
2427: struct audio_params *params)
2428: {
2429: struct emuxki_softc *sc = addr;
2430: /* No multiple voice support for now */
2431: struct emuxki_voice *voice = sc->rvoice;
2432: int error;
2433:
2434: if (voice == NULL)
2435: return (ENXIO);
2436: if ((error = emuxki_set_vparms(voice, params)))
2437: return (error);
2438: if ((error = emuxki_voice_set_bufparms(voice, start,
2439: (caddr_t)end - (caddr_t)start,
2440: blksize)))
2441: return (error);
2442: emuxki_voice_start(voice, inth, inthparam);
2443:
2444: return (0);
2445: }
2446:
2447:
2448: /*
2449: * AC97 callbacks
2450: */
2451:
2452: int
2453: emuxki_ac97_attach(void *arg, struct ac97_codec_if *codecif)
2454: {
2455: struct emuxki_softc *sc = arg;
2456:
2457: sc->codecif = codecif;
2458: return (0);
2459: }
2460:
2461: int
2462: emuxki_ac97_read(void *arg, u_int8_t reg, u_int16_t *val)
2463: {
2464: struct emuxki_softc *sc = arg;
2465: int s;
2466:
2467: s = splaudio();
2468: bus_space_write_1(sc->sc_iot, sc->sc_ioh, EMU_AC97ADDR, reg);
2469: *val = bus_space_read_2(sc->sc_iot, sc->sc_ioh, EMU_AC97DATA);
2470: splx(s);
2471:
2472: return (0);
2473: }
2474:
2475: int
2476: emuxki_ac97_write(void *arg, u_int8_t reg, u_int16_t val)
2477: {
2478: struct emuxki_softc *sc = arg;
2479: int s;
2480:
2481: s = splaudio();
2482: bus_space_write_1(sc->sc_iot, sc->sc_ioh, EMU_AC97ADDR, reg);
2483: bus_space_write_2(sc->sc_iot, sc->sc_ioh, EMU_AC97DATA, val);
2484: splx(s);
2485:
2486: return (0);
2487: }
2488:
2489: void
2490: emuxki_ac97_reset(void *arg)
2491: {
2492: }
CVSweb