aboutsummaryrefslogtreecommitdiffstats
path: root/sound/oss/emu10k1
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-16 18:20:36 -0400
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-16 18:20:36 -0400
commit1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch)
tree0bba044c4ce775e45a88a51686b5d9f90697ea9d /sound/oss/emu10k1
Linux-2.6.12-rc2v2.6.12-rc2
Initial git repository build. I'm not bothering with the full history, even though we have it. We can create a separate "historical" git archive of that later if we want to, and in the meantime it's about 3.2GB when imported into git - space that would just make the early git days unnecessarily complicated, when we don't have a lot of good infrastructure for it. Let it rip!
Diffstat (limited to 'sound/oss/emu10k1')
-rw-r--r--sound/oss/emu10k1/8010.h737
-rw-r--r--sound/oss/emu10k1/Makefile17
-rw-r--r--sound/oss/emu10k1/audio.c1588
-rw-r--r--sound/oss/emu10k1/audio.h44
-rw-r--r--sound/oss/emu10k1/cardmi.c832
-rw-r--r--sound/oss/emu10k1/cardmi.h97
-rw-r--r--sound/oss/emu10k1/cardmo.c229
-rw-r--r--sound/oss/emu10k1/cardmo.h62
-rw-r--r--sound/oss/emu10k1/cardwi.c373
-rw-r--r--sound/oss/emu10k1/cardwi.h91
-rw-r--r--sound/oss/emu10k1/cardwo.c643
-rw-r--r--sound/oss/emu10k1/cardwo.h90
-rw-r--r--sound/oss/emu10k1/ecard.c157
-rw-r--r--sound/oss/emu10k1/ecard.h113
-rw-r--r--sound/oss/emu10k1/efxmgr.c220
-rw-r--r--sound/oss/emu10k1/efxmgr.h270
-rw-r--r--sound/oss/emu10k1/emuadxmg.c104
-rw-r--r--sound/oss/emu10k1/hwaccess.c507
-rw-r--r--sound/oss/emu10k1/hwaccess.h247
-rw-r--r--sound/oss/emu10k1/icardmid.h163
-rw-r--r--sound/oss/emu10k1/icardwav.h53
-rw-r--r--sound/oss/emu10k1/irqmgr.c113
-rw-r--r--sound/oss/emu10k1/irqmgr.h52
-rw-r--r--sound/oss/emu10k1/main.c1475
-rw-r--r--sound/oss/emu10k1/midi.c613
-rw-r--r--sound/oss/emu10k1/midi.h78
-rw-r--r--sound/oss/emu10k1/mixer.c690
-rw-r--r--sound/oss/emu10k1/passthrough.c236
-rw-r--r--sound/oss/emu10k1/passthrough.h99
-rw-r--r--sound/oss/emu10k1/recmgr.c147
-rw-r--r--sound/oss/emu10k1/recmgr.h48
-rw-r--r--sound/oss/emu10k1/timer.c176
-rw-r--r--sound/oss/emu10k1/timer.h54
-rw-r--r--sound/oss/emu10k1/voicemgr.c398
-rw-r--r--sound/oss/emu10k1/voicemgr.h103
35 files changed, 10919 insertions, 0 deletions
diff --git a/sound/oss/emu10k1/8010.h b/sound/oss/emu10k1/8010.h
new file mode 100644
index 000000000000..61c6c42bbc36
--- /dev/null
+++ b/sound/oss/emu10k1/8010.h
@@ -0,0 +1,737 @@
1/*
2 **********************************************************************
3 * 8010.h
4 * Copyright 1999-2001 Creative Labs, Inc.
5 *
6 **********************************************************************
7 *
8 * Date Author Summary of changes
9 * ---- ------ ------------------
10 * October 20, 1999 Bertrand Lee base code release
11 * November 2, 1999 Alan Cox Cleaned of 8bit chars, DOS
12 * line endings
13 * December 8, 1999 Jon Taylor Added lots of new register info
14 * May 16, 2001 Daniel Bertrand Added unofficial DBG register info
15 * Oct-Nov 2001 D.B. Added unofficial Audigy registers
16 *
17 **********************************************************************
18 *
19 * This program is free software; you can redistribute it and/or
20 * modify it under the terms of the GNU General Public License as
21 * published by the Free Software Foundation; either version 2 of
22 * the License, or (at your option) any later version.
23 *
24 * This program is distributed in the hope that it will be useful,
25 * but WITHOUT ANY WARRANTY; without even the implied warranty of
26 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27 * GNU General Public License for more details.
28 *
29 * You should have received a copy of the GNU General Public
30 * License along with this program; if not, write to the Free
31 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139,
32 * USA.
33 *
34 *
35 **********************************************************************
36 */
37
38
39#ifndef _8010_H
40#define _8010_H
41
42#include <linux/types.h>
43
44// Driver version:
45#define MAJOR_VER 0
46#define MINOR_VER 20
47#define DRIVER_VERSION "0.20a"
48
49
50// Audigy specify registers are prefixed with 'A_'
51
52/************************************************************************************************/
53/* PCI function 0 registers, address = <val> + PCIBASE0 */
54/************************************************************************************************/
55
56#define PTR 0x00 /* Indexed register set pointer register */
57 /* NOTE: The CHANNELNUM and ADDRESS words can */
58 /* be modified independently of each other. */
59#define PTR_CHANNELNUM_MASK 0x0000003f /* For each per-channel register, indicates the */
60 /* channel number of the register to be */
61 /* accessed. For non per-channel registers the */
62 /* value should be set to zero. */
63#define PTR_ADDRESS_MASK 0x07ff0000 /* Register index */
64
65#define DATA 0x04 /* Indexed register set data register */
66
67#define IPR 0x08 /* Global interrupt pending register */
68 /* Clear pending interrupts by writing a 1 to */
69 /* the relevant bits and zero to the other bits */
70
71/* The next two interrupts are for the midi port on the Audigy Drive (A_MPU1) */
72#define A_IPR_MIDITRANSBUFEMPTY2 0x10000000 /* MIDI UART transmit buffer empty */
73#define A_IPR_MIDIRECVBUFEMPTY2 0x08000000 /* MIDI UART receive buffer empty */
74
75#define IPR_SAMPLERATETRACKER 0x01000000 /* Sample rate tracker lock status change */
76#define IPR_FXDSP 0x00800000 /* Enable FX DSP interrupts */
77#define IPR_FORCEINT 0x00400000 /* Force Sound Blaster interrupt */
78#define IPR_PCIERROR 0x00200000 /* PCI bus error */
79#define IPR_VOLINCR 0x00100000 /* Volume increment button pressed */
80#define IPR_VOLDECR 0x00080000 /* Volume decrement button pressed */
81#define IPR_MUTE 0x00040000 /* Mute button pressed */
82#define IPR_MICBUFFULL 0x00020000 /* Microphone buffer full */
83#define IPR_MICBUFHALFFULL 0x00010000 /* Microphone buffer half full */
84#define IPR_ADCBUFFULL 0x00008000 /* ADC buffer full */
85#define IPR_ADCBUFHALFFULL 0x00004000 /* ADC buffer half full */
86#define IPR_EFXBUFFULL 0x00002000 /* Effects buffer full */
87#define IPR_EFXBUFHALFFULL 0x00001000 /* Effects buffer half full */
88#define IPR_GPSPDIFSTATUSCHANGE 0x00000800 /* GPSPDIF channel status change */
89#define IPR_CDROMSTATUSCHANGE 0x00000400 /* CD-ROM channel status change */
90#define IPR_INTERVALTIMER 0x00000200 /* Interval timer terminal count */
91#define IPR_MIDITRANSBUFEMPTY 0x00000100 /* MIDI UART transmit buffer empty */
92#define IPR_MIDIRECVBUFEMPTY 0x00000080 /* MIDI UART receive buffer empty */
93#define IPR_CHANNELLOOP 0x00000040 /* One or more channel loop interrupts pending */
94#define IPR_CHANNELNUMBERMASK 0x0000003f /* When IPR_CHANNELLOOP is set, indicates the */
95 /* Highest set channel in CLIPL or CLIPH. When */
96 /* IP is written with CL set, the bit in CLIPL */
97 /* or CLIPH corresponding to the CIN value */
98 /* written will be cleared. */
99#define A_IPR_MIDITRANSBUFEMPTY1 IPR_MIDITRANSBUFEMPTY /* MIDI UART transmit buffer empty */
100#define A_IPR_MIDIRECVBUFEMPTY1 IPR_MIDIRECVBUFEMPTY /* MIDI UART receive buffer empty */
101
102
103
104#define INTE 0x0c /* Interrupt enable register */
105#define INTE_VIRTUALSB_MASK 0xc0000000 /* Virtual Soundblaster I/O port capture */
106#define INTE_VIRTUALSB_220 0x00000000 /* Capture at I/O base address 0x220-0x22f */
107#define INTE_VIRTUALSB_240 0x40000000 /* Capture at I/O base address 0x240 */
108#define INTE_VIRTUALSB_260 0x80000000 /* Capture at I/O base address 0x260 */
109#define INTE_VIRTUALSB_280 0xc0000000 /* Capture at I/O base address 0x280 */
110#define INTE_VIRTUALMPU_MASK 0x30000000 /* Virtual MPU I/O port capture */
111#define INTE_VIRTUALMPU_300 0x00000000 /* Capture at I/O base address 0x300-0x301 */
112#define INTE_VIRTUALMPU_310 0x10000000 /* Capture at I/O base address 0x310 */
113#define INTE_VIRTUALMPU_320 0x20000000 /* Capture at I/O base address 0x320 */
114#define INTE_VIRTUALMPU_330 0x30000000 /* Capture at I/O base address 0x330 */
115#define INTE_MASTERDMAENABLE 0x08000000 /* Master DMA emulation at 0x000-0x00f */
116#define INTE_SLAVEDMAENABLE 0x04000000 /* Slave DMA emulation at 0x0c0-0x0df */
117#define INTE_MASTERPICENABLE 0x02000000 /* Master PIC emulation at 0x020-0x021 */
118#define INTE_SLAVEPICENABLE 0x01000000 /* Slave PIC emulation at 0x0a0-0x0a1 */
119#define INTE_VSBENABLE 0x00800000 /* Enable virtual Soundblaster */
120#define INTE_ADLIBENABLE 0x00400000 /* Enable AdLib emulation at 0x388-0x38b */
121#define INTE_MPUENABLE 0x00200000 /* Enable virtual MPU */
122#define INTE_FORCEINT 0x00100000 /* Continuously assert INTAN */
123
124#define INTE_MRHANDENABLE 0x00080000 /* Enable the "Mr. Hand" logic */
125 /* NOTE: There is no reason to use this under */
126 /* Linux, and it will cause odd hardware */
127 /* behavior and possibly random segfaults and */
128 /* lockups if enabled. */
129
130/* The next two interrupts are for the midi port on the Audigy Drive (A_MPU1) */
131#define A_INTE_MIDITXENABLE2 0x00020000 /* Enable MIDI transmit-buffer-empty interrupts */
132#define A_INTE_MIDIRXENABLE2 0x00010000 /* Enable MIDI receive-buffer-empty interrupts */
133
134
135#define INTE_SAMPLERATETRACKER 0x00002000 /* Enable sample rate tracker interrupts */
136 /* NOTE: This bit must always be enabled */
137#define INTE_FXDSPENABLE 0x00001000 /* Enable FX DSP interrupts */
138#define INTE_PCIERRORENABLE 0x00000800 /* Enable PCI bus error interrupts */
139#define INTE_VOLINCRENABLE 0x00000400 /* Enable volume increment button interrupts */
140#define INTE_VOLDECRENABLE 0x00000200 /* Enable volume decrement button interrupts */
141#define INTE_MUTEENABLE 0x00000100 /* Enable mute button interrupts */
142#define INTE_MICBUFENABLE 0x00000080 /* Enable microphone buffer interrupts */
143#define INTE_ADCBUFENABLE 0x00000040 /* Enable ADC buffer interrupts */
144#define INTE_EFXBUFENABLE 0x00000020 /* Enable Effects buffer interrupts */
145#define INTE_GPSPDIFENABLE 0x00000010 /* Enable GPSPDIF status interrupts */
146#define INTE_CDSPDIFENABLE 0x00000008 /* Enable CDSPDIF status interrupts */
147#define INTE_INTERVALTIMERENB 0x00000004 /* Enable interval timer interrupts */
148#define INTE_MIDITXENABLE 0x00000002 /* Enable MIDI transmit-buffer-empty interrupts */
149#define INTE_MIDIRXENABLE 0x00000001 /* Enable MIDI receive-buffer-empty interrupts */
150
151/* The next two interrupts are for the midi port on the Audigy (A_MPU2) */
152#define A_INTE_MIDITXENABLE1 INTE_MIDITXENABLE
153#define A_INTE_MIDIRXENABLE1 INTE_MIDIRXENABLE
154
155#define WC 0x10 /* Wall Clock register */
156#define WC_SAMPLECOUNTER_MASK 0x03FFFFC0 /* Sample periods elapsed since reset */
157#define WC_SAMPLECOUNTER 0x14060010
158#define WC_CURRENTCHANNEL 0x0000003F /* Channel [0..63] currently being serviced */
159 /* NOTE: Each channel takes 1/64th of a sample */
160 /* period to be serviced. */
161
162#define HCFG 0x14 /* Hardware config register */
163 /* NOTE: There is no reason to use the legacy */
164 /* SoundBlaster emulation stuff described below */
165 /* under Linux, and all kinds of weird hardware */
166 /* behavior can result if you try. Don't. */
167#define HCFG_LEGACYFUNC_MASK 0xe0000000 /* Legacy function number */
168#define HCFG_LEGACYFUNC_MPU 0x00000000 /* Legacy MPU */
169#define HCFG_LEGACYFUNC_SB 0x40000000 /* Legacy SB */
170#define HCFG_LEGACYFUNC_AD 0x60000000 /* Legacy AD */
171#define HCFG_LEGACYFUNC_MPIC 0x80000000 /* Legacy MPIC */
172#define HCFG_LEGACYFUNC_MDMA 0xa0000000 /* Legacy MDMA */
173#define HCFG_LEGACYFUNC_SPCI 0xc0000000 /* Legacy SPCI */
174#define HCFG_LEGACYFUNC_SDMA 0xe0000000 /* Legacy SDMA */
175#define HCFG_IOCAPTUREADDR 0x1f000000 /* The 4 LSBs of the captured I/O address. */
176#define HCFG_LEGACYWRITE 0x00800000 /* 1 = write, 0 = read */
177#define HCFG_LEGACYWORD 0x00400000 /* 1 = word, 0 = byte */
178#define HCFG_LEGACYINT 0x00200000 /* 1 = legacy event captured. Write 1 to clear. */
179 /* NOTE: The rest of the bits in this register */
180 /* _are_ relevant under Linux. */
181#define HCFG_CODECFORMAT_MASK 0x00070000 /* CODEC format */
182#define HCFG_CODECFORMAT_AC97 0x00000000 /* AC97 CODEC format -- Primary Output */
183#define HCFG_CODECFORMAT_I2S 0x00010000 /* I2S CODEC format -- Secondary (Rear) Output */
184#define HCFG_GPINPUT0 0x00004000 /* External pin112 */
185#define HCFG_GPINPUT1 0x00002000 /* External pin110 */
186
187#define HCFG_GPOUTPUT_MASK 0x00001c00 /* External pins which may be controlled */
188#define HCFG_GPOUT0 0x00001000 /* set to enable digital out on 5.1 cards */
189
190#define HCFG_JOYENABLE 0x00000200 /* Internal joystick enable */
191#define HCFG_PHASETRACKENABLE 0x00000100 /* Phase tracking enable */
192 /* 1 = Force all 3 async digital inputs to use */
193 /* the same async sample rate tracker (ZVIDEO) */
194#define HCFG_AC3ENABLE_MASK 0x0x0000e0 /* AC3 async input control - Not implemented */
195#define HCFG_AC3ENABLE_ZVIDEO 0x00000080 /* Channels 0 and 1 replace ZVIDEO */
196#define HCFG_AC3ENABLE_CDSPDIF 0x00000040 /* Channels 0 and 1 replace CDSPDIF */
197#define HCFG_AC3ENABLE_GPSPDIF 0x00000020 /* Channels 0 and 1 replace GPSPDIF */
198#define HCFG_AUTOMUTE 0x00000010 /* When set, the async sample rate convertors */
199 /* will automatically mute their output when */
200 /* they are not rate-locked to the external */
201 /* async audio source */
202#define HCFG_LOCKSOUNDCACHE 0x00000008 /* 1 = Cancel bustmaster accesses to soundcache */
203 /* NOTE: This should generally never be used. */
204#define HCFG_LOCKTANKCACHE_MASK 0x00000004 /* 1 = Cancel bustmaster accesses to tankcache */
205 /* NOTE: This should generally never be used. */
206#define HCFG_LOCKTANKCACHE 0x01020014
207#define HCFG_MUTEBUTTONENABLE 0x00000002 /* 1 = Master mute button sets AUDIOENABLE = 0. */
208 /* NOTE: This is a 'cheap' way to implement a */
209 /* master mute function on the mute button, and */
210 /* in general should not be used unless a more */
211 /* sophisticated master mute function has not */
212 /* been written. */
213#define HCFG_AUDIOENABLE 0x00000001 /* 0 = CODECs transmit zero-valued samples */
214 /* Should be set to 1 when the EMU10K1 is */
215 /* completely initialized. */
216
217//For Audigy, MPU port move to 0x70-0x74 ptr register
218
219#define MUDATA 0x18 /* MPU401 data register (8 bits) */
220
221#define MUCMD 0x19 /* MPU401 command register (8 bits) */
222#define MUCMD_RESET 0xff /* RESET command */
223#define MUCMD_ENTERUARTMODE 0x3f /* Enter_UART_mode command */
224 /* NOTE: All other commands are ignored */
225
226#define MUSTAT MUCMD /* MPU401 status register (8 bits) */
227#define MUSTAT_IRDYN 0x80 /* 0 = MIDI data or command ACK */
228#define MUSTAT_ORDYN 0x40 /* 0 = MUDATA can accept a command or data */
229
230#define A_IOCFG 0x18 /* GPIO on Audigy card (16bits) */
231#define A_GPINPUT_MASK 0xff00
232#define A_GPOUTPUT_MASK 0x00ff
233
234#define TIMER 0x1a /* Timer terminal count register (16-bit) */
235 /* NOTE: After the rate is changed, a maximum */
236 /* of 1024 sample periods should be allowed */
237 /* before the new rate is guaranteed accurate. */
238#define TIMER_RATE_MASK 0x03ff /* Timer interrupt rate in sample periods */
239 /* 0 == 1024 periods, [1..4] are not useful */
240
241#define AC97DATA 0x1c /* AC97 register set data register (16 bit) */
242
243#define AC97ADDRESS 0x1e /* AC97 register set address register (8 bit) */
244#define AC97ADDRESS_READY 0x80 /* Read-only bit, reflects CODEC READY signal */
245#define AC97ADDRESS_ADDRESS 0x7f /* Address of indexed AC97 register */
246
247/********************************************************************************************************/
248/* Emu10k1 pointer-offset register set, accessed through the PTR and DATA registers */
249/********************************************************************************************************/
250
251#define CPF 0x00 /* Current pitch and fraction register */
252#define CPF_CURRENTPITCH_MASK 0xffff0000 /* Current pitch (linear, 0x4000 == unity pitch shift) */
253#define CPF_CURRENTPITCH 0x10100000
254#define CPF_STEREO_MASK 0x00008000 /* 1 = Even channel interleave, odd channel locked */
255#define CPF_STOP_MASK 0x00004000 /* 1 = Current pitch forced to 0 */
256#define CPF_FRACADDRESS_MASK 0x00003fff /* Linear fractional address of the current channel */
257
258#define PTRX 0x01 /* Pitch target and send A/B amounts register */
259#define PTRX_PITCHTARGET_MASK 0xffff0000 /* Pitch target of specified channel */
260#define PTRX_PITCHTARGET 0x10100001
261#define PTRX_FXSENDAMOUNT_A_MASK 0x0000ff00 /* Linear level of channel output sent to FX send bus A */
262#define PTRX_FXSENDAMOUNT_A 0x08080001
263#define PTRX_FXSENDAMOUNT_B_MASK 0x000000ff /* Linear level of channel output sent to FX send bus B */
264#define PTRX_FXSENDAMOUNT_B 0x08000001
265
266#define CVCF 0x02 /* Current volume and filter cutoff register */
267#define CVCF_CURRENTVOL_MASK 0xffff0000 /* Current linear volume of specified channel */
268#define CVCF_CURRENTVOL 0x10100002
269#define CVCF_CURRENTFILTER_MASK 0x0000ffff /* Current filter cutoff frequency of specified channel */
270#define CVCF_CURRENTFILTER 0x10000002
271
272#define VTFT 0x03 /* Volume target and filter cutoff target register */
273#define VTFT_VOLUMETARGET_MASK 0xffff0000 /* Volume target of specified channel */
274#define VTFT_FILTERTARGET_MASK 0x0000ffff /* Filter cutoff target of specified channel */
275
276#define Z1 0x05 /* Filter delay memory 1 register */
277
278#define Z2 0x04 /* Filter delay memory 2 register */
279
280#define PSST 0x06 /* Send C amount and loop start address register */
281#define PSST_FXSENDAMOUNT_C_MASK 0xff000000 /* Linear level of channel output sent to FX send bus C */
282
283#define PSST_FXSENDAMOUNT_C 0x08180006
284
285#define PSST_LOOPSTARTADDR_MASK 0x00ffffff /* Loop start address of the specified channel */
286#define PSST_LOOPSTARTADDR 0x18000006
287
288#define DSL 0x07 /* Send D amount and loop start address register */
289#define DSL_FXSENDAMOUNT_D_MASK 0xff000000 /* Linear level of channel output sent to FX send bus D */
290
291#define DSL_FXSENDAMOUNT_D 0x08180007
292
293#define DSL_LOOPENDADDR_MASK 0x00ffffff /* Loop end address of the specified channel */
294#define DSL_LOOPENDADDR 0x18000007
295
296#define CCCA 0x08 /* Filter Q, interp. ROM, byte size, cur. addr register */
297#define CCCA_RESONANCE 0xf0000000 /* Lowpass filter resonance (Q) height */
298#define CCCA_INTERPROMMASK 0x0e000000 /* Selects passband of interpolation ROM */
299 /* 1 == full band, 7 == lowpass */
300 /* ROM 0 is used when pitch shifting downward or less */
301 /* then 3 semitones upward. Increasingly higher ROM */
302 /* numbers are used, typically in steps of 3 semitones, */
303 /* as upward pitch shifting is performed. */
304#define CCCA_INTERPROM_0 0x00000000 /* Select interpolation ROM 0 */
305#define CCCA_INTERPROM_1 0x02000000 /* Select interpolation ROM 1 */
306#define CCCA_INTERPROM_2 0x04000000 /* Select interpolation ROM 2 */
307#define CCCA_INTERPROM_3 0x06000000 /* Select interpolation ROM 3 */
308#define CCCA_INTERPROM_4 0x08000000 /* Select interpolation ROM 4 */
309#define CCCA_INTERPROM_5 0x0a000000 /* Select interpolation ROM 5 */
310#define CCCA_INTERPROM_6 0x0c000000 /* Select interpolation ROM 6 */
311#define CCCA_INTERPROM_7 0x0e000000 /* Select interpolation ROM 7 */
312#define CCCA_8BITSELECT 0x01000000 /* 1 = Sound memory for this channel uses 8-bit samples */
313#define CCCA_CURRADDR_MASK 0x00ffffff /* Current address of the selected channel */
314#define CCCA_CURRADDR 0x18000008
315
316#define CCR 0x09 /* Cache control register */
317#define CCR_CACHEINVALIDSIZE 0x07190009
318#define CCR_CACHEINVALIDSIZE_MASK 0xfe000000 /* Number of invalid samples cache for this channel */
319#define CCR_CACHELOOPFLAG 0x01000000 /* 1 = Cache has a loop service pending */
320#define CCR_INTERLEAVEDSAMPLES 0x00800000 /* 1 = A cache service will fetch interleaved samples */
321#define CCR_WORDSIZEDSAMPLES 0x00400000 /* 1 = A cache service will fetch word sized samples */
322#define CCR_READADDRESS 0x06100009
323#define CCR_READADDRESS_MASK 0x003f0000 /* Location of cache just beyond current cache service */
324#define CCR_LOOPINVALSIZE 0x0000fe00 /* Number of invalid samples in cache prior to loop */
325 /* NOTE: This is valid only if CACHELOOPFLAG is set */
326#define CCR_LOOPFLAG 0x00000100 /* Set for a single sample period when a loop occurs */
327#define CCR_CACHELOOPADDRHI 0x000000ff /* DSL_LOOPSTARTADDR's hi byte if CACHELOOPFLAG is set */
328
329#define CLP 0x0a /* Cache loop register (valid if CCR_CACHELOOPFLAG = 1) */
330 /* NOTE: This register is normally not used */
331#define CLP_CACHELOOPADDR 0x0000ffff /* Cache loop address (DSL_LOOPSTARTADDR [0..15]) */
332
333#define FXRT 0x0b /* Effects send routing register */
334 /* NOTE: It is illegal to assign the same routing to */
335 /* two effects sends. */
336#define FXRT_CHANNELA 0x000f0000 /* Effects send bus number for channel's effects send A */
337#define FXRT_CHANNELB 0x00f00000 /* Effects send bus number for channel's effects send B */
338#define FXRT_CHANNELC 0x0f000000 /* Effects send bus number for channel's effects send C */
339#define FXRT_CHANNELD 0xf0000000 /* Effects send bus number for channel's effects send D */
340
341#define MAPA 0x0c /* Cache map A */
342
343#define MAPB 0x0d /* Cache map B */
344
345#define MAP_PTE_MASK 0xffffe000 /* The 19 MSBs of the PTE indexed by the PTI */
346#define MAP_PTI_MASK 0x00001fff /* The 13 bit index to one of the 8192 PTE dwords */
347
348#define ENVVOL 0x10 /* Volume envelope register */
349#define ENVVOL_MASK 0x0000ffff /* Current value of volume envelope state variable */
350 /* 0x8000-n == 666*n usec delay */
351
352#define ATKHLDV 0x11 /* Volume envelope hold and attack register */
353#define ATKHLDV_PHASE0 0x00008000 /* 0 = Begin attack phase */
354#define ATKHLDV_HOLDTIME_MASK 0x00007f00 /* Envelope hold time (127-n == n*88.2msec) */
355#define ATKHLDV_ATTACKTIME_MASK 0x0000007f /* Envelope attack time, log encoded */
356 /* 0 = infinite, 1 = 10.9msec, ... 0x7f = 5.5msec */
357
358#define DCYSUSV 0x12 /* Volume envelope sustain and decay register */
359#define DCYSUSV_PHASE1_MASK 0x00008000 /* 0 = Begin attack phase, 1 = begin release phase */
360#define DCYSUSV_SUSTAINLEVEL_MASK 0x00007f00 /* 127 = full, 0 = off, 0.75dB increments */
361#define DCYSUSV_CHANNELENABLE_MASK 0x00000080 /* 1 = Inhibit envelope engine from writing values in */
362 /* this channel and from writing to pitch, filter and */
363 /* volume targets. */
364#define DCYSUSV_DECAYTIME_MASK 0x0000007f /* Volume envelope decay time, log encoded */
365 /* 0 = 43.7msec, 1 = 21.8msec, 0x7f = 22msec */
366
367#define LFOVAL1 0x13 /* Modulation LFO value */
368#define LFOVAL_MASK 0x0000ffff /* Current value of modulation LFO state variable */
369 /* 0x8000-n == 666*n usec delay */
370
371#define ENVVAL 0x14 /* Modulation envelope register */
372#define ENVVAL_MASK 0x0000ffff /* Current value of modulation envelope state variable */
373 /* 0x8000-n == 666*n usec delay */
374
375#define ATKHLDM 0x15 /* Modulation envelope hold and attack register */
376#define ATKHLDM_PHASE0 0x00008000 /* 0 = Begin attack phase */
377#define ATKHLDM_HOLDTIME 0x00007f00 /* Envelope hold time (127-n == n*42msec) */
378#define ATKHLDM_ATTACKTIME 0x0000007f /* Envelope attack time, log encoded */
379 /* 0 = infinite, 1 = 11msec, ... 0x7f = 5.5msec */
380
381#define DCYSUSM 0x16 /* Modulation envelope decay and sustain register */
382#define DCYSUSM_PHASE1_MASK 0x00008000 /* 0 = Begin attack phase, 1 = begin release phase */
383#define DCYSUSM_SUSTAINLEVEL_MASK 0x00007f00 /* 127 = full, 0 = off, 0.75dB increments */
384#define DCYSUSM_DECAYTIME_MASK 0x0000007f /* Envelope decay time, log encoded */
385 /* 0 = 43.7msec, 1 = 21.8msec, 0x7f = 22msec */
386
387#define LFOVAL2 0x17 /* Vibrato LFO register */
388#define LFOVAL2_MASK 0x0000ffff /* Current value of vibrato LFO state variable */
389 /* 0x8000-n == 666*n usec delay */
390
391#define IP 0x18 /* Initial pitch register */
392#define IP_MASK 0x0000ffff /* Exponential initial pitch shift */
393 /* 4 bits of octave, 12 bits of fractional octave */
394#define IP_UNITY 0x0000e000 /* Unity pitch shift */
395
396#define IFATN 0x19 /* Initial filter cutoff and attenuation register */
397#define IFATN_FILTERCUTOFF_MASK 0x0000ff00 /* Initial filter cutoff frequency in exponential units */
398 /* 6 most significant bits are semitones */
399 /* 2 least significant bits are fractions */
400#define IFATN_FILTERCUTOFF 0x08080019
401#define IFATN_ATTENUATION_MASK 0x000000ff /* Initial attenuation in 0.375dB steps */
402#define IFATN_ATTENUATION 0x08000019
403
404
405#define PEFE 0x1a /* Pitch envelope and filter envelope amount register */
406#define PEFE_PITCHAMOUNT_MASK 0x0000ff00 /* Pitch envlope amount */
407 /* Signed 2's complement, +/- one octave peak extremes */
408#define PEFE_PITCHAMOUNT 0x0808001a
409#define PEFE_FILTERAMOUNT_MASK 0x000000ff /* Filter envlope amount */
410 /* Signed 2's complement, +/- six octaves peak extremes */
411#define PEFE_FILTERAMOUNT 0x0800001a
412#define FMMOD 0x1b /* Vibrato/filter modulation from LFO register */
413#define FMMOD_MODVIBRATO 0x0000ff00 /* Vibrato LFO modulation depth */
414 /* Signed 2's complement, +/- one octave extremes */
415#define FMMOD_MOFILTER 0x000000ff /* Filter LFO modulation depth */
416 /* Signed 2's complement, +/- three octave extremes */
417
418
419#define TREMFRQ 0x1c /* Tremolo amount and modulation LFO frequency register */
420#define TREMFRQ_DEPTH 0x0000ff00 /* Tremolo depth */
421 /* Signed 2's complement, with +/- 12dB extremes */
422#define TREMFRQ_FREQUENCY 0x000000ff /* Tremolo LFO frequency */
423 /* ??Hz steps, maximum of ?? Hz. */
424
425#define FM2FRQ2 0x1d /* Vibrato amount and vibrato LFO frequency register */
426#define FM2FRQ2_DEPTH 0x0000ff00 /* Vibrato LFO vibrato depth */
427 /* Signed 2's complement, +/- one octave extremes */
428#define FM2FRQ2_FREQUENCY 0x000000ff /* Vibrato LFO frequency */
429 /* 0.039Hz steps, maximum of 9.85 Hz. */
430
431#define TEMPENV 0x1e /* Tempory envelope register */
432#define TEMPENV_MASK 0x0000ffff /* 16-bit value */
433 /* NOTE: All channels contain internal variables; do */
434 /* not write to these locations. */
435
436#define CD0 0x20 /* Cache data 0 register */
437#define CD1 0x21 /* Cache data 1 register */
438#define CD2 0x22 /* Cache data 2 register */
439#define CD3 0x23 /* Cache data 3 register */
440#define CD4 0x24 /* Cache data 4 register */
441#define CD5 0x25 /* Cache data 5 register */
442#define CD6 0x26 /* Cache data 6 register */
443#define CD7 0x27 /* Cache data 7 register */
444#define CD8 0x28 /* Cache data 8 register */
445#define CD9 0x29 /* Cache data 9 register */
446#define CDA 0x2a /* Cache data A register */
447#define CDB 0x2b /* Cache data B register */
448#define CDC 0x2c /* Cache data C register */
449#define CDD 0x2d /* Cache data D register */
450#define CDE 0x2e /* Cache data E register */
451#define CDF 0x2f /* Cache data F register */
452
453#define PTB 0x40 /* Page table base register */
454#define PTB_MASK 0xfffff000 /* Physical address of the page table in host memory */
455
456#define TCB 0x41 /* Tank cache base register */
457#define TCB_MASK 0xfffff000 /* Physical address of the bottom of host based TRAM */
458
459#define ADCCR 0x42 /* ADC sample rate/stereo control register */
460#define ADCCR_RCHANENABLE 0x00000010 /* Enables right channel for writing to the host */
461#define ADCCR_LCHANENABLE 0x00000008 /* Enables left channel for writing to the host */
462 /* NOTE: To guarantee phase coherency, both channels */
463 /* must be disabled prior to enabling both channels. */
464#define A_ADCCR_RCHANENABLE 0x00000020
465#define A_ADCCR_LCHANENABLE 0x00000010
466
467#define A_ADCCR_SAMPLERATE_MASK 0x0000000F /* Audigy sample rate convertor output rate */
468#define ADCCR_SAMPLERATE_MASK 0x00000007 /* Sample rate convertor output rate */
469
470#define ADCCR_SAMPLERATE_48 0x00000000 /* 48kHz sample rate */
471#define ADCCR_SAMPLERATE_44 0x00000001 /* 44.1kHz sample rate */
472#define ADCCR_SAMPLERATE_32 0x00000002 /* 32kHz sample rate */
473#define ADCCR_SAMPLERATE_24 0x00000003 /* 24kHz sample rate */
474#define ADCCR_SAMPLERATE_22 0x00000004 /* 22.05kHz sample rate */
475#define ADCCR_SAMPLERATE_16 0x00000005 /* 16kHz sample rate */
476#define ADCCR_SAMPLERATE_11 0x00000006 /* 11.025kHz sample rate */
477#define ADCCR_SAMPLERATE_8 0x00000007 /* 8kHz sample rate */
478
479#define A_ADCCR_SAMPLERATE_12 0x00000006 /* 12kHz sample rate */
480#define A_ADCCR_SAMPLERATE_11 0x00000007 /* 11.025kHz sample rate */
481#define A_ADCCR_SAMPLERATE_8 0x00000008 /* 8kHz sample rate */
482
483#define FXWC 0x43 /* FX output write channels register */
484 /* When set, each bit enables the writing of the */
485 /* corresponding FX output channel (internal registers */
486 /* 0x20-0x3f) into host memory. This mode of recording */
487 /* is 16bit, 48KHz only. All 32 channels can be enabled */
488 /* simultaneously. */
489#define TCBS 0x44 /* Tank cache buffer size register */
490#define TCBS_MASK 0x00000007 /* Tank cache buffer size field */
491#define TCBS_BUFFSIZE_16K 0x00000000
492#define TCBS_BUFFSIZE_32K 0x00000001
493#define TCBS_BUFFSIZE_64K 0x00000002
494#define TCBS_BUFFSIZE_128K 0x00000003
495#define TCBS_BUFFSIZE_256K 0x00000004
496#define TCBS_BUFFSIZE_512K 0x00000005
497#define TCBS_BUFFSIZE_1024K 0x00000006
498#define TCBS_BUFFSIZE_2048K 0x00000007
499
500#define MICBA 0x45 /* AC97 microphone buffer address register */
501#define MICBA_MASK 0xfffff000 /* 20 bit base address */
502
503#define ADCBA 0x46 /* ADC buffer address register */
504#define ADCBA_MASK 0xfffff000 /* 20 bit base address */
505
506#define FXBA 0x47 /* FX Buffer Address */
507#define FXBA_MASK 0xfffff000 /* 20 bit base address */
508
509#define MICBS 0x49 /* Microphone buffer size register */
510
511#define ADCBS 0x4a /* ADC buffer size register */
512
513#define FXBS 0x4b /* FX buffer size register */
514
515/* The following mask values define the size of the ADC, MIX and FX buffers in bytes */
516#define ADCBS_BUFSIZE_NONE 0x00000000
517#define ADCBS_BUFSIZE_384 0x00000001
518#define ADCBS_BUFSIZE_448 0x00000002
519#define ADCBS_BUFSIZE_512 0x00000003
520#define ADCBS_BUFSIZE_640 0x00000004
521#define ADCBS_BUFSIZE_768 0x00000005
522#define ADCBS_BUFSIZE_896 0x00000006
523#define ADCBS_BUFSIZE_1024 0x00000007
524#define ADCBS_BUFSIZE_1280 0x00000008
525#define ADCBS_BUFSIZE_1536 0x00000009
526#define ADCBS_BUFSIZE_1792 0x0000000a
527#define ADCBS_BUFSIZE_2048 0x0000000b
528#define ADCBS_BUFSIZE_2560 0x0000000c
529#define ADCBS_BUFSIZE_3072 0x0000000d
530#define ADCBS_BUFSIZE_3584 0x0000000e
531#define ADCBS_BUFSIZE_4096 0x0000000f
532#define ADCBS_BUFSIZE_5120 0x00000010
533#define ADCBS_BUFSIZE_6144 0x00000011
534#define ADCBS_BUFSIZE_7168 0x00000012
535#define ADCBS_BUFSIZE_8192 0x00000013
536#define ADCBS_BUFSIZE_10240 0x00000014
537#define ADCBS_BUFSIZE_12288 0x00000015
538#define ADCBS_BUFSIZE_14366 0x00000016
539#define ADCBS_BUFSIZE_16384 0x00000017
540#define ADCBS_BUFSIZE_20480 0x00000018
541#define ADCBS_BUFSIZE_24576 0x00000019
542#define ADCBS_BUFSIZE_28672 0x0000001a
543#define ADCBS_BUFSIZE_32768 0x0000001b
544#define ADCBS_BUFSIZE_40960 0x0000001c
545#define ADCBS_BUFSIZE_49152 0x0000001d
546#define ADCBS_BUFSIZE_57344 0x0000001e
547#define ADCBS_BUFSIZE_65536 0x0000001f
548
549
550#define CDCS 0x50 /* CD-ROM digital channel status register */
551
552#define GPSCS 0x51 /* General Purpose SPDIF channel status register*/
553
554#define DBG 0x52 /* DO NOT PROGRAM THIS REGISTER!!! MAY DESTROY CHIP */
555
556/* definitions for debug register - taken from the alsa drivers */
557#define DBG_ZC 0x80000000 /* zero tram counter */
558#define DBG_SATURATION_OCCURED 0x02000000 /* saturation control */
559#define DBG_SATURATION_ADDR 0x01ff0000 /* saturation address */
560#define DBG_SINGLE_STEP 0x00008000 /* single step mode */
561#define DBG_STEP 0x00004000 /* start single step */
562#define DBG_CONDITION_CODE 0x00003e00 /* condition code */
563#define DBG_SINGLE_STEP_ADDR 0x000001ff /* single step address */
564
565
566#define REG53 0x53 /* DO NOT PROGRAM THIS REGISTER!!! MAY DESTROY CHIP */
567
568#define A_DBG 0x53
569#define A_DBG_SINGLE_STEP 0x00020000 /* Set to zero to start dsp */
570#define A_DBG_ZC 0x40000000 /* zero tram counter */
571#define A_DBG_STEP_ADDR 0x000003ff
572#define A_DBG_SATURATION_OCCURED 0x20000000
573#define A_DBG_SATURATION_ADDR 0x0ffc0000
574
575#define SPCS0 0x54 /* SPDIF output Channel Status 0 register */
576
577#define SPCS1 0x55 /* SPDIF output Channel Status 1 register */
578
579#define SPCS2 0x56 /* SPDIF output Channel Status 2 register */
580
581#define SPCS_CLKACCYMASK 0x30000000 /* Clock accuracy */
582#define SPCS_CLKACCY_1000PPM 0x00000000 /* 1000 parts per million */
583#define SPCS_CLKACCY_50PPM 0x10000000 /* 50 parts per million */
584#define SPCS_CLKACCY_VARIABLE 0x20000000 /* Variable accuracy */
585#define SPCS_SAMPLERATEMASK 0x0f000000 /* Sample rate */
586#define SPCS_SAMPLERATE_44 0x00000000 /* 44.1kHz sample rate */
587#define SPCS_SAMPLERATE_48 0x02000000 /* 48kHz sample rate */
588#define SPCS_SAMPLERATE_32 0x03000000 /* 32kHz sample rate */
589#define SPCS_CHANNELNUMMASK 0x00f00000 /* Channel number */
590#define SPCS_CHANNELNUM_UNSPEC 0x00000000 /* Unspecified channel number */
591#define SPCS_CHANNELNUM_LEFT 0x00100000 /* Left channel */
592#define SPCS_CHANNELNUM_RIGHT 0x00200000 /* Right channel */
593#define SPCS_SOURCENUMMASK 0x000f0000 /* Source number */
594#define SPCS_SOURCENUM_UNSPEC 0x00000000 /* Unspecified source number */
595#define SPCS_GENERATIONSTATUS 0x00008000 /* Originality flag (see IEC-958 spec) */
596#define SPCS_CATEGORYCODEMASK 0x00007f00 /* Category code (see IEC-958 spec) */
597#define SPCS_MODEMASK 0x000000c0 /* Mode (see IEC-958 spec) */
598#define SPCS_EMPHASISMASK 0x00000038 /* Emphasis */
599#define SPCS_EMPHASIS_NONE 0x00000000 /* No emphasis */
600#define SPCS_EMPHASIS_50_15 0x00000008 /* 50/15 usec 2 channel */
601#define SPCS_COPYRIGHT 0x00000004 /* Copyright asserted flag -- do not modify */
602#define SPCS_NOTAUDIODATA 0x00000002 /* 0 = Digital audio, 1 = not audio */
603#define SPCS_PROFESSIONAL 0x00000001 /* 0 = Consumer (IEC-958), 1 = pro (AES3-1992) */
604
605/* The 32-bit CLIx and SOLx registers all have one bit per channel control/status */
606#define CLIEL 0x58 /* Channel loop interrupt enable low register */
607
608#define CLIEH 0x59 /* Channel loop interrupt enable high register */
609
610#define CLIPL 0x5a /* Channel loop interrupt pending low register */
611
612#define CLIPH 0x5b /* Channel loop interrupt pending high register */
613
614#define SOLEL 0x5c /* Stop on loop enable low register */
615
616#define SOLEH 0x5d /* Stop on loop enable high register */
617
618#define SPBYPASS 0x5e /* SPDIF BYPASS mode register */
619#define SPBYPASS_ENABLE 0x00000001 /* Enable SPDIF bypass mode */
620
621#define AC97SLOT 0x5f /* additional AC97 slots enable bits */
622#define AC97SLOT_CNTR 0x10 /* Center enable */
623#define AC97SLOT_LFE 0x20 /* LFE enable */
624
625#define CDSRCS 0x60 /* CD-ROM Sample Rate Converter status register */
626
627#define GPSRCS 0x61 /* General Purpose SPDIF sample rate cvt status */
628
629#define ZVSRCS 0x62 /* ZVideo sample rate converter status */
630 /* NOTE: This one has no SPDIFLOCKED field */
631 /* Assumes sample lock */
632
633/* These three bitfields apply to CDSRCS, GPSRCS, and (except as noted) ZVSRCS. */
634#define SRCS_SPDIFLOCKED 0x02000000 /* SPDIF stream locked */
635#define SRCS_RATELOCKED 0x01000000 /* Sample rate locked */
636#define SRCS_ESTSAMPLERATE 0x0007ffff /* Do not modify this field. */
637
638
639/* Note that these values can vary +/- by a small amount */
640#define SRCS_SPDIFRATE_44 0x0003acd9
641#define SRCS_SPDIFRATE_48 0x00040000
642#define SRCS_SPDIFRATE_96 0x00080000
643
644#define MICIDX 0x63 /* Microphone recording buffer index register */
645#define MICIDX_MASK 0x0000ffff /* 16-bit value */
646#define MICIDX_IDX 0x10000063
647
648#define A_ADCIDX 0x63
649#define A_ADCIDX_IDX 0x10000063
650
651#define ADCIDX 0x64 /* ADC recording buffer index register */
652#define ADCIDX_MASK 0x0000ffff /* 16 bit index field */
653#define ADCIDX_IDX 0x10000064
654
655#define FXIDX 0x65 /* FX recording buffer index register */
656#define FXIDX_MASK 0x0000ffff /* 16-bit value */
657#define FXIDX_IDX 0x10000065
658
659/* This is the MPU port on the card (via the game port) */
660#define A_MUDATA1 0x70
661#define A_MUCMD1 0x71
662#define A_MUSTAT1 A_MUCMD1
663
664/* This is the MPU port on the Audigy Drive */
665#define A_MUDATA2 0x72
666#define A_MUCMD2 0x73
667#define A_MUSTAT2 A_MUCMD2
668
669/* The next two are the Audigy equivalent of FXWC */
670/* the Audigy can record any output (16bit, 48kHz, up to 64 channel simultaneously) */
671/* Each bit selects a channel for recording */
672#define A_FXWC1 0x74 /* Selects 0x7f-0x60 for FX recording */
673#define A_FXWC2 0x75 /* Selects 0x9f-0x80 for FX recording */
674
675#define A_SPDIF_SAMPLERATE 0x76 /* Set the sample rate of SPDIF output */
676#define A_SPDIF_48000 0x00000080
677#define A_SPDIF_44100 0x00000000
678#define A_SPDIF_96000 0x00000040
679
680#define A_FXRT2 0x7c
681#define A_FXRT_CHANNELE 0x0000003f /* Effects send bus number for channel's effects send E */
682#define A_FXRT_CHANNELF 0x00003f00 /* Effects send bus number for channel's effects send F */
683#define A_FXRT_CHANNELG 0x003f0000 /* Effects send bus number for channel's effects send G */
684#define A_FXRT_CHANNELH 0x3f000000 /* Effects send bus number for channel's effects send H */
685
686#define A_SENDAMOUNTS 0x7d
687#define A_FXSENDAMOUNT_E_MASK 0xff000000
688#define A_FXSENDAMOUNT_F_MASK 0x00ff0000
689#define A_FXSENDAMOUNT_G_MASK 0x0000ff00
690#define A_FXSENDAMOUNT_H_MASK 0x000000ff
691
692/* The send amounts for this one are the same as used with the emu10k1 */
693#define A_FXRT1 0x7e
694#define A_FXRT_CHANNELA 0x0000003f
695#define A_FXRT_CHANNELB 0x00003f00
696#define A_FXRT_CHANNELC 0x003f0000
697#define A_FXRT_CHANNELD 0x3f000000
698
699
700/* Each FX general purpose register is 32 bits in length, all bits are used */
701#define FXGPREGBASE 0x100 /* FX general purpose registers base */
702#define A_FXGPREGBASE 0x400 /* Audigy GPRs, 0x400 to 0x5ff */
703/* Tank audio data is logarithmically compressed down to 16 bits before writing to TRAM and is */
704/* decompressed back to 20 bits on a read. There are a total of 160 locations, the last 32 */
705/* locations are for external TRAM. */
706#define TANKMEMDATAREGBASE 0x200 /* Tank memory data registers base */
707#define TANKMEMDATAREG_MASK 0x000fffff /* 20 bit tank audio data field */
708
709/* Combined address field and memory opcode or flag field. 160 locations, last 32 are external */
710#define TANKMEMADDRREGBASE 0x300 /* Tank memory address registers base */
711#define TANKMEMADDRREG_ADDR_MASK 0x000fffff /* 20 bit tank address field */
712#define TANKMEMADDRREG_CLEAR 0x00800000 /* Clear tank memory */
713#define TANKMEMADDRREG_ALIGN 0x00400000 /* Align read or write relative to tank access */
714#define TANKMEMADDRREG_WRITE 0x00200000 /* Write to tank memory */
715#define TANKMEMADDRREG_READ 0x00100000 /* Read from tank memory */
716
717#define MICROCODEBASE 0x400 /* Microcode data base address */
718
719/* Each DSP microcode instruction is mapped into 2 doublewords */
720/* NOTE: When writing, always write the LO doubleword first. Reads can be in either order. */
721#define LOWORD_OPX_MASK 0x000ffc00 /* Instruction operand X */
722#define LOWORD_OPY_MASK 0x000003ff /* Instruction operand Y */
723#define HIWORD_OPCODE_MASK 0x00f00000 /* Instruction opcode */
724#define HIWORD_RESULT_MASK 0x000ffc00 /* Instruction result */
725#define HIWORD_OPA_MASK 0x000003ff /* Instruction operand A */
726
727
728/* Audigy Soundcard have a different instruction format */
729#define AUDIGY_CODEBASE 0x600
730#define A_LOWORD_OPY_MASK 0x000007ff
731#define A_LOWORD_OPX_MASK 0x007ff000
732#define A_HIWORD_OPCODE_MASK 0x0f000000
733#define A_HIWORD_RESULT_MASK 0x007ff000
734#define A_HIWORD_OPA_MASK 0x000007ff
735
736
737#endif /* _8010_H */
diff --git a/sound/oss/emu10k1/Makefile b/sound/oss/emu10k1/Makefile
new file mode 100644
index 000000000000..b3af9ccb0579
--- /dev/null
+++ b/sound/oss/emu10k1/Makefile
@@ -0,0 +1,17 @@
1# Makefile for Creative Labs EMU10K1
2#
3# 12 Apr 2000 Rui Sousa
4
5obj-$(CONFIG_SOUND_EMU10K1) += emu10k1.o
6
7emu10k1-objs := audio.o cardmi.o cardmo.o cardwi.o cardwo.o ecard.o \
8 efxmgr.o emuadxmg.o hwaccess.o irqmgr.o main.o midi.o \
9 mixer.o passthrough.o recmgr.o timer.o voicemgr.o
10
11ifdef DEBUG
12 EXTRA_CFLAGS += -DEMU10K1_DEBUG
13endif
14
15ifdef CONFIG_MIDI_EMU10K1
16 EXTRA_CFLAGS += -DEMU10K1_SEQUENCER
17endif
diff --git a/sound/oss/emu10k1/audio.c b/sound/oss/emu10k1/audio.c
new file mode 100644
index 000000000000..cde4d59d5430
--- /dev/null
+++ b/sound/oss/emu10k1/audio.c
@@ -0,0 +1,1588 @@
1/*
2 **********************************************************************
3 * audio.c -- /dev/dsp interface for emu10k1 driver
4 * Copyright 1999, 2000 Creative Labs, Inc.
5 *
6 **********************************************************************
7 *
8 * Date Author Summary of changes
9 * ---- ------ ------------------
10 * October 20, 1999 Bertrand Lee base code release
11 * November 2, 1999 Alan Cox cleaned up types/leaks
12 *
13 **********************************************************************
14 *
15 * This program is free software; you can redistribute it and/or
16 * modify it under the terms of the GNU General Public License as
17 * published by the Free Software Foundation; either version 2 of
18 * the License, or (at your option) any later version.
19 *
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public
26 * License along with this program; if not, write to the Free
27 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139,
28 * USA.
29 *
30 **********************************************************************
31 */
32
33#include <linux/module.h>
34#include <linux/poll.h>
35#include <linux/slab.h>
36#include <linux/bitops.h>
37#include <asm/io.h>
38#include <linux/sched.h>
39#include <linux/smp_lock.h>
40
41#include "hwaccess.h"
42#include "cardwo.h"
43#include "cardwi.h"
44#include "recmgr.h"
45#include "irqmgr.h"
46#include "audio.h"
47#include "8010.h"
48
49static void calculate_ofrag(struct woinst *);
50static void calculate_ifrag(struct wiinst *);
51
52static void emu10k1_waveout_bh(unsigned long refdata);
53static void emu10k1_wavein_bh(unsigned long refdata);
54
55/* Audio file operations */
56static ssize_t emu10k1_audio_read(struct file *file, char __user *buffer, size_t count, loff_t * ppos)
57{
58 struct emu10k1_wavedevice *wave_dev = (struct emu10k1_wavedevice *) file->private_data;
59 struct wiinst *wiinst = wave_dev->wiinst;
60 ssize_t ret = 0;
61 unsigned long flags;
62
63 DPD(3, "emu10k1_audio_read(), buffer=%p, count=%d\n", buffer, (u32) count);
64
65 if (!access_ok(VERIFY_WRITE, buffer, count))
66 return -EFAULT;
67
68 spin_lock_irqsave(&wiinst->lock, flags);
69
70 if (wiinst->mmapped) {
71 spin_unlock_irqrestore(&wiinst->lock, flags);
72 return -ENXIO;
73 }
74
75 if (wiinst->state == WAVE_STATE_CLOSED) {
76 calculate_ifrag(wiinst);
77
78 while (emu10k1_wavein_open(wave_dev) < 0) {
79 spin_unlock_irqrestore(&wiinst->lock, flags);
80
81 if (file->f_flags & O_NONBLOCK)
82 return -EAGAIN;
83
84 interruptible_sleep_on(&wave_dev->card->open_wait);
85
86 if (signal_pending(current))
87 return -ERESTARTSYS;
88
89 spin_lock_irqsave(&wiinst->lock, flags);
90 }
91 }
92
93 spin_unlock_irqrestore(&wiinst->lock, flags);
94
95 while (count > 0) {
96 u32 bytestocopy;
97
98 spin_lock_irqsave(&wiinst->lock, flags);
99
100 if (!(wiinst->state & WAVE_STATE_STARTED)
101 && (wave_dev->enablebits & PCM_ENABLE_INPUT))
102 emu10k1_wavein_start(wave_dev);
103
104 emu10k1_wavein_update(wave_dev->card, wiinst);
105 emu10k1_wavein_getxfersize(wiinst, &bytestocopy);
106
107 spin_unlock_irqrestore(&wiinst->lock, flags);
108
109 DPD(3, "bytestocopy --> %d\n", bytestocopy);
110
111 if ((bytestocopy >= wiinst->buffer.fragment_size)
112 || (bytestocopy >= count)) {
113 bytestocopy = min_t(u32, bytestocopy, count);
114
115 emu10k1_wavein_xferdata(wiinst, (u8 __user *)buffer, &bytestocopy);
116
117 count -= bytestocopy;
118 buffer += bytestocopy;
119 ret += bytestocopy;
120 }
121
122 if (count > 0) {
123 if ((file->f_flags & O_NONBLOCK)
124 || (!(wave_dev->enablebits & PCM_ENABLE_INPUT)))
125 return (ret ? ret : -EAGAIN);
126
127 interruptible_sleep_on(&wiinst->wait_queue);
128
129 if (signal_pending(current))
130 return (ret ? ret : -ERESTARTSYS);
131
132 }
133 }
134
135 DPD(3, "bytes copied -> %d\n", (u32) ret);
136
137 return ret;
138}
139
140static ssize_t emu10k1_audio_write(struct file *file, const char __user *buffer, size_t count, loff_t * ppos)
141{
142 struct emu10k1_wavedevice *wave_dev = (struct emu10k1_wavedevice *) file->private_data;
143 struct woinst *woinst = wave_dev->woinst;
144 ssize_t ret;
145 unsigned long flags;
146
147 DPD(3, "emu10k1_audio_write(), buffer=%p, count=%d\n", buffer, (u32) count);
148
149 if (!access_ok(VERIFY_READ, buffer, count))
150 return -EFAULT;
151
152 spin_lock_irqsave(&woinst->lock, flags);
153
154 if (woinst->mmapped) {
155 spin_unlock_irqrestore(&woinst->lock, flags);
156 return -ENXIO;
157 }
158 // This is for emu10k1 revs less than 7, we need to go through tram
159 if (woinst->format.passthrough == 1) {
160 int r;
161
162 woinst->buffer.ossfragshift = PT_BLOCKSIZE_LOG2;
163 woinst->buffer.numfrags = PT_BLOCKCOUNT;
164 calculate_ofrag(woinst);
165
166 r = emu10k1_pt_write(file, buffer, count);
167 spin_unlock_irqrestore(&woinst->lock, flags);
168 return r;
169 }
170
171 if (woinst->state == WAVE_STATE_CLOSED) {
172 calculate_ofrag(woinst);
173
174 while (emu10k1_waveout_open(wave_dev) < 0) {
175 spin_unlock_irqrestore(&woinst->lock, flags);
176
177 if (file->f_flags & O_NONBLOCK)
178 return -EAGAIN;
179
180 interruptible_sleep_on(&wave_dev->card->open_wait);
181
182 if (signal_pending(current))
183 return -ERESTARTSYS;
184
185 spin_lock_irqsave(&woinst->lock, flags);
186 }
187 }
188
189 spin_unlock_irqrestore(&woinst->lock, flags);
190
191 ret = 0;
192 if (count % woinst->format.bytespersample)
193 return -EINVAL;
194
195 count /= woinst->num_voices;
196
197 while (count > 0) {
198 u32 bytestocopy;
199
200 spin_lock_irqsave(&woinst->lock, flags);
201 emu10k1_waveout_update(woinst);
202 emu10k1_waveout_getxfersize(woinst, &bytestocopy);
203 spin_unlock_irqrestore(&woinst->lock, flags);
204
205 DPD(3, "bytestocopy --> %d\n", bytestocopy);
206
207 if ((bytestocopy >= woinst->buffer.fragment_size)
208 || (bytestocopy >= count)) {
209
210 bytestocopy = min_t(u32, bytestocopy, count);
211
212 emu10k1_waveout_xferdata(woinst, (u8 __user *) buffer, &bytestocopy);
213
214 count -= bytestocopy;
215 buffer += bytestocopy * woinst->num_voices;
216 ret += bytestocopy * woinst->num_voices;
217
218 spin_lock_irqsave(&woinst->lock, flags);
219 woinst->total_copied += bytestocopy;
220
221 if (!(woinst->state & WAVE_STATE_STARTED)
222 && (wave_dev->enablebits & PCM_ENABLE_OUTPUT)
223 && (woinst->total_copied >= woinst->buffer.fragment_size))
224 emu10k1_waveout_start(wave_dev);
225
226 spin_unlock_irqrestore(&woinst->lock, flags);
227 }
228
229 if (count > 0) {
230 if ((file->f_flags & O_NONBLOCK)
231 || (!(wave_dev->enablebits & PCM_ENABLE_OUTPUT)))
232 return (ret ? ret : -EAGAIN);
233
234 interruptible_sleep_on(&woinst->wait_queue);
235
236 if (signal_pending(current))
237 return (ret ? ret : -ERESTARTSYS);
238 }
239 }
240
241 DPD(3, "bytes copied -> %d\n", (u32) ret);
242
243 return ret;
244}
245
246static int emu10k1_audio_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
247{
248 struct emu10k1_wavedevice *wave_dev = (struct emu10k1_wavedevice *) file->private_data;
249 struct woinst *woinst = NULL;
250 struct wiinst *wiinst = NULL;
251 int val = 0;
252 u32 bytestocopy;
253 unsigned long flags;
254 int __user *p = (int __user *)arg;
255
256 DPF(4, "emu10k1_audio_ioctl()\n");
257
258 if (file->f_mode & FMODE_WRITE)
259 woinst = wave_dev->woinst;
260
261 if (file->f_mode & FMODE_READ)
262 wiinst = wave_dev->wiinst;
263
264 switch (cmd) {
265 case OSS_GETVERSION:
266 DPF(2, "OSS_GETVERSION:\n");
267 return put_user(SOUND_VERSION, p);
268
269 case SNDCTL_DSP_RESET:
270 DPF(2, "SNDCTL_DSP_RESET:\n");
271 wave_dev->enablebits = PCM_ENABLE_OUTPUT | PCM_ENABLE_INPUT;
272
273 if (file->f_mode & FMODE_WRITE) {
274 spin_lock_irqsave(&woinst->lock, flags);
275
276 if (woinst->state & WAVE_STATE_OPEN) {
277 emu10k1_waveout_close(wave_dev);
278 }
279
280 woinst->mmapped = 0;
281 woinst->total_copied = 0;
282 woinst->total_played = 0;
283 woinst->blocks = 0;
284
285 spin_unlock_irqrestore(&woinst->lock, flags);
286 }
287
288 if (file->f_mode & FMODE_READ) {
289 spin_lock_irqsave(&wiinst->lock, flags);
290
291 if (wiinst->state & WAVE_STATE_OPEN) {
292 emu10k1_wavein_close(wave_dev);
293 }
294
295 wiinst->mmapped = 0;
296 wiinst->total_recorded = 0;
297 wiinst->blocks = 0;
298 spin_unlock_irqrestore(&wiinst->lock, flags);
299 }
300
301 break;
302
303 case SNDCTL_DSP_SYNC:
304 DPF(2, "SNDCTL_DSP_SYNC:\n");
305
306 if (file->f_mode & FMODE_WRITE) {
307
308 spin_lock_irqsave(&woinst->lock, flags);
309
310 if (woinst->state & WAVE_STATE_OPEN) {
311
312 if (woinst->state & WAVE_STATE_STARTED)
313 while ((woinst->total_played < woinst->total_copied)
314 && !signal_pending(current)) {
315 spin_unlock_irqrestore(&woinst->lock, flags);
316 interruptible_sleep_on(&woinst->wait_queue);
317 spin_lock_irqsave(&woinst->lock, flags);
318 }
319 emu10k1_waveout_close(wave_dev);
320 }
321
322 woinst->mmapped = 0;
323 woinst->total_copied = 0;
324 woinst->total_played = 0;
325 woinst->blocks = 0;
326
327 spin_unlock_irqrestore(&woinst->lock, flags);
328 }
329
330 if (file->f_mode & FMODE_READ) {
331 spin_lock_irqsave(&wiinst->lock, flags);
332
333 if (wiinst->state & WAVE_STATE_OPEN) {
334 emu10k1_wavein_close(wave_dev);
335 }
336
337 wiinst->mmapped = 0;
338 wiinst->total_recorded = 0;
339 wiinst->blocks = 0;
340 spin_unlock_irqrestore(&wiinst->lock, flags);
341 }
342
343 break;
344
345 case SNDCTL_DSP_SETDUPLEX:
346 DPF(2, "SNDCTL_DSP_SETDUPLEX:\n");
347 break;
348
349 case SNDCTL_DSP_GETCAPS:
350 DPF(2, "SNDCTL_DSP_GETCAPS:\n");
351 return put_user(DSP_CAP_DUPLEX | DSP_CAP_REALTIME |
352 DSP_CAP_TRIGGER | DSP_CAP_MMAP |
353 DSP_CAP_COPROC| DSP_CAP_MULTI, p);
354 case SNDCTL_DSP_SPEED:
355 DPF(2, "SNDCTL_DSP_SPEED:\n");
356
357 if (get_user(val, p))
358 return -EFAULT;
359
360 DPD(2, "val is %d\n", val);
361
362 if (val > 0) {
363 if (file->f_mode & FMODE_READ) {
364 struct wave_format format;
365
366 spin_lock_irqsave(&wiinst->lock, flags);
367
368 format = wiinst->format;
369 format.samplingrate = val;
370
371 if (emu10k1_wavein_setformat(wave_dev, &format) < 0) {
372 spin_unlock_irqrestore(&wiinst->lock, flags);
373 return -EINVAL;
374 }
375
376 val = wiinst->format.samplingrate;
377
378 spin_unlock_irqrestore(&wiinst->lock, flags);
379
380 DPD(2, "set recording sampling rate -> %d\n", val);
381 }
382
383 if (file->f_mode & FMODE_WRITE) {
384 struct wave_format format;
385
386 spin_lock_irqsave(&woinst->lock, flags);
387
388 format = woinst->format;
389 format.samplingrate = val;
390
391 if (emu10k1_waveout_setformat(wave_dev, &format) < 0) {
392 spin_unlock_irqrestore(&woinst->lock, flags);
393 return -EINVAL;
394 }
395
396 val = woinst->format.samplingrate;
397
398 spin_unlock_irqrestore(&woinst->lock, flags);
399
400 DPD(2, "set playback sampling rate -> %d\n", val);
401 }
402
403 return put_user(val, p);
404 } else {
405 if (file->f_mode & FMODE_READ)
406 val = wiinst->format.samplingrate;
407 else if (file->f_mode & FMODE_WRITE)
408 val = woinst->format.samplingrate;
409
410 return put_user(val, p);
411 }
412 break;
413
414 case SNDCTL_DSP_STEREO:
415 DPF(2, "SNDCTL_DSP_STEREO:\n");
416
417 if (get_user(val, p))
418 return -EFAULT;
419
420 DPD(2, " val is %d\n", val);
421
422 if (file->f_mode & FMODE_READ) {
423 struct wave_format format;
424
425 spin_lock_irqsave(&wiinst->lock, flags);
426
427 format = wiinst->format;
428 format.channels = val ? 2 : 1;
429
430 if (emu10k1_wavein_setformat(wave_dev, &format) < 0) {
431 spin_unlock_irqrestore(&wiinst->lock, flags);
432 return -EINVAL;
433 }
434
435 val = wiinst->format.channels - 1;
436
437 spin_unlock_irqrestore(&wiinst->lock, flags);
438 DPD(2, "set recording stereo -> %d\n", val);
439 }
440
441 if (file->f_mode & FMODE_WRITE) {
442 struct wave_format format;
443
444 spin_lock_irqsave(&woinst->lock, flags);
445
446 format = woinst->format;
447 format.channels = val ? 2 : 1;
448
449 if (emu10k1_waveout_setformat(wave_dev, &format) < 0) {
450 spin_unlock_irqrestore(&woinst->lock, flags);
451 return -EINVAL;
452 }
453
454 val = woinst->format.channels - 1;
455
456 spin_unlock_irqrestore(&woinst->lock, flags);
457
458 DPD(2, "set playback stereo -> %d\n", val);
459 }
460
461 return put_user(val, p);
462
463 break;
464
465 case SNDCTL_DSP_CHANNELS:
466 DPF(2, "SNDCTL_DSP_CHANNELS:\n");
467
468 if (get_user(val, p))
469 return -EFAULT;
470
471 DPD(2, " val is %d\n", val);
472
473 if (val > 0) {
474 if (file->f_mode & FMODE_READ) {
475 struct wave_format format;
476
477 spin_lock_irqsave(&wiinst->lock, flags);
478
479 format = wiinst->format;
480 format.channels = val;
481
482 if (emu10k1_wavein_setformat(wave_dev, &format) < 0) {
483 spin_unlock_irqrestore(&wiinst->lock, flags);
484 return -EINVAL;
485 }
486 val = wiinst->format.channels;
487
488 spin_unlock_irqrestore(&wiinst->lock, flags);
489 DPD(2, "set recording number of channels -> %d\n", val);
490 }
491
492 if (file->f_mode & FMODE_WRITE) {
493 struct wave_format format;
494
495 spin_lock_irqsave(&woinst->lock, flags);
496
497 format = woinst->format;
498 format.channels = val;
499
500 if (emu10k1_waveout_setformat(wave_dev, &format) < 0) {
501 spin_unlock_irqrestore(&woinst->lock, flags);
502 return -EINVAL;
503 }
504
505 val = woinst->format.channels;
506
507 spin_unlock_irqrestore(&woinst->lock, flags);
508 DPD(2, "set playback number of channels -> %d\n", val);
509 }
510
511 return put_user(val, p);
512 } else {
513 if (file->f_mode & FMODE_READ)
514 val = wiinst->format.channels;
515 else if (file->f_mode & FMODE_WRITE)
516 val = woinst->format.channels;
517
518 return put_user(val, p);
519 }
520 break;
521
522 case SNDCTL_DSP_GETFMTS:
523 DPF(2, "SNDCTL_DSP_GETFMTS:\n");
524
525 if (file->f_mode & FMODE_READ)
526 val = AFMT_S16_LE;
527 else if (file->f_mode & FMODE_WRITE) {
528 val = AFMT_S16_LE | AFMT_U8;
529 if (emu10k1_find_control_gpr(&wave_dev->card->mgr,
530 wave_dev->card->pt.patch_name,
531 wave_dev->card->pt.enable_gpr_name) >= 0)
532 val |= AFMT_AC3;
533 }
534 return put_user(val, p);
535
536 case SNDCTL_DSP_SETFMT: /* Same as SNDCTL_DSP_SAMPLESIZE */
537 DPF(2, "SNDCTL_DSP_SETFMT:\n");
538
539 if (get_user(val, p))
540 return -EFAULT;
541
542 DPD(2, " val is %d\n", val);
543
544 if (val != AFMT_QUERY) {
545 if (file->f_mode & FMODE_READ) {
546 struct wave_format format;
547
548 spin_lock_irqsave(&wiinst->lock, flags);
549
550 format = wiinst->format;
551 format.id = val;
552
553 if (emu10k1_wavein_setformat(wave_dev, &format) < 0) {
554 spin_unlock_irqrestore(&wiinst->lock, flags);
555 return -EINVAL;
556 }
557
558 val = wiinst->format.id;
559
560 spin_unlock_irqrestore(&wiinst->lock, flags);
561 DPD(2, "set recording format -> %d\n", val);
562 }
563
564 if (file->f_mode & FMODE_WRITE) {
565 struct wave_format format;
566
567 spin_lock_irqsave(&woinst->lock, flags);
568
569 format = woinst->format;
570 format.id = val;
571
572 if (emu10k1_waveout_setformat(wave_dev, &format) < 0) {
573 spin_unlock_irqrestore(&woinst->lock, flags);
574 return -EINVAL;
575 }
576
577 val = woinst->format.id;
578
579 spin_unlock_irqrestore(&woinst->lock, flags);
580 DPD(2, "set playback format -> %d\n", val);
581 }
582
583 return put_user(val, p);
584 } else {
585 if (file->f_mode & FMODE_READ)
586 val = wiinst->format.id;
587 else if (file->f_mode & FMODE_WRITE)
588 val = woinst->format.id;
589
590 return put_user(val, p);
591 }
592 break;
593
594 case SOUND_PCM_READ_BITS:
595
596 if (file->f_mode & FMODE_READ)
597 val = wiinst->format.bitsperchannel;
598 else if (file->f_mode & FMODE_WRITE)
599 val = woinst->format.bitsperchannel;
600
601 return put_user(val, p);
602
603 case SOUND_PCM_READ_RATE:
604
605 if (file->f_mode & FMODE_READ)
606 val = wiinst->format.samplingrate;
607 else if (file->f_mode & FMODE_WRITE)
608 val = woinst->format.samplingrate;
609
610 return put_user(val, p);
611
612 case SOUND_PCM_READ_CHANNELS:
613
614 if (file->f_mode & FMODE_READ)
615 val = wiinst->format.channels;
616 else if (file->f_mode & FMODE_WRITE)
617 val = woinst->format.channels;
618
619 return put_user(val, p);
620
621 case SOUND_PCM_WRITE_FILTER:
622 DPF(2, "SOUND_PCM_WRITE_FILTER: not implemented\n");
623 break;
624
625 case SOUND_PCM_READ_FILTER:
626 DPF(2, "SOUND_PCM_READ_FILTER: not implemented\n");
627 break;
628
629 case SNDCTL_DSP_SETSYNCRO:
630 DPF(2, "SNDCTL_DSP_SETSYNCRO: not implemented\n");
631 break;
632
633 case SNDCTL_DSP_GETTRIGGER:
634 DPF(2, "SNDCTL_DSP_GETTRIGGER:\n");
635
636 if (file->f_mode & FMODE_WRITE && (wave_dev->enablebits & PCM_ENABLE_OUTPUT))
637 val |= PCM_ENABLE_OUTPUT;
638
639 if (file->f_mode & FMODE_READ && (wave_dev->enablebits & PCM_ENABLE_INPUT))
640 val |= PCM_ENABLE_INPUT;
641
642 return put_user(val, p);
643
644 case SNDCTL_DSP_SETTRIGGER:
645 DPF(2, "SNDCTL_DSP_SETTRIGGER:\n");
646
647 if (get_user(val, p))
648 return -EFAULT;
649
650 if (file->f_mode & FMODE_WRITE) {
651 spin_lock_irqsave(&woinst->lock, flags);
652
653 if (val & PCM_ENABLE_OUTPUT) {
654 wave_dev->enablebits |= PCM_ENABLE_OUTPUT;
655 if (woinst->state & WAVE_STATE_OPEN)
656 emu10k1_waveout_start(wave_dev);
657 } else {
658 wave_dev->enablebits &= ~PCM_ENABLE_OUTPUT;
659 if (woinst->state & WAVE_STATE_STARTED)
660 emu10k1_waveout_stop(wave_dev);
661 }
662
663 spin_unlock_irqrestore(&woinst->lock, flags);
664 }
665
666 if (file->f_mode & FMODE_READ) {
667 spin_lock_irqsave(&wiinst->lock, flags);
668
669 if (val & PCM_ENABLE_INPUT) {
670 wave_dev->enablebits |= PCM_ENABLE_INPUT;
671 if (wiinst->state & WAVE_STATE_OPEN)
672 emu10k1_wavein_start(wave_dev);
673 } else {
674 wave_dev->enablebits &= ~PCM_ENABLE_INPUT;
675 if (wiinst->state & WAVE_STATE_STARTED)
676 emu10k1_wavein_stop(wave_dev);
677 }
678
679 spin_unlock_irqrestore(&wiinst->lock, flags);
680 }
681 break;
682
683 case SNDCTL_DSP_GETOSPACE:
684 {
685 audio_buf_info info;
686
687 DPF(4, "SNDCTL_DSP_GETOSPACE:\n");
688
689 if (!(file->f_mode & FMODE_WRITE))
690 return -EINVAL;
691
692 spin_lock_irqsave(&woinst->lock, flags);
693
694 if (woinst->state & WAVE_STATE_OPEN) {
695 emu10k1_waveout_update(woinst);
696 emu10k1_waveout_getxfersize(woinst, &bytestocopy);
697 info.bytes = bytestocopy;
698 } else {
699 calculate_ofrag(woinst);
700 info.bytes = woinst->buffer.size;
701 }
702 spin_unlock_irqrestore(&woinst->lock, flags);
703
704 info.bytes *= woinst->num_voices;
705 info.fragsize = woinst->buffer.fragment_size * woinst->num_voices;
706 info.fragstotal = woinst->buffer.numfrags * woinst->num_voices;
707 info.fragments = info.bytes / info.fragsize;
708
709 if (copy_to_user(p, &info, sizeof(info)))
710 return -EFAULT;
711 }
712 break;
713
714 case SNDCTL_DSP_GETISPACE:
715 {
716 audio_buf_info info;
717
718 DPF(4, "SNDCTL_DSP_GETISPACE:\n");
719
720 if (!(file->f_mode & FMODE_READ))
721 return -EINVAL;
722
723 spin_lock_irqsave(&wiinst->lock, flags);
724 if (wiinst->state & WAVE_STATE_OPEN) {
725 emu10k1_wavein_update(wave_dev->card, wiinst);
726 emu10k1_wavein_getxfersize(wiinst, &bytestocopy);
727 info.bytes = bytestocopy;
728 } else {
729 calculate_ifrag(wiinst);
730 info.bytes = 0;
731 }
732 spin_unlock_irqrestore(&wiinst->lock, flags);
733
734 info.fragstotal = wiinst->buffer.numfrags;
735 info.fragments = info.bytes / wiinst->buffer.fragment_size;
736 info.fragsize = wiinst->buffer.fragment_size;
737
738 if (copy_to_user(p, &info, sizeof(info)))
739 return -EFAULT;
740 }
741 break;
742
743 case SNDCTL_DSP_NONBLOCK:
744 DPF(2, "SNDCTL_DSP_NONBLOCK:\n");
745
746 file->f_flags |= O_NONBLOCK;
747 break;
748
749 case SNDCTL_DSP_GETODELAY:
750 DPF(4, "SNDCTL_DSP_GETODELAY:\n");
751
752 if (!(file->f_mode & FMODE_WRITE))
753 return -EINVAL;
754
755 spin_lock_irqsave(&woinst->lock, flags);
756 if (woinst->state & WAVE_STATE_OPEN) {
757 emu10k1_waveout_update(woinst);
758 emu10k1_waveout_getxfersize(woinst, &bytestocopy);
759 val = woinst->buffer.size - bytestocopy;
760 } else
761 val = 0;
762
763 val *= woinst->num_voices;
764 spin_unlock_irqrestore(&woinst->lock, flags);
765
766 return put_user(val, p);
767
768 case SNDCTL_DSP_GETIPTR:
769 {
770 count_info cinfo;
771
772 DPF(4, "SNDCTL_DSP_GETIPTR: \n");
773
774 if (!(file->f_mode & FMODE_READ))
775 return -EINVAL;
776
777 spin_lock_irqsave(&wiinst->lock, flags);
778
779 if (wiinst->state & WAVE_STATE_OPEN) {
780 emu10k1_wavein_update(wave_dev->card, wiinst);
781 cinfo.ptr = wiinst->buffer.hw_pos;
782 cinfo.bytes = cinfo.ptr + wiinst->total_recorded - wiinst->total_recorded % wiinst->buffer.size;
783 cinfo.blocks = cinfo.bytes / wiinst->buffer.fragment_size - wiinst->blocks;
784 wiinst->blocks = cinfo.bytes / wiinst->buffer.fragment_size;
785 } else {
786 cinfo.ptr = 0;
787 cinfo.bytes = 0;
788 cinfo.blocks = 0;
789 }
790
791 if (wiinst->mmapped)
792 wiinst->buffer.bytestocopy %= wiinst->buffer.fragment_size;
793
794 spin_unlock_irqrestore(&wiinst->lock, flags);
795
796 if (copy_to_user(p, &cinfo, sizeof(cinfo)))
797 return -EFAULT;
798 }
799 break;
800
801 case SNDCTL_DSP_GETOPTR:
802 {
803 count_info cinfo;
804
805 DPF(4, "SNDCTL_DSP_GETOPTR:\n");
806
807 if (!(file->f_mode & FMODE_WRITE))
808 return -EINVAL;
809
810 spin_lock_irqsave(&woinst->lock, flags);
811
812 if (woinst->state & WAVE_STATE_OPEN ||
813 ((woinst->format.passthrough == 1) && wave_dev->card->pt.state)) {
814 int num_fragments;
815
816 if (woinst->format.passthrough == 1) {
817 emu10k1_pt_waveout_update(wave_dev);
818 cinfo.bytes = woinst->total_played;
819 } else {
820 emu10k1_waveout_update(woinst);
821 cinfo.bytes = woinst->total_played;
822 }
823
824 cinfo.ptr = woinst->buffer.hw_pos;
825 num_fragments = cinfo.bytes / woinst->buffer.fragment_size;
826 cinfo.blocks = num_fragments - woinst->blocks;
827 woinst->blocks = num_fragments;
828
829 cinfo.bytes *= woinst->num_voices;
830 cinfo.ptr *= woinst->num_voices;
831 } else {
832 cinfo.ptr = 0;
833 cinfo.bytes = 0;
834 cinfo.blocks = 0;
835 }
836
837 if (woinst->mmapped)
838 woinst->buffer.free_bytes %= woinst->buffer.fragment_size;
839
840 spin_unlock_irqrestore(&woinst->lock, flags);
841
842 if (copy_to_user(p, &cinfo, sizeof(cinfo)))
843 return -EFAULT;
844 }
845 break;
846
847 case SNDCTL_DSP_GETBLKSIZE:
848 DPF(2, "SNDCTL_DSP_GETBLKSIZE:\n");
849
850 if (file->f_mode & FMODE_WRITE) {
851 spin_lock_irqsave(&woinst->lock, flags);
852
853 calculate_ofrag(woinst);
854 val = woinst->buffer.fragment_size * woinst->num_voices;
855
856 spin_unlock_irqrestore(&woinst->lock, flags);
857 }
858
859 if (file->f_mode & FMODE_READ) {
860 spin_lock_irqsave(&wiinst->lock, flags);
861
862 calculate_ifrag(wiinst);
863 val = wiinst->buffer.fragment_size;
864
865 spin_unlock_irqrestore(&wiinst->lock, flags);
866 }
867
868 return put_user(val, p);
869
870 break;
871
872 case SNDCTL_DSP_POST:
873 if (file->f_mode & FMODE_WRITE) {
874 spin_lock_irqsave(&woinst->lock, flags);
875
876 if (!(woinst->state & WAVE_STATE_STARTED)
877 && (wave_dev->enablebits & PCM_ENABLE_OUTPUT)
878 && (woinst->total_copied > 0))
879 emu10k1_waveout_start(wave_dev);
880
881 spin_unlock_irqrestore(&woinst->lock, flags);
882 }
883
884 break;
885
886 case SNDCTL_DSP_SUBDIVIDE:
887 DPF(2, "SNDCTL_DSP_SUBDIVIDE: not implemented\n");
888 break;
889
890 case SNDCTL_DSP_SETFRAGMENT:
891 DPF(2, "SNDCTL_DSP_SETFRAGMENT:\n");
892
893 if (get_user(val, p))
894 return -EFAULT;
895
896 DPD(2, "val is %#x\n", val);
897
898 if (val == 0)
899 return -EIO;
900
901 if (file->f_mode & FMODE_WRITE) {
902 /* digital pass-through fragment count and size are fixed values */
903 if (woinst->state & WAVE_STATE_OPEN || (woinst->format.passthrough == 1))
904 return -EINVAL; /* too late to change */
905
906 woinst->buffer.ossfragshift = val & 0xffff;
907 woinst->buffer.numfrags = (val >> 16) & 0xffff;
908 }
909
910 if (file->f_mode & FMODE_READ) {
911 if (wiinst->state & WAVE_STATE_OPEN)
912 return -EINVAL; /* too late to change */
913
914 wiinst->buffer.ossfragshift = val & 0xffff;
915 wiinst->buffer.numfrags = (val >> 16) & 0xffff;
916 }
917
918 break;
919
920 case SNDCTL_COPR_LOAD:
921 {
922 copr_buffer *buf;
923 u32 i;
924
925 DPF(4, "SNDCTL_COPR_LOAD:\n");
926
927 buf = kmalloc(sizeof(copr_buffer), GFP_KERNEL);
928 if (!buf)
929 return -ENOMEM;
930
931 if (copy_from_user(buf, p, sizeof(copr_buffer))) {
932 kfree (buf);
933 return -EFAULT;
934 }
935
936 if ((buf->command != CMD_READ) && (buf->command != CMD_WRITE)) {
937 kfree (buf);
938 return -EINVAL;
939 }
940
941 if (buf->command == CMD_WRITE) {
942
943#ifdef DBGEMU
944 if ((buf->offs < 0) || (buf->offs + buf->len > 0xe00) || (buf->len > 1000)) {
945#else
946 if (((buf->offs < 0x100) || (buf->offs + buf->len > (wave_dev->card->is_audigy ? 0xe00 : 0x800)) || (buf->len > 1000)
947 ) && !(
948 //any register allowed raw access to users goes here:
949 (buf->offs == DBG ||
950 buf->offs == A_DBG)
951 && (buf->len == 1))) {
952#endif
953 kfree(buf);
954 return -EINVAL;
955 }
956 } else {
957 if ((buf->offs < 0) || (buf->offs + buf->len > 0xe00) || (buf->len > 1000)) {
958 kfree(buf);
959 return -EINVAL;
960 }
961 }
962
963 if (((unsigned)buf->flags) > 0x3f)
964 buf->flags = 0;
965
966 if (buf->command == CMD_READ) {
967 for (i = 0; i < buf->len; i++)
968 ((u32 *) buf->data)[i] = sblive_readptr(wave_dev->card, buf->offs + i, buf->flags);
969
970 if (copy_to_user(p, buf, sizeof(copr_buffer))) {
971 kfree(buf);
972 return -EFAULT;
973 }
974 } else {
975 for (i = 0; i < buf->len; i++)
976 sblive_writeptr(wave_dev->card, buf->offs + i, buf->flags, ((u32 *) buf->data)[i]);
977 }
978
979 kfree (buf);
980 break;
981 }
982
983 default: /* Default is unrecognized command */
984 DPD(2, "default: %#x\n", cmd);
985 return -EINVAL;
986 }
987 return 0;
988}
989
990static struct page *emu10k1_mm_nopage (struct vm_area_struct * vma, unsigned long address, int *type)
991{
992 struct emu10k1_wavedevice *wave_dev = vma->vm_private_data;
993 struct woinst *woinst = wave_dev->woinst;
994 struct wiinst *wiinst = wave_dev->wiinst;
995 struct page *dmapage;
996 unsigned long pgoff;
997 int rd, wr;
998
999 DPF(3, "emu10k1_mm_nopage()\n");
1000 DPD(3, "addr: %#lx\n", address);
1001
1002 if (address > vma->vm_end) {
1003 DPF(1, "EXIT, returning NOPAGE_SIGBUS\n");
1004 return NOPAGE_SIGBUS; /* Disallow mremap */
1005 }
1006
1007 pgoff = vma->vm_pgoff + ((address - vma->vm_start) >> PAGE_SHIFT);
1008 if (woinst != NULL)
1009 wr = woinst->mmapped;
1010 else
1011 wr = 0;
1012
1013 if (wiinst != NULL)
1014 rd = wiinst->mmapped;
1015 else
1016 rd = 0;
1017
1018 /* if full-duplex (read+write) and we have two sets of bufs,
1019 * then the playback buffers come first, sez soundcard.c */
1020 if (wr) {
1021 if (pgoff >= woinst->buffer.pages) {
1022 pgoff -= woinst->buffer.pages;
1023 dmapage = virt_to_page ((u8 *) wiinst->buffer.addr + pgoff * PAGE_SIZE);
1024 } else
1025 dmapage = virt_to_page (woinst->voice[0].mem.addr[pgoff]);
1026 } else {
1027 dmapage = virt_to_page ((u8 *) wiinst->buffer.addr + pgoff * PAGE_SIZE);
1028 }
1029
1030 get_page (dmapage);
1031
1032 DPD(3, "page: %#lx\n", (unsigned long) dmapage);
1033 if (type)
1034 *type = VM_FAULT_MINOR;
1035 return dmapage;
1036}
1037
1038static struct vm_operations_struct emu10k1_mm_ops = {
1039 .nopage = emu10k1_mm_nopage,
1040};
1041
1042static int emu10k1_audio_mmap(struct file *file, struct vm_area_struct *vma)
1043{
1044 struct emu10k1_wavedevice *wave_dev = (struct emu10k1_wavedevice *) file->private_data;
1045 unsigned long max_pages, n_pages, pgoffset;
1046 struct woinst *woinst = NULL;
1047 struct wiinst *wiinst = NULL;
1048 unsigned long flags;
1049
1050 DPF(2, "emu10k1_audio_mmap()\n");
1051
1052 max_pages = 0;
1053 if (vma->vm_flags & VM_WRITE) {
1054 woinst = wave_dev->woinst;
1055
1056 spin_lock_irqsave(&woinst->lock, flags);
1057
1058 /* No m'mapping possible for multichannel */
1059 if (woinst->num_voices > 1) {
1060 spin_unlock_irqrestore(&woinst->lock, flags);
1061 return -EINVAL;
1062 }
1063
1064 if (woinst->state == WAVE_STATE_CLOSED) {
1065 calculate_ofrag(woinst);
1066
1067 if (emu10k1_waveout_open(wave_dev) < 0) {
1068 spin_unlock_irqrestore(&woinst->lock, flags);
1069 ERROR();
1070 return -EINVAL;
1071 }
1072 }
1073
1074 woinst->mmapped = 1;
1075 max_pages += woinst->buffer.pages;
1076 spin_unlock_irqrestore(&woinst->lock, flags);
1077 }
1078
1079 if (vma->vm_flags & VM_READ) {
1080 wiinst = wave_dev->wiinst;
1081
1082 spin_lock_irqsave(&wiinst->lock, flags);
1083 if (wiinst->state == WAVE_STATE_CLOSED) {
1084 calculate_ifrag(wiinst);
1085
1086 if (emu10k1_wavein_open(wave_dev) < 0) {
1087 spin_unlock_irqrestore(&wiinst->lock, flags);
1088 ERROR();
1089 return -EINVAL;
1090 }
1091 }
1092
1093 wiinst->mmapped = 1;
1094 max_pages += wiinst->buffer.pages;
1095 spin_unlock_irqrestore(&wiinst->lock, flags);
1096 }
1097
1098 n_pages = ((vma->vm_end - vma->vm_start) + PAGE_SIZE - 1) >> PAGE_SHIFT;
1099 pgoffset = vma->vm_pgoff;
1100
1101 DPD(2, "vma_start: %#lx, vma_end: %#lx, vma_offset: %ld\n", vma->vm_start, vma->vm_end, pgoffset);
1102 DPD(2, "n_pages: %ld, max_pages: %ld\n", n_pages, max_pages);
1103
1104 if (pgoffset + n_pages > max_pages)
1105 return -EINVAL;
1106
1107 vma->vm_flags |= VM_RESERVED;
1108 vma->vm_ops = &emu10k1_mm_ops;
1109 vma->vm_private_data = wave_dev;
1110 return 0;
1111}
1112
1113static int emu10k1_audio_open(struct inode *inode, struct file *file)
1114{
1115 int minor = iminor(inode);
1116 struct emu10k1_card *card = NULL;
1117 struct list_head *entry;
1118 struct emu10k1_wavedevice *wave_dev;
1119
1120 DPF(2, "emu10k1_audio_open()\n");
1121
1122 /* Check for correct device to open */
1123
1124 list_for_each(entry, &emu10k1_devs) {
1125 card = list_entry(entry, struct emu10k1_card, list);
1126
1127 if (!((card->audio_dev ^ minor) & ~0xf) || !((card->audio_dev1 ^ minor) & ~0xf))
1128 goto match;
1129 }
1130
1131 return -ENODEV;
1132
1133match:
1134
1135 wave_dev = (struct emu10k1_wavedevice *) kmalloc(sizeof(struct emu10k1_wavedevice), GFP_KERNEL);
1136
1137 if (wave_dev == NULL) {
1138 ERROR();
1139 return -ENOMEM;
1140 }
1141
1142 wave_dev->card = card;
1143 wave_dev->wiinst = NULL;
1144 wave_dev->woinst = NULL;
1145 wave_dev->enablebits = PCM_ENABLE_OUTPUT | PCM_ENABLE_INPUT; /* Default */
1146
1147 if (file->f_mode & FMODE_READ) {
1148 /* Recording */
1149 struct wiinst *wiinst;
1150
1151 if ((wiinst = (struct wiinst *) kmalloc(sizeof(struct wiinst), GFP_KERNEL)) == NULL) {
1152 ERROR();
1153 kfree(wave_dev);
1154 return -ENOMEM;
1155 }
1156
1157 wiinst->recsrc = card->wavein.recsrc;
1158 wiinst->fxwc = card->wavein.fxwc;
1159
1160 switch (wiinst->recsrc) {
1161 case WAVERECORD_AC97:
1162 wiinst->format.id = AFMT_S16_LE;
1163 wiinst->format.samplingrate = 8000;
1164 wiinst->format.bitsperchannel = 16;
1165 wiinst->format.channels = 1;
1166 break;
1167 case WAVERECORD_MIC:
1168 wiinst->format.id = AFMT_S16_LE;
1169 wiinst->format.samplingrate = 8000;
1170 wiinst->format.bitsperchannel = 16;
1171 wiinst->format.channels = 1;
1172 break;
1173 case WAVERECORD_FX:
1174 wiinst->format.id = AFMT_S16_LE;
1175 wiinst->format.samplingrate = 48000;
1176 wiinst->format.bitsperchannel = 16;
1177 wiinst->format.channels = hweight32(wiinst->fxwc);
1178 break;
1179 default:
1180 kfree(wave_dev);
1181 kfree(wiinst);
1182 BUG();
1183 break;
1184 }
1185
1186 wiinst->state = WAVE_STATE_CLOSED;
1187
1188 wiinst->buffer.ossfragshift = 0;
1189 wiinst->buffer.fragment_size = 0;
1190 wiinst->buffer.numfrags = 0;
1191
1192 init_waitqueue_head(&wiinst->wait_queue);
1193
1194 wiinst->mmapped = 0;
1195 wiinst->total_recorded = 0;
1196 wiinst->blocks = 0;
1197 spin_lock_init(&wiinst->lock);
1198 tasklet_init(&wiinst->timer.tasklet, emu10k1_wavein_bh, (unsigned long) wave_dev);
1199 wave_dev->wiinst = wiinst;
1200 emu10k1_wavein_setformat(wave_dev, &wiinst->format);
1201 }
1202
1203 if (file->f_mode & FMODE_WRITE) {
1204 struct woinst *woinst;
1205 int i;
1206
1207 if ((woinst = (struct woinst *) kmalloc(sizeof(struct woinst), GFP_KERNEL)) == NULL) {
1208 ERROR();
1209 kfree(wave_dev);
1210 return -ENOMEM;
1211 }
1212
1213 if (wave_dev->wiinst != NULL) {
1214 woinst->format = wave_dev->wiinst->format;
1215 } else {
1216 woinst->format.id = AFMT_U8;
1217 woinst->format.samplingrate = 8000;
1218 woinst->format.bitsperchannel = 8;
1219 woinst->format.channels = 1;
1220 }
1221
1222 woinst->state = WAVE_STATE_CLOSED;
1223
1224 woinst->buffer.fragment_size = 0;
1225 woinst->buffer.ossfragshift = 0;
1226 woinst->buffer.numfrags = 0;
1227 woinst->device = (card->audio_dev1 == minor);
1228 woinst->timer.state = TIMER_STATE_UNINSTALLED;
1229 woinst->num_voices = 1;
1230 for (i = 0; i < WAVEOUT_MAXVOICES; i++) {
1231 woinst->voice[i].usage = VOICE_USAGE_FREE;
1232 woinst->voice[i].mem.emupageindex = -1;
1233 }
1234
1235 init_waitqueue_head(&woinst->wait_queue);
1236
1237 woinst->mmapped = 0;
1238 woinst->total_copied = 0;
1239 woinst->total_played = 0;
1240 woinst->blocks = 0;
1241 spin_lock_init(&woinst->lock);
1242 tasklet_init(&woinst->timer.tasklet, emu10k1_waveout_bh, (unsigned long) wave_dev);
1243 wave_dev->woinst = woinst;
1244 emu10k1_waveout_setformat(wave_dev, &woinst->format);
1245 }
1246
1247 file->private_data = (void *) wave_dev;
1248
1249 return nonseekable_open(inode, file);
1250}
1251
1252static int emu10k1_audio_release(struct inode *inode, struct file *file)
1253{
1254 struct emu10k1_wavedevice *wave_dev = (struct emu10k1_wavedevice *) file->private_data;
1255 struct emu10k1_card *card;
1256 unsigned long flags;
1257
1258 card = wave_dev->card;
1259
1260 DPF(2, "emu10k1_audio_release()\n");
1261
1262 if (file->f_mode & FMODE_WRITE) {
1263 struct woinst *woinst = wave_dev->woinst;
1264
1265 spin_lock_irqsave(&woinst->lock, flags);
1266 if(woinst->format.passthrough==2)
1267 card->pt.state=PT_STATE_PLAYING;
1268 if (woinst->format.passthrough && card->pt.state != PT_STATE_INACTIVE){
1269 spin_lock(&card->pt.lock);
1270 emu10k1_pt_stop(card);
1271 spin_unlock(&card->pt.lock);
1272 }
1273 if (woinst->state & WAVE_STATE_OPEN) {
1274 if (woinst->state & WAVE_STATE_STARTED) {
1275 if (!(file->f_flags & O_NONBLOCK)) {
1276 while (!signal_pending(current)
1277 && (woinst->total_played < woinst->total_copied)) {
1278 DPF(4, "Buffer hasn't been totally played, sleep....\n");
1279 spin_unlock_irqrestore(&woinst->lock, flags);
1280 interruptible_sleep_on(&woinst->wait_queue);
1281 spin_lock_irqsave(&woinst->lock, flags);
1282 }
1283 }
1284 }
1285 emu10k1_waveout_close(wave_dev);
1286 }
1287
1288 spin_unlock_irqrestore(&woinst->lock, flags);
1289 /* remove the tasklet */
1290 tasklet_kill(&woinst->timer.tasklet);
1291 kfree(wave_dev->woinst);
1292 }
1293
1294 if (file->f_mode & FMODE_READ) {
1295 struct wiinst *wiinst = wave_dev->wiinst;
1296
1297 spin_lock_irqsave(&wiinst->lock, flags);
1298
1299 if (wiinst->state & WAVE_STATE_OPEN) {
1300 emu10k1_wavein_close(wave_dev);
1301 }
1302
1303 spin_unlock_irqrestore(&wiinst->lock, flags);
1304 tasklet_kill(&wiinst->timer.tasklet);
1305 kfree(wave_dev->wiinst);
1306 }
1307
1308 kfree(wave_dev);
1309
1310 if (waitqueue_active(&card->open_wait))
1311 wake_up_interruptible(&card->open_wait);
1312
1313 return 0;
1314}
1315
1316/* FIXME sort out poll() + mmap() */
1317static unsigned int emu10k1_audio_poll(struct file *file, struct poll_table_struct *wait)
1318{
1319 struct emu10k1_wavedevice *wave_dev = (struct emu10k1_wavedevice *) file->private_data;
1320 struct woinst *woinst = wave_dev->woinst;
1321 struct wiinst *wiinst = wave_dev->wiinst;
1322 unsigned int mask = 0;
1323 u32 bytestocopy;
1324 unsigned long flags;
1325
1326 DPF(4, "emu10k1_audio_poll()\n");
1327
1328 if (file->f_mode & FMODE_WRITE)
1329 poll_wait(file, &woinst->wait_queue, wait);
1330
1331 if (file->f_mode & FMODE_READ)
1332 poll_wait(file, &wiinst->wait_queue, wait);
1333
1334 if (file->f_mode & FMODE_WRITE) {
1335 spin_lock_irqsave(&woinst->lock, flags);
1336
1337 if (woinst->state & WAVE_STATE_OPEN) {
1338 emu10k1_waveout_update(woinst);
1339 emu10k1_waveout_getxfersize(woinst, &bytestocopy);
1340
1341 if (bytestocopy >= woinst->buffer.fragment_size)
1342 mask |= POLLOUT | POLLWRNORM;
1343 } else
1344 mask |= POLLOUT | POLLWRNORM;
1345
1346 spin_unlock_irqrestore(&woinst->lock, flags);
1347 }
1348
1349 if (file->f_mode & FMODE_READ) {
1350 spin_lock_irqsave(&wiinst->lock, flags);
1351
1352 if (wiinst->state & WAVE_STATE_OPEN) {
1353 emu10k1_wavein_update(wave_dev->card, wiinst);
1354 emu10k1_wavein_getxfersize(wiinst, &bytestocopy);
1355
1356 if (bytestocopy >= wiinst->buffer.fragment_size)
1357 mask |= POLLIN | POLLRDNORM;
1358 }
1359
1360 spin_unlock_irqrestore(&wiinst->lock, flags);
1361 }
1362
1363 return mask;
1364}
1365
1366static void calculate_ofrag(struct woinst *woinst)
1367{
1368 struct waveout_buffer *buffer = &woinst->buffer;
1369 u32 fragsize;
1370
1371 if (buffer->fragment_size)
1372 return;
1373
1374 if (!buffer->ossfragshift) {
1375 fragsize = (woinst->format.bytespervoicesample * woinst->format.samplingrate * WAVEOUT_DEFAULTFRAGLEN) / 1000 - 1;
1376
1377 while (fragsize) {
1378 fragsize >>= 1;
1379 buffer->ossfragshift++;
1380 }
1381 }
1382
1383 if (buffer->ossfragshift < WAVEOUT_MINFRAGSHIFT)
1384 buffer->ossfragshift = WAVEOUT_MINFRAGSHIFT;
1385
1386 buffer->fragment_size = 1 << buffer->ossfragshift;
1387
1388 while (buffer->fragment_size * WAVEOUT_MINFRAGS > WAVEOUT_MAXBUFSIZE)
1389 buffer->fragment_size >>= 1;
1390
1391 /* now we are sure that:
1392 (2^WAVEOUT_MINFRAGSHIFT) <= (fragment_size = 2^n) <= (WAVEOUT_MAXBUFSIZE / WAVEOUT_MINFRAGS)
1393 */
1394
1395 if (!buffer->numfrags) {
1396 u32 numfrags;
1397
1398 numfrags = (woinst->format.bytespervoicesample * woinst->format.samplingrate * WAVEOUT_DEFAULTBUFLEN) /
1399 (buffer->fragment_size * 1000) - 1;
1400
1401 buffer->numfrags = 1;
1402
1403 while (numfrags) {
1404 numfrags >>= 1;
1405 buffer->numfrags <<= 1;
1406 }
1407 }
1408
1409 if (buffer->numfrags < WAVEOUT_MINFRAGS)
1410 buffer->numfrags = WAVEOUT_MINFRAGS;
1411
1412 if (buffer->numfrags * buffer->fragment_size > WAVEOUT_MAXBUFSIZE)
1413 buffer->numfrags = WAVEOUT_MAXBUFSIZE / buffer->fragment_size;
1414
1415 if (buffer->numfrags < WAVEOUT_MINFRAGS)
1416 BUG();
1417
1418 buffer->size = buffer->fragment_size * buffer->numfrags;
1419 buffer->pages = buffer->size / PAGE_SIZE + ((buffer->size % PAGE_SIZE) ? 1 : 0);
1420
1421 DPD(2, " calculated playback fragment_size -> %d\n", buffer->fragment_size);
1422 DPD(2, " calculated playback numfrags -> %d\n", buffer->numfrags);
1423
1424 return;
1425}
1426
1427static void calculate_ifrag(struct wiinst *wiinst)
1428{
1429 struct wavein_buffer *buffer = &wiinst->buffer;
1430 u32 fragsize, bufsize, size[4];
1431 int i, j;
1432
1433 if (buffer->fragment_size)
1434 return;
1435
1436 if (!buffer->ossfragshift) {
1437 fragsize = (wiinst->format.bytespersec * WAVEIN_DEFAULTFRAGLEN) / 1000 - 1;
1438
1439 while (fragsize) {
1440 fragsize >>= 1;
1441 buffer->ossfragshift++;
1442 }
1443 }
1444
1445 if (buffer->ossfragshift < WAVEIN_MINFRAGSHIFT)
1446 buffer->ossfragshift = WAVEIN_MINFRAGSHIFT;
1447
1448 buffer->fragment_size = 1 << buffer->ossfragshift;
1449
1450 while (buffer->fragment_size * WAVEIN_MINFRAGS > WAVEIN_MAXBUFSIZE)
1451 buffer->fragment_size >>= 1;
1452
1453 /* now we are sure that:
1454 (2^WAVEIN_MINFRAGSHIFT) <= (fragment_size = 2^n) <= (WAVEIN_MAXBUFSIZE / WAVEIN_MINFRAGS)
1455 */
1456
1457
1458 if (!buffer->numfrags)
1459 buffer->numfrags = (wiinst->format.bytespersec * WAVEIN_DEFAULTBUFLEN) / (buffer->fragment_size * 1000) - 1;
1460
1461 if (buffer->numfrags < WAVEIN_MINFRAGS)
1462 buffer->numfrags = WAVEIN_MINFRAGS;
1463
1464 if (buffer->numfrags * buffer->fragment_size > WAVEIN_MAXBUFSIZE)
1465 buffer->numfrags = WAVEIN_MAXBUFSIZE / buffer->fragment_size;
1466
1467 if (buffer->numfrags < WAVEIN_MINFRAGS)
1468 BUG();
1469
1470 bufsize = buffer->fragment_size * buffer->numfrags;
1471
1472 /* the buffer size for recording is restricted to certain values, adjust it now */
1473 if (bufsize >= 0x10000) {
1474 buffer->size = 0x10000;
1475 buffer->sizeregval = 0x1f;
1476 } else {
1477 buffer->size = 0;
1478 size[0] = 384;
1479 size[1] = 448;
1480 size[2] = 512;
1481 size[3] = 640;
1482
1483 for (i = 0; i < 8; i++)
1484 for (j = 0; j < 4; j++)
1485 if (bufsize >= size[j]) {
1486 buffer->size = size[j];
1487 size[j] *= 2;
1488 buffer->sizeregval = i * 4 + j + 1;
1489 } else
1490 goto exitloop;
1491 exitloop:
1492 if (buffer->size == 0) {
1493 buffer->size = 384;
1494 buffer->sizeregval = 0x01;
1495 }
1496 }
1497
1498 /* adjust the fragment size so that buffer size is an integer multiple */
1499 while (buffer->size % buffer->fragment_size)
1500 buffer->fragment_size >>= 1;
1501
1502 buffer->numfrags = buffer->size / buffer->fragment_size;
1503 buffer->pages = buffer->size / PAGE_SIZE + ((buffer->size % PAGE_SIZE) ? 1 : 0);
1504
1505 DPD(2, " calculated recording fragment_size -> %d\n", buffer->fragment_size);
1506 DPD(2, " calculated recording numfrags -> %d\n", buffer->numfrags);
1507 DPD(2, " buffer size register -> %#04x\n", buffer->sizeregval);
1508
1509 return;
1510}
1511
1512static void emu10k1_wavein_bh(unsigned long refdata)
1513{
1514 struct emu10k1_wavedevice *wave_dev = (struct emu10k1_wavedevice *) refdata;
1515 struct wiinst *wiinst = wave_dev->wiinst;
1516 u32 bytestocopy;
1517 unsigned long flags;
1518
1519 if (!wiinst)
1520 return;
1521
1522 spin_lock_irqsave(&wiinst->lock, flags);
1523
1524 if (!(wiinst->state & WAVE_STATE_STARTED)) {
1525 spin_unlock_irqrestore(&wiinst->lock, flags);
1526 return;
1527 }
1528
1529 emu10k1_wavein_update(wave_dev->card, wiinst);
1530 emu10k1_wavein_getxfersize(wiinst, &bytestocopy);
1531
1532 spin_unlock_irqrestore(&wiinst->lock, flags);
1533
1534 if (bytestocopy >= wiinst->buffer.fragment_size) {
1535 if (waitqueue_active(&wiinst->wait_queue))
1536 wake_up_interruptible(&wiinst->wait_queue);
1537 } else
1538 DPD(3, "Not enough transfer size, %d\n", bytestocopy);
1539
1540 return;
1541}
1542
1543static void emu10k1_waveout_bh(unsigned long refdata)
1544{
1545 struct emu10k1_wavedevice *wave_dev = (struct emu10k1_wavedevice *) refdata;
1546 struct woinst *woinst = wave_dev->woinst;
1547 u32 bytestocopy;
1548 unsigned long flags;
1549
1550 if (!woinst)
1551 return;
1552
1553 spin_lock_irqsave(&woinst->lock, flags);
1554
1555 if (!(woinst->state & WAVE_STATE_STARTED)) {
1556 spin_unlock_irqrestore(&woinst->lock, flags);
1557 return;
1558 }
1559
1560 emu10k1_waveout_update(woinst);
1561 emu10k1_waveout_getxfersize(woinst, &bytestocopy);
1562
1563 if (woinst->buffer.fill_silence) {
1564 spin_unlock_irqrestore(&woinst->lock, flags);
1565 emu10k1_waveout_fillsilence(woinst);
1566 } else
1567 spin_unlock_irqrestore(&woinst->lock, flags);
1568
1569 if (bytestocopy >= woinst->buffer.fragment_size) {
1570 if (waitqueue_active(&woinst->wait_queue))
1571 wake_up_interruptible(&woinst->wait_queue);
1572 } else
1573 DPD(3, "Not enough transfer size -> %d\n", bytestocopy);
1574
1575 return;
1576}
1577
1578struct file_operations emu10k1_audio_fops = {
1579 .owner = THIS_MODULE,
1580 .llseek = no_llseek,
1581 .read = emu10k1_audio_read,
1582 .write = emu10k1_audio_write,
1583 .poll = emu10k1_audio_poll,
1584 .ioctl = emu10k1_audio_ioctl,
1585 .mmap = emu10k1_audio_mmap,
1586 .open = emu10k1_audio_open,
1587 .release = emu10k1_audio_release,
1588};
diff --git a/sound/oss/emu10k1/audio.h b/sound/oss/emu10k1/audio.h
new file mode 100644
index 000000000000..26ee81bbd6c6
--- /dev/null
+++ b/sound/oss/emu10k1/audio.h
@@ -0,0 +1,44 @@
1/*
2 **********************************************************************
3 * audio.c -- /dev/dsp interface for emu10k1 driver
4 * Copyright 1999, 2000 Creative Labs, Inc.
5 *
6 **********************************************************************
7 *
8 * Date Author Summary of changes
9 * ---- ------ ------------------
10 * October 20, 1999 Bertrand Lee base code release
11 * November 2, 1999 Alan Cox cleaned up types/leaks
12 *
13 **********************************************************************
14 *
15 * This program is free software; you can redistribute it and/or
16 * modify it under the terms of the GNU General Public License as
17 * published by the Free Software Foundation; either version 2 of
18 * the License, or (at your option) any later version.
19 *
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public
26 * License along with this program; if not, write to the Free
27 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139,
28 * USA.
29 *
30 **********************************************************************
31 */
32
33#ifndef _AUDIO_H
34#define _AUDIO_H
35
36struct emu10k1_wavedevice
37{
38 struct emu10k1_card *card;
39 struct wiinst *wiinst;
40 struct woinst *woinst;
41 u16 enablebits;
42};
43
44#endif /* _AUDIO_H */
diff --git a/sound/oss/emu10k1/cardmi.c b/sound/oss/emu10k1/cardmi.c
new file mode 100644
index 000000000000..0545814cc67d
--- /dev/null
+++ b/sound/oss/emu10k1/cardmi.c
@@ -0,0 +1,832 @@
1/*
2 **********************************************************************
3 * sblive_mi.c - MIDI UART input HAL for emu10k1 driver
4 * Copyright 1999, 2000 Creative Labs, Inc.
5 *
6 **********************************************************************
7 *
8 * Date Author Summary of changes
9 * ---- ------ ------------------
10 * October 20, 1999 Bertrand Lee base code release
11 * November 2, 1999 Alan Cox clean up
12 *
13 **********************************************************************
14 *
15 * This program is free software; you can redistribute it and/or
16 * modify it under the terms of the GNU General Public License as
17 * published by the Free Software Foundation; either version 2 of
18 * the License, or (at your option) any later version.
19 *
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public
26 * License along with this program; if not, write to the Free
27 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139,
28 * USA.
29 *
30 **********************************************************************
31 */
32
33#include <linux/slab.h>
34#include <linux/jiffies.h>
35
36#include "hwaccess.h"
37#include "8010.h"
38#include "cardmi.h"
39#include "irqmgr.h"
40
41
42static int emu10k1_mpuin_callback(struct emu10k1_mpuin *card_mpuin, u32 msg, unsigned long data, u32 bytesvalid);
43
44static int sblive_miStateInit(struct emu10k1_mpuin *);
45static int sblive_miStateEntry(struct emu10k1_mpuin *, u8);
46static int sblive_miStateParse(struct emu10k1_mpuin *, u8);
47static int sblive_miState3Byte(struct emu10k1_mpuin *, u8);
48static int sblive_miState3ByteKey(struct emu10k1_mpuin *, u8);
49static int sblive_miState3ByteVel(struct emu10k1_mpuin *, u8);
50static int sblive_miState2Byte(struct emu10k1_mpuin *, u8);
51static int sblive_miState2ByteKey(struct emu10k1_mpuin *, u8);
52static int sblive_miStateSysCommon2(struct emu10k1_mpuin *, u8);
53static int sblive_miStateSysCommon2Key(struct emu10k1_mpuin *, u8);
54static int sblive_miStateSysCommon3(struct emu10k1_mpuin *, u8);
55static int sblive_miStateSysCommon3Key(struct emu10k1_mpuin *, u8);
56static int sblive_miStateSysCommon3Vel(struct emu10k1_mpuin *, u8);
57static int sblive_miStateSysExNorm(struct emu10k1_mpuin *, u8);
58static int sblive_miStateSysReal(struct emu10k1_mpuin *, u8);
59
60
61static struct {
62 int (*Fn) (struct emu10k1_mpuin *, u8);
63} midistatefn[] = {
64
65 {
66 sblive_miStateParse}, {
67 sblive_miState3Byte}, /* 0x8n, 0x9n, 0xAn, 0xBn, 0xEn */
68 {
69 sblive_miState3ByteKey}, /* Byte 1 */
70 {
71 sblive_miState3ByteVel}, /* Byte 2 */
72 {
73 sblive_miState2Byte}, /* 0xCn, 0xDn */
74 {
75 sblive_miState2ByteKey}, /* Byte 1 */
76 {
77 sblive_miStateSysCommon2}, /* 0xF1 , 0xF3 */
78 {
79 sblive_miStateSysCommon2Key}, /* 0xF1 , 0xF3, Byte 1 */
80 {
81 sblive_miStateSysCommon3}, /* 0xF2 */
82 {
83 sblive_miStateSysCommon3Key}, /* 0xF2 , Byte 1 */
84 {
85 sblive_miStateSysCommon3Vel}, /* 0xF2 , Byte 2 */
86 {
87 sblive_miStateSysExNorm}, /* 0xF0, 0xF7, Normal mode */
88 {
89 sblive_miStateSysReal} /* 0xF4 - 0xF6 ,0xF8 - 0xFF */
90};
91
92
93/* Installs the IRQ handler for the MPU in port */
94
95/* and initialize parameters */
96
97int emu10k1_mpuin_open(struct emu10k1_card *card, struct midi_openinfo *openinfo)
98{
99 struct emu10k1_mpuin *card_mpuin = card->mpuin;
100
101 DPF(2, "emu10k1_mpuin_open\n");
102
103 if (!(card_mpuin->status & FLAGS_AVAILABLE))
104 return -1;
105
106 /* Copy open info and mark channel as in use */
107 card_mpuin->openinfo = *openinfo;
108 card_mpuin->status &= ~FLAGS_AVAILABLE; /* clear */
109 card_mpuin->status |= FLAGS_READY; /* set */
110 card_mpuin->status &= ~FLAGS_MIDM_STARTED; /* clear */
111 card_mpuin->firstmidiq = NULL;
112 card_mpuin->lastmidiq = NULL;
113 card_mpuin->qhead = 0;
114 card_mpuin->qtail = 0;
115
116 sblive_miStateInit(card_mpuin);
117
118 emu10k1_mpu_reset(card);
119 emu10k1_mpu_acquire(card);
120
121 return 0;
122}
123
124int emu10k1_mpuin_close(struct emu10k1_card *card)
125{
126 struct emu10k1_mpuin *card_mpuin = card->mpuin;
127
128 DPF(2, "emu10k1_mpuin_close()\n");
129
130 /* Check if there are pending input SysEx buffers */
131 if (card_mpuin->firstmidiq != NULL) {
132 ERROR();
133 return -1;
134 }
135
136 /* Disable RX interrupt */
137 emu10k1_irq_disable(card, card->is_audigy ? A_INTE_MIDIRXENABLE : INTE_MIDIRXENABLE);
138
139 emu10k1_mpu_release(card);
140
141 card_mpuin->status |= FLAGS_AVAILABLE; /* set */
142 card_mpuin->status &= ~FLAGS_MIDM_STARTED; /* clear */
143
144 return 0;
145}
146
147/* Adds MIDI buffer to local queue list */
148
149int emu10k1_mpuin_add_buffer(struct emu10k1_mpuin *card_mpuin, struct midi_hdr *midihdr)
150{
151 struct midi_queue *midiq;
152 unsigned long flags;
153
154 DPF(2, "emu10k1_mpuin_add_buffer()\n");
155
156 /* Update MIDI buffer flags */
157 midihdr->flags |= MIDIBUF_INQUEUE; /* set */
158 midihdr->flags &= ~MIDIBUF_DONE; /* clear */
159
160 if ((midiq = (struct midi_queue *) kmalloc(sizeof(struct midi_queue), GFP_ATOMIC)) == NULL) {
161 /* Message lost */
162 return -1;
163 }
164
165 midiq->next = NULL;
166 midiq->qtype = 1;
167 midiq->length = midihdr->bufferlength;
168 midiq->sizeLeft = midihdr->bufferlength;
169 midiq->midibyte = midihdr->data;
170 midiq->refdata = (unsigned long) midihdr;
171
172 spin_lock_irqsave(&card_mpuin->lock, flags);
173
174 if (card_mpuin->firstmidiq == NULL) {
175 card_mpuin->firstmidiq = midiq;
176 card_mpuin->lastmidiq = midiq;
177 } else {
178 (card_mpuin->lastmidiq)->next = midiq;
179 card_mpuin->lastmidiq = midiq;
180 }
181
182 spin_unlock_irqrestore(&card_mpuin->lock, flags);
183
184 return 0;
185}
186
187/* First set the Time Stamp if MIDI IN has not started. */
188
189/* Then enable RX Irq. */
190
191int emu10k1_mpuin_start(struct emu10k1_card *card)
192{
193 struct emu10k1_mpuin *card_mpuin = card->mpuin;
194 u8 dummy;
195
196 DPF(2, "emu10k1_mpuin_start()\n");
197
198 /* Set timestamp if not set */
199 if (card_mpuin->status & FLAGS_MIDM_STARTED) {
200 DPF(2, "Time Stamp not changed\n");
201 } else {
202 while (!emu10k1_mpu_read_data(card, &dummy));
203
204 card_mpuin->status |= FLAGS_MIDM_STARTED; /* set */
205
206 /* Set new time stamp */
207 card_mpuin->timestart = (jiffies * 1000) / HZ;
208 DPD(2, "New Time Stamp = %d\n", card_mpuin->timestart);
209
210 card_mpuin->qhead = 0;
211 card_mpuin->qtail = 0;
212
213 emu10k1_irq_enable(card, card->is_audigy ? A_INTE_MIDIRXENABLE : INTE_MIDIRXENABLE);
214 }
215
216 return 0;
217}
218
219/* Disable the RX Irq. If a partial recorded buffer */
220
221/* exist, send it up to IMIDI level. */
222
223int emu10k1_mpuin_stop(struct emu10k1_card *card)
224{
225 struct emu10k1_mpuin *card_mpuin = card->mpuin;
226 struct midi_queue *midiq;
227 unsigned long flags;
228
229 DPF(2, "emu10k1_mpuin_stop()\n");
230
231 emu10k1_irq_disable(card, card->is_audigy ? A_INTE_MIDIRXENABLE : INTE_MIDIRXENABLE);
232
233 card_mpuin->status &= ~FLAGS_MIDM_STARTED; /* clear */
234
235 if (card_mpuin->firstmidiq) {
236 spin_lock_irqsave(&card_mpuin->lock, flags);
237
238 midiq = card_mpuin->firstmidiq;
239 if (midiq != NULL) {
240 if (midiq->sizeLeft == midiq->length)
241 midiq = NULL;
242 else {
243 card_mpuin->firstmidiq = midiq->next;
244 if (card_mpuin->firstmidiq == NULL)
245 card_mpuin->lastmidiq = NULL;
246 }
247 }
248
249 spin_unlock_irqrestore(&card_mpuin->lock, flags);
250
251 if (midiq) {
252 emu10k1_mpuin_callback(card_mpuin, ICARDMIDI_INLONGERROR, (unsigned long) midiq, 0);
253 kfree(midiq);
254 }
255 }
256
257 return 0;
258}
259
260/* Disable the RX Irq. If any buffer */
261
262/* exist, send it up to IMIDI level. */
263int emu10k1_mpuin_reset(struct emu10k1_card *card)
264{
265 struct emu10k1_mpuin *card_mpuin = card->mpuin;
266 struct midi_queue *midiq;
267
268 DPF(2, "emu10k1_mpuin_reset()\n");
269
270 emu10k1_irq_disable(card, card->is_audigy ? A_INTE_MIDIRXENABLE : INTE_MIDIRXENABLE);
271
272 while (card_mpuin->firstmidiq) {
273 midiq = card_mpuin->firstmidiq;
274 card_mpuin->firstmidiq = midiq->next;
275
276 if (midiq->sizeLeft == midiq->length)
277 emu10k1_mpuin_callback(card_mpuin, ICARDMIDI_INLONGDATA, (unsigned long) midiq, 0);
278 else
279 emu10k1_mpuin_callback(card_mpuin, ICARDMIDI_INLONGERROR, (unsigned long) midiq, 0);
280
281 kfree(midiq);
282 }
283
284 card_mpuin->lastmidiq = NULL;
285 card_mpuin->status &= ~FLAGS_MIDM_STARTED;
286
287 return 0;
288}
289
290/* Passes the message with the data back to the client */
291
292/* via IRQ & DPC callbacks to Ring 3 */
293static int emu10k1_mpuin_callback(struct emu10k1_mpuin *card_mpuin, u32 msg, unsigned long data, u32 bytesvalid)
294{
295 unsigned long timein;
296 struct midi_queue *midiq;
297 unsigned long callback_msg[3];
298 struct midi_hdr *midihdr;
299
300 /* Called during ISR. The data & code touched are:
301 * 1. card_mpuin
302 * 2. The function to be called
303 */
304
305 timein = card_mpuin->timein;
306 if (card_mpuin->timestart <= timein)
307 callback_msg[0] = timein - card_mpuin->timestart;
308 else
309 callback_msg[0] = (~0x0L - card_mpuin->timestart) + timein;
310
311 if (msg == ICARDMIDI_INDATA || msg == ICARDMIDI_INDATAERROR) {
312 callback_msg[1] = data;
313 callback_msg[2] = bytesvalid;
314 DPD(2, "emu10k1_mpuin_callback: midimsg = %#lx\n", data);
315 } else {
316 midiq = (struct midi_queue *) data;
317 midihdr = (struct midi_hdr *) midiq->refdata;
318
319 callback_msg[1] = midiq->length - midiq->sizeLeft;
320 callback_msg[2] = midiq->refdata;
321 midihdr->flags &= ~MIDIBUF_INQUEUE;
322 midihdr->flags |= MIDIBUF_DONE;
323
324 midihdr->bytesrecorded = midiq->length - midiq->sizeLeft;
325 }
326
327 /* Notify client that Sysex buffer has been sent */
328 emu10k1_midi_callback(msg, card_mpuin->openinfo.refdata, callback_msg);
329
330 return 0;
331}
332
333void emu10k1_mpuin_bh(unsigned long refdata)
334{
335 u8 data;
336 unsigned idx;
337 struct emu10k1_mpuin *card_mpuin = (struct emu10k1_mpuin *) refdata;
338 unsigned long flags;
339
340 while (card_mpuin->qhead != card_mpuin->qtail) {
341 spin_lock_irqsave(&card_mpuin->lock, flags);
342 idx = card_mpuin->qhead;
343 data = card_mpuin->midiq[idx].data;
344 card_mpuin->timein = card_mpuin->midiq[idx].timein;
345 idx = (idx + 1) % MIDIIN_MAX_BUFFER_SIZE;
346 card_mpuin->qhead = idx;
347 spin_unlock_irqrestore(&card_mpuin->lock, flags);
348
349 sblive_miStateEntry(card_mpuin, data);
350 }
351
352 return;
353}
354
355/* IRQ callback handler routine for the MPU in port */
356
357int emu10k1_mpuin_irqhandler(struct emu10k1_card *card)
358{
359 unsigned idx;
360 unsigned count;
361 u8 MPUIvalue;
362 struct emu10k1_mpuin *card_mpuin = card->mpuin;
363
364 /* IRQ service routine. The data and code touched are:
365 * 1. card_mpuin
366 */
367
368 count = 0;
369 idx = card_mpuin->qtail;
370
371 while (1) {
372 if (emu10k1_mpu_read_data(card, &MPUIvalue) < 0) {
373 break;
374 } else {
375 ++count;
376 card_mpuin->midiq[idx].data = MPUIvalue;
377 card_mpuin->midiq[idx].timein = (jiffies * 1000) / HZ;
378 idx = (idx + 1) % MIDIIN_MAX_BUFFER_SIZE;
379 }
380 }
381
382 if (count) {
383 card_mpuin->qtail = idx;
384
385 tasklet_hi_schedule(&card_mpuin->tasklet);
386 }
387
388 return 0;
389}
390
391/*****************************************************************************/
392
393/* Supporting functions for Midi-In Interpretation State Machine */
394
395/*****************************************************************************/
396
397/* FIXME: This should be a macro */
398static int sblive_miStateInit(struct emu10k1_mpuin *card_mpuin)
399{
400 card_mpuin->status = 0; /* For MIDI running status */
401 card_mpuin->fstatus = 0; /* For 0xFn status only */
402 card_mpuin->curstate = STIN_PARSE;
403 card_mpuin->laststate = STIN_PARSE;
404 card_mpuin->data = 0;
405 card_mpuin->timestart = 0;
406 card_mpuin->timein = 0;
407
408 return 0;
409}
410
411/* FIXME: This should be a macro */
412static int sblive_miStateEntry(struct emu10k1_mpuin *card_mpuin, u8 data)
413{
414 return midistatefn[card_mpuin->curstate].Fn(card_mpuin, data);
415}
416
417static int sblive_miStateParse(struct emu10k1_mpuin *card_mpuin, u8 data)
418{
419 switch (data & 0xf0) {
420 case 0x80:
421 case 0x90:
422 case 0xA0:
423 case 0xB0:
424 case 0xE0:
425 card_mpuin->curstate = STIN_3BYTE;
426 break;
427
428 case 0xC0:
429 case 0xD0:
430 card_mpuin->curstate = STIN_2BYTE;
431 break;
432
433 case 0xF0:
434 /* System messages do not affect the previous running status! */
435 switch (data & 0x0f) {
436 case 0x0:
437 card_mpuin->laststate = card_mpuin->curstate;
438 card_mpuin->curstate = STIN_SYS_EX_NORM;
439
440 if (card_mpuin->firstmidiq) {
441 struct midi_queue *midiq;
442
443 midiq = card_mpuin->firstmidiq;
444 *midiq->midibyte = data;
445 --midiq->sizeLeft;
446 ++midiq->midibyte;
447 }
448
449 return CTSTATUS_NEXT_BYTE;
450
451 case 0x7:
452 emu10k1_mpuin_callback(card_mpuin, ICARDMIDI_INDATAERROR, 0xf7, 0);
453 return -1;
454
455 case 0x2:
456 card_mpuin->laststate = card_mpuin->curstate;
457 card_mpuin->curstate = STIN_SYS_COMMON_3;
458 break;
459
460 case 0x1:
461 case 0x3:
462 card_mpuin->laststate = card_mpuin->curstate;
463 card_mpuin->curstate = STIN_SYS_COMMON_2;
464 break;
465
466 default:
467 /* includes 0xF4 - 0xF6, 0xF8 - 0xFF */
468 return midistatefn[STIN_SYS_REAL].Fn(card_mpuin, data);
469 }
470
471 break;
472
473 default:
474 DPF(2, "BUG: default case hit\n");
475 return -1;
476 }
477
478 return midistatefn[card_mpuin->curstate].Fn(card_mpuin, data);
479}
480
481static int sblive_miState3Byte(struct emu10k1_mpuin *card_mpuin, u8 data)
482{
483 u8 temp = data & 0xf0;
484
485 if (temp < 0x80) {
486 return midistatefn[STIN_3BYTE_KEY].Fn(card_mpuin, data);
487 } else if (temp <= 0xe0 && temp != 0xc0 && temp != 0xd0) {
488 card_mpuin->status = data;
489 card_mpuin->curstate = STIN_3BYTE_KEY;
490
491 return CTSTATUS_NEXT_BYTE;
492 }
493
494 return midistatefn[STIN_PARSE].Fn(card_mpuin, data);
495}
496
497static int sblive_miState3ByteKey(struct emu10k1_mpuin *card_mpuin, u8 data)
498/* byte 1 */
499{
500 unsigned long tmp;
501
502 if (data > 0x7f) {
503 /* Real-time messages check */
504 if (data > 0xf7)
505 return midistatefn[STIN_SYS_REAL].Fn(card_mpuin, data);
506
507 /* Invalid data! */
508 DPF(2, "Invalid data!\n");
509
510 card_mpuin->curstate = STIN_PARSE;
511 tmp = ((unsigned long) data) << 8;
512 tmp |= (unsigned long) card_mpuin->status;
513
514 emu10k1_mpuin_callback(card_mpuin, ICARDMIDI_INDATAERROR, tmp, 0);
515
516 return -1;
517 }
518
519 card_mpuin->data = data;
520 card_mpuin->curstate = STIN_3BYTE_VEL;
521
522 return CTSTATUS_NEXT_BYTE;
523}
524
525static int sblive_miState3ByteVel(struct emu10k1_mpuin *card_mpuin, u8 data)
526/* byte 2 */
527{
528 unsigned long tmp;
529
530 if (data > 0x7f) {
531 /* Real-time messages check */
532 if (data > 0xf7)
533 return midistatefn[STIN_SYS_REAL].Fn(card_mpuin, data);
534
535 /* Invalid data! */
536 DPF(2, "Invalid data!\n");
537
538 card_mpuin->curstate = STIN_PARSE;
539 tmp = ((unsigned long) data) << 8;
540 tmp |= card_mpuin->data;
541 tmp = tmp << 8;
542 tmp |= (unsigned long) card_mpuin->status;
543
544 emu10k1_mpuin_callback(card_mpuin, ICARDMIDI_INDATAERROR, tmp, 0);
545
546 return -1;
547 }
548
549 card_mpuin->curstate = STIN_3BYTE;
550 tmp = (unsigned long) data;
551 tmp = tmp << 8;
552 tmp |= (unsigned long) card_mpuin->data;
553 tmp = tmp << 8;
554 tmp |= (unsigned long) card_mpuin->status;
555
556 emu10k1_mpuin_callback(card_mpuin, ICARDMIDI_INDATA, tmp, 3);
557
558 return 0;
559}
560
561static int sblive_miState2Byte(struct emu10k1_mpuin *card_mpuin, u8 data)
562{
563 u8 temp = data & 0xf0;
564
565 if ((temp == 0xc0) || (temp == 0xd0)) {
566 card_mpuin->status = data;
567 card_mpuin->curstate = STIN_2BYTE_KEY;
568
569 return CTSTATUS_NEXT_BYTE;
570 }
571
572 if (temp < 0x80)
573 return midistatefn[STIN_2BYTE_KEY].Fn(card_mpuin, data);
574
575 return midistatefn[STIN_PARSE].Fn(card_mpuin, data);
576}
577
578static int sblive_miState2ByteKey(struct emu10k1_mpuin *card_mpuin, u8 data)
579/* byte 1 */
580{
581 unsigned long tmp;
582
583 if (data > 0x7f) {
584 /* Real-time messages check */
585 if (data > 0xf7)
586 return midistatefn[STIN_SYS_REAL].Fn(card_mpuin, data);
587
588 /* Invalid data! */
589 DPF(2, "Invalid data!\n");
590
591 card_mpuin->curstate = STIN_PARSE;
592 tmp = (unsigned long) data;
593 tmp = tmp << 8;
594 tmp |= (unsigned long) card_mpuin->status;
595
596 emu10k1_mpuin_callback(card_mpuin, ICARDMIDI_INDATAERROR, tmp, 0);
597
598 return -1;
599 }
600
601 card_mpuin->curstate = STIN_2BYTE;
602 tmp = (unsigned long) data;
603 tmp = tmp << 8;
604 tmp |= (unsigned long) card_mpuin->status;
605
606 emu10k1_mpuin_callback(card_mpuin, ICARDMIDI_INDATA, tmp, 2);
607
608 return 0;
609}
610
611static int sblive_miStateSysCommon2(struct emu10k1_mpuin *card_mpuin, u8 data)
612{
613 card_mpuin->fstatus = data;
614 card_mpuin->curstate = STIN_SYS_COMMON_2_KEY;
615
616 return CTSTATUS_NEXT_BYTE;
617}
618
619static int sblive_miStateSysCommon2Key(struct emu10k1_mpuin *card_mpuin, u8 data)
620/* byte 1 */
621{
622 unsigned long tmp;
623
624 if (data > 0x7f) {
625 /* Real-time messages check */
626 if (data > 0xf7)
627 return midistatefn[STIN_SYS_REAL].Fn(card_mpuin, data);
628
629 /* Invalid data! */
630 DPF(2, "Invalid data!\n");
631
632 card_mpuin->curstate = card_mpuin->laststate;
633 tmp = (unsigned long) data;
634 tmp = tmp << 8;
635 tmp |= (unsigned long) card_mpuin->fstatus;
636
637 emu10k1_mpuin_callback(card_mpuin, ICARDMIDI_INDATAERROR, tmp, 0);
638
639 return -1;
640 }
641
642 card_mpuin->curstate = card_mpuin->laststate;
643 tmp = (unsigned long) data;
644 tmp = tmp << 8;
645 tmp |= (unsigned long) card_mpuin->fstatus;
646
647 emu10k1_mpuin_callback(card_mpuin, ICARDMIDI_INDATA, tmp, 2);
648
649 return 0;
650}
651
652static int sblive_miStateSysCommon3(struct emu10k1_mpuin *card_mpuin, u8 data)
653{
654 card_mpuin->fstatus = data;
655 card_mpuin->curstate = STIN_SYS_COMMON_3_KEY;
656
657 return CTSTATUS_NEXT_BYTE;
658}
659
660static int sblive_miStateSysCommon3Key(struct emu10k1_mpuin *card_mpuin, u8 data)
661/* byte 1 */
662{
663 unsigned long tmp;
664
665 if (data > 0x7f) {
666 /* Real-time messages check */
667 if (data > 0xf7)
668 return midistatefn[STIN_SYS_REAL].Fn(card_mpuin, data);
669
670 /* Invalid data! */
671 DPF(2, "Invalid data!\n");
672
673 card_mpuin->curstate = card_mpuin->laststate;
674 tmp = (unsigned long) data;
675 tmp = tmp << 8;
676 tmp |= (unsigned long) card_mpuin->fstatus;
677
678 emu10k1_mpuin_callback(card_mpuin, ICARDMIDI_INDATAERROR, tmp, 0);
679
680 return -1;
681 }
682
683 card_mpuin->data = data;
684 card_mpuin->curstate = STIN_SYS_COMMON_3_VEL;
685
686 return CTSTATUS_NEXT_BYTE;
687}
688
689static int sblive_miStateSysCommon3Vel(struct emu10k1_mpuin *card_mpuin, u8 data)
690/* byte 2 */
691{
692 unsigned long tmp;
693
694 if (data > 0x7f) {
695 /* Real-time messages check */
696 if (data > 0xf7)
697 return midistatefn[STIN_SYS_REAL].Fn(card_mpuin, data);
698
699 /* Invalid data! */
700 DPF(2, "Invalid data!\n");
701
702 card_mpuin->curstate = card_mpuin->laststate;
703 tmp = (unsigned long) data;
704 tmp = tmp << 8;
705 tmp |= (unsigned long) card_mpuin->data;
706 tmp = tmp << 8;
707 tmp |= (unsigned long) card_mpuin->fstatus;
708
709 emu10k1_mpuin_callback(card_mpuin, ICARDMIDI_INDATAERROR, tmp, 0);
710
711 return -1;
712 }
713
714 card_mpuin->curstate = card_mpuin->laststate;
715 tmp = (unsigned long) data;
716 tmp = tmp << 8;
717 tmp |= (unsigned long) card_mpuin->data;
718 tmp = tmp << 8;
719 tmp |= (unsigned long) card_mpuin->fstatus;
720
721 emu10k1_mpuin_callback(card_mpuin, ICARDMIDI_INDATA, tmp, 3);
722
723 return 0;
724}
725
726static int sblive_miStateSysExNorm(struct emu10k1_mpuin *card_mpuin, u8 data)
727{
728 unsigned long flags;
729
730 if ((data > 0x7f) && (data != 0xf7)) {
731 /* Real-time messages check */
732 if (data > 0xf7)
733 return midistatefn[STIN_SYS_REAL].Fn(card_mpuin, data);
734
735 /* Invalid Data! */
736 DPF(2, "Invalid data!\n");
737
738 card_mpuin->curstate = card_mpuin->laststate;
739
740 if (card_mpuin->firstmidiq) {
741 struct midi_queue *midiq;
742
743 midiq = card_mpuin->firstmidiq;
744 *midiq->midibyte = data;
745 --midiq->sizeLeft;
746 ++midiq->midibyte;
747
748 spin_lock_irqsave(&card_mpuin->lock, flags);
749
750 card_mpuin->firstmidiq = midiq->next;
751 if (card_mpuin->firstmidiq == NULL)
752 card_mpuin->lastmidiq = NULL;
753
754 spin_unlock_irqrestore(&card_mpuin->lock, flags);
755
756 emu10k1_mpuin_callback(card_mpuin, ICARDMIDI_INLONGERROR, (unsigned long) midiq, 0);
757
758 kfree(midiq);
759 }
760
761 return -1;
762 }
763
764 if (card_mpuin->firstmidiq) {
765 struct midi_queue *midiq;
766
767 midiq = card_mpuin->firstmidiq;
768 *midiq->midibyte = data;
769 --midiq->sizeLeft;
770 ++midiq->midibyte;
771 }
772
773 if (data == 0xf7) {
774 /* End of Sysex buffer */
775 /* Send down the buffer */
776
777 card_mpuin->curstate = card_mpuin->laststate;
778
779 if (card_mpuin->firstmidiq) {
780 struct midi_queue *midiq;
781
782 midiq = card_mpuin->firstmidiq;
783
784 spin_lock_irqsave(&card_mpuin->lock, flags);
785
786 card_mpuin->firstmidiq = midiq->next;
787 if (card_mpuin->firstmidiq == NULL)
788 card_mpuin->lastmidiq = NULL;
789
790 spin_unlock_irqrestore(&card_mpuin->lock, flags);
791
792 emu10k1_mpuin_callback(card_mpuin, ICARDMIDI_INLONGDATA, (unsigned long) midiq, 0);
793
794 kfree(midiq);
795 }
796
797 return 0;
798 }
799
800 if (card_mpuin->firstmidiq) {
801 struct midi_queue *midiq;
802
803 midiq = card_mpuin->firstmidiq;
804
805 if (midiq->sizeLeft == 0) {
806 /* Special case */
807
808 spin_lock_irqsave(&card_mpuin->lock, flags);
809
810 card_mpuin->firstmidiq = midiq->next;
811 if (card_mpuin->firstmidiq == NULL)
812 card_mpuin->lastmidiq = NULL;
813
814 spin_unlock_irqrestore(&card_mpuin->lock, flags);
815
816 emu10k1_mpuin_callback(card_mpuin, ICARDMIDI_INLONGDATA, (unsigned long) midiq, 0);
817
818 kfree(midiq);
819
820 return CTSTATUS_NEXT_BYTE;
821 }
822 }
823
824 return CTSTATUS_NEXT_BYTE;
825}
826
827static int sblive_miStateSysReal(struct emu10k1_mpuin *card_mpuin, u8 data)
828{
829 emu10k1_mpuin_callback(card_mpuin, ICARDMIDI_INDATA, data, 1);
830
831 return CTSTATUS_NEXT_BYTE;
832}
diff --git a/sound/oss/emu10k1/cardmi.h b/sound/oss/emu10k1/cardmi.h
new file mode 100644
index 000000000000..d12c24116307
--- /dev/null
+++ b/sound/oss/emu10k1/cardmi.h
@@ -0,0 +1,97 @@
1/*
2 **********************************************************************
3 * sblive_mi.h
4 * Copyright 1999, 2000 Creative Labs, Inc.
5 *
6 **********************************************************************
7 *
8 * Date Author Summary of changes
9 * ---- ------ ------------------
10 * October 20, 1999 Bertrand Lee base code release
11 * November 2, 1999 Alan Cox cleaned up
12 *
13 **********************************************************************
14 *
15 * This program is free software; you can redistribute it and/or
16 * modify it under the terms of the GNU General Public License as
17 * published by the Free Software Foundation; either version 2 of
18 * the License, or (at your option) any later version.
19 *
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public
26 * License along with this program; if not, write to the Free
27 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139,
28 * USA.
29 *
30 **********************************************************************
31 */
32
33#ifndef _CARDMI_H
34#define _CARDMI_H
35
36#include "icardmid.h"
37#include <linux/interrupt.h>
38
39typedef enum
40{
41 STIN_PARSE = 0,
42 STIN_3BYTE, /* 0x80, 0x90, 0xA0, 0xB0, 0xE0 */
43 STIN_3BYTE_KEY, /* Byte 1 */
44 STIN_3BYTE_VEL, /* Byte 1 */
45 STIN_2BYTE, /* 0xC0, 0xD0 */
46 STIN_2BYTE_KEY, /* Byte 1 */
47 STIN_SYS_COMMON_2, /* 0xF1, 0xF3 */
48 STIN_SYS_COMMON_2_KEY,
49 STIN_SYS_COMMON_3, /* 0xF2 */
50 STIN_SYS_COMMON_3_KEY,
51 STIN_SYS_COMMON_3_VEL,
52 STIN_SYS_EX_NORM, /* 0xF0, Normal mode */
53 STIN_SYS_REAL
54} midi_in_state;
55
56
57/* flags for card MIDI in object */
58#define FLAGS_MIDM_STARTED 0x00001000 // Data has started to come in after Midm Start
59#define MIDIIN_MAX_BUFFER_SIZE 200 // Definition for struct emu10k1_mpuin
60
61struct midi_data
62{
63 u8 data;
64 u32 timein;
65};
66
67struct emu10k1_mpuin
68{
69 spinlock_t lock;
70 struct midi_queue *firstmidiq;
71 struct midi_queue *lastmidiq;
72 unsigned qhead, qtail;
73 struct midi_data midiq[MIDIIN_MAX_BUFFER_SIZE];
74 struct tasklet_struct tasklet;
75 struct midi_openinfo openinfo;
76
77 /* For MIDI state machine */
78 u8 status; /* For MIDI running status */
79 u8 fstatus; /* For 0xFn status only */
80 midi_in_state curstate;
81 midi_in_state laststate;
82 u32 timestart;
83 u32 timein;
84 u8 data;
85};
86
87int emu10k1_mpuin_open(struct emu10k1_card *, struct midi_openinfo *);
88int emu10k1_mpuin_close(struct emu10k1_card *);
89int emu10k1_mpuin_add_buffer(struct emu10k1_mpuin *, struct midi_hdr *);
90int emu10k1_mpuin_start(struct emu10k1_card *);
91int emu10k1_mpuin_stop(struct emu10k1_card *);
92int emu10k1_mpuin_reset(struct emu10k1_card *);
93
94int emu10k1_mpuin_irqhandler(struct emu10k1_card *);
95void emu10k1_mpuin_bh(unsigned long);
96
97#endif /* _CARDMI_H */
diff --git a/sound/oss/emu10k1/cardmo.c b/sound/oss/emu10k1/cardmo.c
new file mode 100644
index 000000000000..5938d31f9e21
--- /dev/null
+++ b/sound/oss/emu10k1/cardmo.c
@@ -0,0 +1,229 @@
1/*
2 **********************************************************************
3 * cardmo.c - MIDI UART output HAL for emu10k1 driver
4 * Copyright 1999, 2000 Creative Labs, Inc.
5 *
6 **********************************************************************
7 *
8 * Date Author Summary of changes
9 * ---- ------ ------------------
10 * October 20, 1999 Bertrand Lee base code release
11 * November 2, 1999 Alan Cox cleaned up
12 *
13 **********************************************************************
14 *
15 * This program is free software; you can redistribute it and/or
16 * modify it under the terms of the GNU General Public License as
17 * published by the Free Software Foundation; either version 2 of
18 * the License, or (at your option) any later version.
19 *
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public
26 * License along with this program; if not, write to the Free
27 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139,
28 * USA.
29 *
30 **********************************************************************
31 */
32
33#include <linux/slab.h>
34
35#include "hwaccess.h"
36#include "8010.h"
37#include "cardmo.h"
38#include "irqmgr.h"
39
40/* Installs the IRQ handler for the MPU out port *
41 * and initialize parameters */
42
43int emu10k1_mpuout_open(struct emu10k1_card *card, struct midi_openinfo *openinfo)
44{
45 struct emu10k1_mpuout *card_mpuout = card->mpuout;
46
47 DPF(2, "emu10k1_mpuout_open()\n");
48
49 if (!(card_mpuout->status & FLAGS_AVAILABLE))
50 return -1;
51
52 /* Copy open info and mark channel as in use */
53 card_mpuout->intr = 0;
54 card_mpuout->openinfo = *openinfo;
55 card_mpuout->status &= ~FLAGS_AVAILABLE;
56 card_mpuout->laststatus = 0x80;
57 card_mpuout->firstmidiq = NULL;
58 card_mpuout->lastmidiq = NULL;
59
60 emu10k1_mpu_reset(card);
61 emu10k1_mpu_acquire(card);
62
63 return 0;
64}
65
66int emu10k1_mpuout_close(struct emu10k1_card *card)
67{
68 struct emu10k1_mpuout *card_mpuout = card->mpuout;
69 struct midi_queue *midiq;
70 struct midi_hdr *midihdr;
71 unsigned long flags;
72
73 DPF(2, "emu10k1_mpuout_close()\n");
74
75 emu10k1_irq_disable(card, card->is_audigy ? A_INTE_MIDITXENABLE : INTE_MIDITXENABLE);
76
77 spin_lock_irqsave(&card_mpuout->lock, flags);
78
79 while (card_mpuout->firstmidiq != NULL) {
80 midiq = card_mpuout->firstmidiq;
81 midihdr = (struct midi_hdr *) midiq->refdata;
82
83 card_mpuout->firstmidiq = midiq->next;
84
85 kfree(midihdr->data);
86 kfree(midihdr);
87 kfree(midiq);
88 }
89
90 card_mpuout->lastmidiq = NULL;
91
92 emu10k1_mpu_release(card);
93
94 card_mpuout->status |= FLAGS_AVAILABLE;
95
96 spin_unlock_irqrestore(&card_mpuout->lock, flags);
97
98 return 0;
99}
100
101/* If there isn't enough buffer space, reject Midi Buffer. *
102* Otherwise, disable TX, create object to hold Midi *
103* uffer, update buffer flags and other parameters *
104* before enabling TX again. */
105
106int emu10k1_mpuout_add_buffer(struct emu10k1_card *card, struct midi_hdr *midihdr)
107{
108 struct emu10k1_mpuout *card_mpuout = card->mpuout;
109 struct midi_queue *midiq;
110 unsigned long flags;
111
112 DPF(2, "emu10k1_mpuout_add_buffer()\n");
113
114 if (card_mpuout->state == CARDMIDIOUT_STATE_SUSPEND)
115 return 0;
116
117 midihdr->flags |= MIDIBUF_INQUEUE;
118 midihdr->flags &= ~MIDIBUF_DONE;
119
120 if ((midiq = (struct midi_queue *) kmalloc(sizeof(struct midi_queue), GFP_KERNEL)) == NULL) {
121 /* Message lost */
122 return -1;
123 }
124
125 midiq->next = NULL;
126 midiq->qtype = 1;
127 midiq->length = midihdr->bufferlength;
128 midiq->sizeLeft = midihdr->bufferlength;
129 midiq->midibyte = midihdr->data;
130
131 midiq->refdata = (unsigned long) midihdr;
132
133 spin_lock_irqsave(&card_mpuout->lock, flags);
134
135 if (card_mpuout->firstmidiq == NULL) {
136 card_mpuout->firstmidiq = midiq;
137 card_mpuout->lastmidiq = midiq;
138 } else {
139 (card_mpuout->lastmidiq)->next = midiq;
140 card_mpuout->lastmidiq = midiq;
141 }
142
143 card_mpuout->intr = 0;
144
145 emu10k1_irq_enable(card, card->is_audigy ? A_INTE_MIDITXENABLE : INTE_MIDITXENABLE);
146
147 spin_unlock_irqrestore(&card_mpuout->lock, flags);
148
149 return 0;
150}
151
152void emu10k1_mpuout_bh(unsigned long refdata)
153{
154 struct emu10k1_card *card = (struct emu10k1_card *) refdata;
155 struct emu10k1_mpuout *card_mpuout = card->mpuout;
156 int cByteSent = 0;
157 struct midi_queue *midiq;
158 struct midi_queue *doneq = NULL;
159 unsigned long flags;
160
161 spin_lock_irqsave(&card_mpuout->lock, flags);
162
163 while (card_mpuout->firstmidiq != NULL) {
164 midiq = card_mpuout->firstmidiq;
165
166 while (cByteSent < 4 && midiq->sizeLeft) {
167 if (emu10k1_mpu_write_data(card, *midiq->midibyte) < 0) {
168 DPF(2, "emu10k1_mpuoutDpcCallback error!!\n");
169 } else {
170 ++cByteSent;
171 --midiq->sizeLeft;
172 ++midiq->midibyte;
173 }
174 }
175
176 if (midiq->sizeLeft == 0) {
177 if (doneq == NULL)
178 doneq = midiq;
179 card_mpuout->firstmidiq = midiq->next;
180 } else
181 break;
182 }
183
184 if (card_mpuout->firstmidiq == NULL)
185 card_mpuout->lastmidiq = NULL;
186
187 if (doneq != NULL) {
188 while (doneq != card_mpuout->firstmidiq) {
189 unsigned long callback_msg[3];
190
191 midiq = doneq;
192 doneq = midiq->next;
193
194 if (midiq->qtype) {
195 callback_msg[0] = 0;
196 callback_msg[1] = midiq->length;
197 callback_msg[2] = midiq->refdata;
198
199 emu10k1_midi_callback(ICARDMIDI_OUTLONGDATA, card_mpuout->openinfo.refdata, callback_msg);
200 } else if (((u8) midiq->refdata) < 0xF0 && ((u8) midiq->refdata) > 0x7F)
201 card_mpuout->laststatus = (u8) midiq->refdata;
202
203 kfree(midiq);
204 }
205 }
206
207 if ((card_mpuout->firstmidiq != NULL) || cByteSent) {
208 card_mpuout->intr = 0;
209 emu10k1_irq_enable(card, card->is_audigy ? A_INTE_MIDITXENABLE : INTE_MIDITXENABLE);
210 }
211
212 spin_unlock_irqrestore(&card_mpuout->lock, flags);
213
214 return;
215}
216
217int emu10k1_mpuout_irqhandler(struct emu10k1_card *card)
218{
219 struct emu10k1_mpuout *card_mpuout = card->mpuout;
220
221 DPF(4, "emu10k1_mpuout_irqhandler\n");
222
223 card_mpuout->intr = 1;
224 emu10k1_irq_disable(card, card->is_audigy ? A_INTE_MIDITXENABLE : INTE_MIDITXENABLE);
225
226 tasklet_hi_schedule(&card_mpuout->tasklet);
227
228 return 0;
229}
diff --git a/sound/oss/emu10k1/cardmo.h b/sound/oss/emu10k1/cardmo.h
new file mode 100644
index 000000000000..7026eb3a85af
--- /dev/null
+++ b/sound/oss/emu10k1/cardmo.h
@@ -0,0 +1,62 @@
1/*
2 **********************************************************************
3 * cardmo.h
4 * Copyright 1999, 2000 Creative Labs, Inc.
5 *
6 **********************************************************************
7 *
8 * Date Author Summary of changes
9 * ---- ------ ------------------
10 * October 20, 1999 Bertrand Lee base code release
11 * November 2, 1999 Alan Cox cleaned up
12 *
13 **********************************************************************
14 *
15 * This program is free software; you can redistribute it and/or
16 * modify it under the terms of the GNU General Public License as
17 * published by the Free Software Foundation; either version 2 of
18 * the License, or (at your option) any later version.
19 *
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public
26 * License along with this program; if not, write to the Free
27 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139,
28 * USA.
29 *
30 **********************************************************************
31 */
32
33#ifndef _CARDMO_H
34#define _CARDMO_H
35
36#include "icardmid.h"
37#include <linux/interrupt.h>
38
39#define CARDMIDIOUT_STATE_DEFAULT 0x00000000
40#define CARDMIDIOUT_STATE_SUSPEND 0x00000001
41
42struct emu10k1_mpuout
43{
44 u32 status;
45 u32 state;
46 volatile int intr;
47 struct midi_queue *firstmidiq;
48 struct midi_queue *lastmidiq;
49 u8 laststatus;
50 struct tasklet_struct tasklet;
51 spinlock_t lock;
52 struct midi_openinfo openinfo;
53};
54
55int emu10k1_mpuout_open(struct emu10k1_card *, struct midi_openinfo *);
56int emu10k1_mpuout_close(struct emu10k1_card *);
57int emu10k1_mpuout_add_buffer(struct emu10k1_card *, struct midi_hdr *);
58
59int emu10k1_mpuout_irqhandler(struct emu10k1_card *);
60void emu10k1_mpuout_bh(unsigned long);
61
62#endif /* _CARDMO_H */
diff --git a/sound/oss/emu10k1/cardwi.c b/sound/oss/emu10k1/cardwi.c
new file mode 100644
index 000000000000..8bbf44b881b4
--- /dev/null
+++ b/sound/oss/emu10k1/cardwi.c
@@ -0,0 +1,373 @@
1/*
2 **********************************************************************
3 * cardwi.c - PCM input HAL for emu10k1 driver
4 * Copyright 1999, 2000 Creative Labs, Inc.
5 *
6 **********************************************************************
7 *
8 * Date Author Summary of changes
9 * ---- ------ ------------------
10 * October 20, 1999 Bertrand Lee base code release
11 *
12 **********************************************************************
13 *
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License as
16 * published by the Free Software Foundation; either version 2 of
17 * the License, or (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public
25 * License along with this program; if not, write to the Free
26 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139,
27 * USA.
28 *
29 **********************************************************************
30 */
31
32#include <linux/poll.h>
33#include "hwaccess.h"
34#include "timer.h"
35#include "recmgr.h"
36#include "audio.h"
37#include "cardwi.h"
38
39/**
40 * query_format - returns a valid sound format
41 *
42 * This function will return a valid sound format as close
43 * to the requested one as possible.
44 */
45static void query_format(int recsrc, struct wave_format *wave_fmt)
46{
47
48 switch (recsrc) {
49 case WAVERECORD_AC97:
50
51 if ((wave_fmt->channels != 1) && (wave_fmt->channels != 2))
52 wave_fmt->channels = 2;
53
54 if (wave_fmt->samplingrate >= (0xBB80 + 0xAC44) / 2)
55 wave_fmt->samplingrate = 0xBB80;
56 else if (wave_fmt->samplingrate >= (0xAC44 + 0x7D00) / 2)
57 wave_fmt->samplingrate = 0xAC44;
58 else if (wave_fmt->samplingrate >= (0x7D00 + 0x5DC0) / 2)
59 wave_fmt->samplingrate = 0x7D00;
60 else if (wave_fmt->samplingrate >= (0x5DC0 + 0x5622) / 2)
61 wave_fmt->samplingrate = 0x5DC0;
62 else if (wave_fmt->samplingrate >= (0x5622 + 0x3E80) / 2)
63 wave_fmt->samplingrate = 0x5622;
64 else if (wave_fmt->samplingrate >= (0x3E80 + 0x2B11) / 2)
65 wave_fmt->samplingrate = 0x3E80;
66 else if (wave_fmt->samplingrate >= (0x2B11 + 0x1F40) / 2)
67 wave_fmt->samplingrate = 0x2B11;
68 else
69 wave_fmt->samplingrate = 0x1F40;
70
71 switch (wave_fmt->id) {
72 case AFMT_S16_LE:
73 wave_fmt->bitsperchannel = 16;
74 break;
75 case AFMT_U8:
76 wave_fmt->bitsperchannel = 8;
77 break;
78 default:
79 wave_fmt->id = AFMT_S16_LE;
80 wave_fmt->bitsperchannel = 16;
81 break;
82 }
83
84 break;
85
86 /* these can't be changed from the original values */
87 case WAVERECORD_MIC:
88 case WAVERECORD_FX:
89 break;
90
91 default:
92 BUG();
93 break;
94 }
95
96 wave_fmt->bytesperchannel = wave_fmt->bitsperchannel >> 3;
97 wave_fmt->bytespersample = wave_fmt->channels * wave_fmt->bytesperchannel;
98 wave_fmt->bytespersec = wave_fmt->bytespersample * wave_fmt->samplingrate;
99 wave_fmt->bytespervoicesample = wave_fmt->bytespersample;
100}
101
102static int alloc_buffer(struct emu10k1_card *card, struct wavein_buffer *buffer)
103{
104 buffer->addr = pci_alloc_consistent(card->pci_dev, buffer->size * buffer->cov,
105 &buffer->dma_handle);
106 if (buffer->addr == NULL)
107 return -1;
108
109 return 0;
110}
111
112static void free_buffer(struct emu10k1_card *card, struct wavein_buffer *buffer)
113{
114 if (buffer->addr != NULL)
115 pci_free_consistent(card->pci_dev, buffer->size * buffer->cov,
116 buffer->addr, buffer->dma_handle);
117}
118
119int emu10k1_wavein_open(struct emu10k1_wavedevice *wave_dev)
120{
121 struct emu10k1_card *card = wave_dev->card;
122 struct wiinst *wiinst = wave_dev->wiinst;
123 struct wiinst **wiinst_tmp = NULL;
124 u16 delay;
125 unsigned long flags;
126
127 DPF(2, "emu10k1_wavein_open()\n");
128
129 switch (wiinst->recsrc) {
130 case WAVERECORD_AC97:
131 wiinst_tmp = &card->wavein.ac97;
132 break;
133 case WAVERECORD_MIC:
134 wiinst_tmp = &card->wavein.mic;
135 break;
136 case WAVERECORD_FX:
137 wiinst_tmp = &card->wavein.fx;
138 break;
139 default:
140 BUG();
141 break;
142 }
143
144 spin_lock_irqsave(&card->lock, flags);
145 if (*wiinst_tmp != NULL) {
146 spin_unlock_irqrestore(&card->lock, flags);
147 return -1;
148 }
149
150 *wiinst_tmp = wiinst;
151 spin_unlock_irqrestore(&card->lock, flags);
152
153 /* handle 8 bit recording */
154 if (wiinst->format.bytesperchannel == 1) {
155 if (wiinst->buffer.size > 0x8000) {
156 wiinst->buffer.size = 0x8000;
157 wiinst->buffer.sizeregval = 0x1f;
158 } else
159 wiinst->buffer.sizeregval += 4;
160
161 wiinst->buffer.cov = 2;
162 } else
163 wiinst->buffer.cov = 1;
164
165 if (alloc_buffer(card, &wiinst->buffer) < 0) {
166 ERROR();
167 return -1;
168 }
169
170 emu10k1_set_record_src(card, wiinst);
171
172 emu10k1_reset_record(card, &wiinst->buffer);
173
174 wiinst->buffer.hw_pos = 0;
175 wiinst->buffer.pos = 0;
176 wiinst->buffer.bytestocopy = 0;
177
178 delay = (48000 * wiinst->buffer.fragment_size) / wiinst->format.bytespersec;
179
180 emu10k1_timer_install(card, &wiinst->timer, delay / 2);
181
182 wiinst->state = WAVE_STATE_OPEN;
183
184 return 0;
185}
186
187void emu10k1_wavein_close(struct emu10k1_wavedevice *wave_dev)
188{
189 struct emu10k1_card *card = wave_dev->card;
190 struct wiinst *wiinst = wave_dev->wiinst;
191 unsigned long flags;
192
193 DPF(2, "emu10k1_wavein_close()\n");
194
195 emu10k1_wavein_stop(wave_dev);
196
197 emu10k1_timer_uninstall(card, &wiinst->timer);
198
199 free_buffer(card, &wiinst->buffer);
200
201 spin_lock_irqsave(&card->lock, flags);
202 switch (wave_dev->wiinst->recsrc) {
203 case WAVERECORD_AC97:
204 card->wavein.ac97 = NULL;
205 break;
206 case WAVERECORD_MIC:
207 card->wavein.mic = NULL;
208 break;
209 case WAVERECORD_FX:
210 card->wavein.fx = NULL;
211 break;
212 default:
213 BUG();
214 break;
215 }
216 spin_unlock_irqrestore(&card->lock, flags);
217
218 wiinst->state = WAVE_STATE_CLOSED;
219}
220
221void emu10k1_wavein_start(struct emu10k1_wavedevice *wave_dev)
222{
223 struct emu10k1_card *card = wave_dev->card;
224 struct wiinst *wiinst = wave_dev->wiinst;
225
226 DPF(2, "emu10k1_wavein_start()\n");
227
228 emu10k1_start_record(card, &wiinst->buffer);
229 emu10k1_timer_enable(wave_dev->card, &wiinst->timer);
230
231 wiinst->state |= WAVE_STATE_STARTED;
232}
233
234void emu10k1_wavein_stop(struct emu10k1_wavedevice *wave_dev)
235{
236 struct emu10k1_card *card = wave_dev->card;
237 struct wiinst *wiinst = wave_dev->wiinst;
238
239 DPF(2, "emu10k1_wavein_stop()\n");
240
241 if (!(wiinst->state & WAVE_STATE_STARTED))
242 return;
243
244 emu10k1_timer_disable(card, &wiinst->timer);
245 emu10k1_stop_record(card, &wiinst->buffer);
246
247 wiinst->state &= ~WAVE_STATE_STARTED;
248}
249
250int emu10k1_wavein_setformat(struct emu10k1_wavedevice *wave_dev, struct wave_format *format)
251{
252 struct emu10k1_card *card = wave_dev->card;
253 struct wiinst *wiinst = wave_dev->wiinst;
254 u16 delay;
255
256 DPF(2, "emu10k1_wavein_setformat()\n");
257
258 if (wiinst->state & WAVE_STATE_STARTED)
259 return -1;
260
261 query_format(wiinst->recsrc, format);
262
263 if ((wiinst->format.samplingrate != format->samplingrate)
264 || (wiinst->format.bitsperchannel != format->bitsperchannel)
265 || (wiinst->format.channels != format->channels)) {
266
267 wiinst->format = *format;
268
269 if (wiinst->state == WAVE_STATE_CLOSED)
270 return 0;
271
272 wiinst->buffer.size *= wiinst->buffer.cov;
273
274 if (wiinst->format.bytesperchannel == 1) {
275 wiinst->buffer.cov = 2;
276 wiinst->buffer.size /= wiinst->buffer.cov;
277 } else
278 wiinst->buffer.cov = 1;
279
280 emu10k1_timer_uninstall(card, &wiinst->timer);
281
282 delay = (48000 * wiinst->buffer.fragment_size) / wiinst->format.bytespersec;
283
284 emu10k1_timer_install(card, &wiinst->timer, delay / 2);
285 }
286
287 return 0;
288}
289
290void emu10k1_wavein_getxfersize(struct wiinst *wiinst, u32 * size)
291{
292 struct wavein_buffer *buffer = &wiinst->buffer;
293
294 *size = buffer->bytestocopy;
295
296 if (wiinst->mmapped)
297 return;
298
299 if (*size > buffer->size) {
300 *size = buffer->size;
301 buffer->pos = buffer->hw_pos;
302 buffer->bytestocopy = buffer->size;
303 DPF(1, "buffer overrun\n");
304 }
305}
306
307static void copy_block(u8 __user *dst, u8 * src, u32 str, u32 len, u8 cov)
308{
309 if (cov == 1)
310 __copy_to_user(dst, src + str, len);
311 else {
312 u8 byte;
313 u32 i;
314
315 src += 1 + 2 * str;
316
317 for (i = 0; i < len; i++) {
318 byte = src[2 * i] ^ 0x80;
319 __copy_to_user(dst + i, &byte, 1);
320 }
321 }
322}
323
324void emu10k1_wavein_xferdata(struct wiinst *wiinst, u8 __user *data, u32 * size)
325{
326 struct wavein_buffer *buffer = &wiinst->buffer;
327 u32 sizetocopy, sizetocopy_now, start;
328 unsigned long flags;
329
330 sizetocopy = min_t(u32, buffer->size, *size);
331 *size = sizetocopy;
332
333 if (!sizetocopy)
334 return;
335
336 spin_lock_irqsave(&wiinst->lock, flags);
337 start = buffer->pos;
338 buffer->pos += sizetocopy;
339 buffer->pos %= buffer->size;
340 buffer->bytestocopy -= sizetocopy;
341 sizetocopy_now = buffer->size - start;
342
343 spin_unlock_irqrestore(&wiinst->lock, flags);
344
345 if (sizetocopy > sizetocopy_now) {
346 sizetocopy -= sizetocopy_now;
347
348 copy_block(data, buffer->addr, start, sizetocopy_now, buffer->cov);
349 copy_block(data + sizetocopy_now, buffer->addr, 0, sizetocopy, buffer->cov);
350 } else {
351 copy_block(data, buffer->addr, start, sizetocopy, buffer->cov);
352 }
353}
354
355void emu10k1_wavein_update(struct emu10k1_card *card, struct wiinst *wiinst)
356{
357 u32 hw_pos;
358 u32 diff;
359
360 /* There is no actual start yet */
361 if (!(wiinst->state & WAVE_STATE_STARTED)) {
362 hw_pos = wiinst->buffer.hw_pos;
363 } else {
364 /* hw_pos in byte units */
365 hw_pos = sblive_readptr(card, wiinst->buffer.idxreg, 0) / wiinst->buffer.cov;
366 }
367
368 diff = (wiinst->buffer.size + hw_pos - wiinst->buffer.hw_pos) % wiinst->buffer.size;
369 wiinst->total_recorded += diff;
370 wiinst->buffer.bytestocopy += diff;
371
372 wiinst->buffer.hw_pos = hw_pos;
373}
diff --git a/sound/oss/emu10k1/cardwi.h b/sound/oss/emu10k1/cardwi.h
new file mode 100644
index 000000000000..15cfb9b35596
--- /dev/null
+++ b/sound/oss/emu10k1/cardwi.h
@@ -0,0 +1,91 @@
1/*
2 **********************************************************************
3 * cardwi.h -- header file for card wave input functions
4 * Copyright 1999, 2000 Creative Labs, Inc.
5 *
6 **********************************************************************
7 *
8 * Date Author Summary of changes
9 * ---- ------ ------------------
10 * October 20, 1999 Bertrand Lee base code release
11 *
12 **********************************************************************
13 *
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License as
16 * published by the Free Software Foundation; either version 2 of
17 * the License, or (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public
25 * License along with this program; if not, write to the Free
26 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139,
27 * USA.
28 *
29 **********************************************************************
30 */
31#ifndef _CARDWI_H
32#define _CARDWI_H
33
34#include "icardwav.h"
35#include "audio.h"
36#include "timer.h"
37
38struct wavein_buffer {
39 u16 ossfragshift;
40 u32 fragment_size;
41 u32 numfrags;
42 u32 hw_pos; /* hardware cursor position */
43 u32 pos; /* software cursor position */
44 u32 bytestocopy; /* bytes of recorded data available */
45 u32 size;
46 u32 pages;
47 u32 sizereg;
48 u32 sizeregval;
49 u32 addrreg;
50 u32 idxreg;
51 u32 adcctl;
52 void *addr;
53 u8 cov;
54 dma_addr_t dma_handle;
55};
56
57struct wiinst
58{
59 u8 state;
60 struct emu_timer timer;
61 struct wave_format format;
62 struct wavein_buffer buffer;
63 wait_queue_head_t wait_queue;
64 u8 mmapped;
65 u32 total_recorded; /* total bytes read() from device */
66 u32 blocks;
67 spinlock_t lock;
68 u8 recsrc;
69 u16 fxwc;
70};
71
72#define WAVEIN_MAXBUFSIZE 65536
73#define WAVEIN_MINBUFSIZE 368
74
75#define WAVEIN_DEFAULTFRAGLEN 100
76#define WAVEIN_DEFAULTBUFLEN 1000
77
78#define WAVEIN_MINFRAGSHIFT 8
79#define WAVEIN_MINFRAGS 2
80
81int emu10k1_wavein_open(struct emu10k1_wavedevice *);
82void emu10k1_wavein_close(struct emu10k1_wavedevice *);
83void emu10k1_wavein_start(struct emu10k1_wavedevice *);
84void emu10k1_wavein_stop(struct emu10k1_wavedevice *);
85void emu10k1_wavein_getxfersize(struct wiinst *, u32 *);
86void emu10k1_wavein_xferdata(struct wiinst *, u8 __user *, u32 *);
87int emu10k1_wavein_setformat(struct emu10k1_wavedevice *, struct wave_format *);
88void emu10k1_wavein_update(struct emu10k1_card *, struct wiinst *);
89
90
91#endif /* _CARDWI_H */
diff --git a/sound/oss/emu10k1/cardwo.c b/sound/oss/emu10k1/cardwo.c
new file mode 100644
index 000000000000..54daca4f57b4
--- /dev/null
+++ b/sound/oss/emu10k1/cardwo.c
@@ -0,0 +1,643 @@
1/*
2 **********************************************************************
3 * cardwo.c - PCM output HAL for emu10k1 driver
4 * Copyright 1999, 2000 Creative Labs, Inc.
5 *
6 **********************************************************************
7 *
8 * Date Author Summary of changes
9 * ---- ------ ------------------
10 * October 20, 1999 Bertrand Lee base code release
11 *
12 **********************************************************************
13 *
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License as
16 * published by the Free Software Foundation; either version 2 of
17 * the License, or (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public
25 * License along with this program; if not, write to the Free
26 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139,
27 * USA.
28 *
29 **********************************************************************
30 */
31
32#include <linux/poll.h>
33#include "hwaccess.h"
34#include "8010.h"
35#include "voicemgr.h"
36#include "cardwo.h"
37#include "audio.h"
38
39static u32 samplerate_to_linearpitch(u32 samplingrate)
40{
41 samplingrate = (samplingrate << 8) / 375;
42 return (samplingrate >> 1) + (samplingrate & 1);
43}
44
45static void query_format(struct emu10k1_wavedevice *wave_dev, struct wave_format *wave_fmt)
46{
47 int i, j, do_passthrough = 0, is_ac3 = 0;
48 struct emu10k1_card *card = wave_dev->card;
49 struct woinst *woinst = wave_dev->woinst;
50
51 if ((wave_fmt->channels > 2) && (wave_fmt->id != AFMT_S16_LE) && (wave_fmt->id != AFMT_U8))
52 wave_fmt->channels = 2;
53
54 if ((wave_fmt->channels < 1) || (wave_fmt->channels > WAVEOUT_MAXVOICES))
55 wave_fmt->channels = 2;
56
57 if (wave_fmt->channels == 2)
58 woinst->num_voices = 1;
59 else
60 woinst->num_voices = wave_fmt->channels;
61
62 if (wave_fmt->samplingrate >= 0x2ee00)
63 wave_fmt->samplingrate = 0x2ee00;
64
65 wave_fmt->passthrough = 0;
66 do_passthrough = is_ac3 = 0;
67
68 if (card->pt.selected)
69 do_passthrough = 1;
70
71 switch (wave_fmt->id) {
72 case AFMT_S16_LE:
73 wave_fmt->bitsperchannel = 16;
74 break;
75 case AFMT_U8:
76 wave_fmt->bitsperchannel = 8;
77 break;
78 case AFMT_AC3:
79 do_passthrough = 1;
80 is_ac3 = 1;
81 break;
82 default:
83 wave_fmt->id = AFMT_S16_LE;
84 wave_fmt->bitsperchannel = 16;
85 break;
86 }
87 if (do_passthrough) {
88 /* currently only one waveout instance may use pass-through */
89 if (woinst->state != WAVE_STATE_CLOSED ||
90 card->pt.state != PT_STATE_INACTIVE ||
91 (wave_fmt->samplingrate != 48000 && !is_ac3)) {
92 DPF(2, "unable to set pass-through mode\n");
93 } else if (USE_PT_METHOD1) {
94 i = emu10k1_find_control_gpr(&card->mgr, card->pt.patch_name, card->pt.intr_gpr_name);
95 j = emu10k1_find_control_gpr(&card->mgr, card->pt.patch_name, card->pt.enable_gpr_name);
96 if (i < 0 || j < 0)
97 DPF(2, "unable to set pass-through mode\n");
98 else {
99 wave_fmt->samplingrate = 48000;
100 wave_fmt->channels = 2;
101 card->pt.pos_gpr = emu10k1_find_control_gpr(&card->mgr, card->pt.patch_name,
102 card->pt.pos_gpr_name);
103 wave_fmt->passthrough = 1;
104 card->pt.intr_gpr = i;
105 card->pt.enable_gpr = j;
106 card->pt.state = PT_STATE_INACTIVE;
107
108 DPD(2, "is_ac3 is %d\n", is_ac3);
109 card->pt.ac3data = is_ac3;
110 wave_fmt->bitsperchannel = 16;
111 }
112 }else{
113 DPF(2, "Using Passthrough Method 2\n");
114 card->pt.enable_gpr = emu10k1_find_control_gpr(&card->mgr, card->pt.patch_name,
115 card->pt.enable_gpr_name);
116 wave_fmt->passthrough = 2;
117 wave_fmt->bitsperchannel = 16;
118 }
119 }
120
121 wave_fmt->bytesperchannel = wave_fmt->bitsperchannel >> 3;
122 wave_fmt->bytespersample = wave_fmt->channels * wave_fmt->bytesperchannel;
123 wave_fmt->bytespersec = wave_fmt->bytespersample * wave_fmt->samplingrate;
124
125 if (wave_fmt->channels == 2)
126 wave_fmt->bytespervoicesample = wave_fmt->channels * wave_fmt->bytesperchannel;
127 else
128 wave_fmt->bytespervoicesample = wave_fmt->bytesperchannel;
129}
130
131static int get_voice(struct emu10k1_card *card, struct woinst *woinst, unsigned int voicenum)
132{
133 struct emu_voice *voice = &woinst->voice[voicenum];
134
135 /* Allocate voices here, if no voices available, return error. */
136
137 voice->usage = VOICE_USAGE_PLAYBACK;
138
139 voice->flags = 0;
140
141 if (woinst->format.channels == 2)
142 voice->flags |= VOICE_FLAGS_STEREO;
143
144 if (woinst->format.bitsperchannel == 16)
145 voice->flags |= VOICE_FLAGS_16BIT;
146
147 if (emu10k1_voice_alloc(card, voice) < 0) {
148 voice->usage = VOICE_USAGE_FREE;
149 return -1;
150 }
151
152 /* Calculate pitch */
153 voice->initial_pitch = (u16) (srToPitch(woinst->format.samplingrate) >> 8);
154 voice->pitch_target = samplerate_to_linearpitch(woinst->format.samplingrate);
155
156 DPD(2, "Initial pitch --> %#x\n", voice->initial_pitch);
157
158 voice->startloop = (voice->mem.emupageindex << 12) /
159 woinst->format.bytespervoicesample;
160 voice->endloop = voice->startloop + woinst->buffer.size / woinst->format.bytespervoicesample;
161 voice->start = voice->startloop;
162
163
164 voice->params[0].volume_target = 0xffff;
165 voice->params[0].initial_fc = 0xff;
166 voice->params[0].initial_attn = 0x00;
167 voice->params[0].byampl_env_sustain = 0x7f;
168 voice->params[0].byampl_env_decay = 0x7f;
169
170
171 if (voice->flags & VOICE_FLAGS_STEREO) {
172 if (woinst->format.passthrough == 2) {
173 voice->params[0].send_routing = voice->params[1].send_routing = card->waveout.send_routing[ROUTE_PT];
174 voice->params[0].send_routing2 = voice->params[1].send_routing2 = card->waveout.send_routing2[ROUTE_PT];
175 voice->params[0].send_dcba = 0xff;
176 voice->params[1].send_dcba = 0xff00;
177 voice->params[0].send_hgfe = voice->params[1].send_hgfe=0;
178 } else {
179 voice->params[0].send_dcba = card->waveout.send_dcba[SEND_LEFT];
180 voice->params[0].send_hgfe = card->waveout.send_hgfe[SEND_LEFT];
181 voice->params[1].send_dcba = card->waveout.send_dcba[SEND_RIGHT];
182 voice->params[1].send_hgfe = card->waveout.send_hgfe[SEND_RIGHT];
183
184 if (woinst->device) {
185 // /dev/dps1
186 voice->params[0].send_routing = voice->params[1].send_routing = card->waveout.send_routing[ROUTE_PCM1];
187 voice->params[0].send_routing2 = voice->params[1].send_routing2 = card->waveout.send_routing2[ROUTE_PCM1];
188 } else {
189 voice->params[0].send_routing = voice->params[1].send_routing = card->waveout.send_routing[ROUTE_PCM];
190 voice->params[0].send_routing2 = voice->params[1].send_routing2 = card->waveout.send_routing2[ROUTE_PCM];
191 }
192 }
193
194 voice->params[1].volume_target = 0xffff;
195 voice->params[1].initial_fc = 0xff;
196 voice->params[1].initial_attn = 0x00;
197 voice->params[1].byampl_env_sustain = 0x7f;
198 voice->params[1].byampl_env_decay = 0x7f;
199 } else {
200 if (woinst->num_voices > 1) {
201 // Multichannel pcm
202 voice->params[0].send_dcba=0xff;
203 voice->params[0].send_hgfe=0;
204 if (card->is_audigy) {
205 voice->params[0].send_routing = 0x3f3f3f00 + card->mchannel_fx + voicenum;
206 voice->params[0].send_routing2 = 0x3f3f3f3f;
207 } else {
208 voice->params[0].send_routing = 0xfff0 + card->mchannel_fx + voicenum;
209 }
210
211 } else {
212 voice->params[0].send_dcba = card->waveout.send_dcba[SEND_MONO];
213 voice->params[0].send_hgfe = card->waveout.send_hgfe[SEND_MONO];
214
215 if (woinst->device) {
216 voice->params[0].send_routing = card->waveout.send_routing[ROUTE_PCM1];
217 voice->params[0].send_routing2 = card->waveout.send_routing2[ROUTE_PCM1];
218 } else {
219 voice->params[0].send_routing = card->waveout.send_routing[ROUTE_PCM];
220 voice->params[0].send_routing2 = card->waveout.send_routing2[ROUTE_PCM];
221 }
222 }
223 }
224
225 DPD(2, "voice: startloop=%#x, endloop=%#x\n", voice->startloop, voice->endloop);
226
227 emu10k1_voice_playback_setup(voice);
228
229 return 0;
230}
231
232int emu10k1_waveout_open(struct emu10k1_wavedevice *wave_dev)
233{
234 struct emu10k1_card *card = wave_dev->card;
235 struct woinst *woinst = wave_dev->woinst;
236 struct waveout_buffer *buffer = &woinst->buffer;
237 unsigned int voicenum;
238 u16 delay;
239
240 DPF(2, "emu10k1_waveout_open()\n");
241
242 for (voicenum = 0; voicenum < woinst->num_voices; voicenum++) {
243 if (emu10k1_voice_alloc_buffer(card, &woinst->voice[voicenum].mem, woinst->buffer.pages) < 0) {
244 ERROR();
245 emu10k1_waveout_close(wave_dev);
246 return -1;
247 }
248
249 if (get_voice(card, woinst, voicenum) < 0) {
250 ERROR();
251 emu10k1_waveout_close(wave_dev);
252 return -1;
253 }
254 }
255
256 buffer->fill_silence = 0;
257 buffer->silence_bytes = 0;
258 buffer->silence_pos = 0;
259 buffer->hw_pos = 0;
260 buffer->free_bytes = woinst->buffer.size;
261
262 delay = (48000 * woinst->buffer.fragment_size) /
263 (woinst->format.samplingrate * woinst->format.bytespervoicesample);
264
265 emu10k1_timer_install(card, &woinst->timer, delay);
266
267 woinst->state = WAVE_STATE_OPEN;
268
269 return 0;
270}
271
272void emu10k1_waveout_close(struct emu10k1_wavedevice *wave_dev)
273{
274 struct emu10k1_card *card = wave_dev->card;
275 struct woinst *woinst = wave_dev->woinst;
276 unsigned int voicenum;
277
278 DPF(2, "emu10k1_waveout_close()\n");
279
280 emu10k1_waveout_stop(wave_dev);
281
282 emu10k1_timer_uninstall(card, &woinst->timer);
283
284 for (voicenum = 0; voicenum < woinst->num_voices; voicenum++) {
285 emu10k1_voice_free(&woinst->voice[voicenum]);
286 emu10k1_voice_free_buffer(card, &woinst->voice[voicenum].mem);
287 }
288
289 woinst->state = WAVE_STATE_CLOSED;
290}
291
292void emu10k1_waveout_start(struct emu10k1_wavedevice *wave_dev)
293{
294 struct emu10k1_card *card = wave_dev->card;
295 struct woinst *woinst = wave_dev->woinst;
296 struct pt_data *pt = &card->pt;
297
298 DPF(2, "emu10k1_waveout_start()\n");
299
300 if (woinst->format.passthrough == 2) {
301 emu10k1_pt_setup(wave_dev);
302 sblive_writeptr(card, (card->is_audigy ? A_GPR_BASE : GPR_BASE) + pt->enable_gpr, 0, 1);
303 pt->state = PT_STATE_PLAYING;
304 }
305
306 /* Actual start */
307 emu10k1_voices_start(woinst->voice, woinst->num_voices, woinst->total_played);
308
309 emu10k1_timer_enable(card, &woinst->timer);
310
311 woinst->state |= WAVE_STATE_STARTED;
312}
313
314int emu10k1_waveout_setformat(struct emu10k1_wavedevice *wave_dev, struct wave_format *format)
315{
316 struct emu10k1_card *card = wave_dev->card;
317 struct woinst *woinst = wave_dev->woinst;
318 unsigned int voicenum;
319 u16 delay;
320
321 DPF(2, "emu10k1_waveout_setformat()\n");
322
323 if (woinst->state & WAVE_STATE_STARTED)
324 return -1;
325
326 query_format(wave_dev, format);
327
328 if (woinst->format.samplingrate != format->samplingrate ||
329 woinst->format.channels != format->channels ||
330 woinst->format.bitsperchannel != format->bitsperchannel) {
331
332 woinst->format = *format;
333
334 if (woinst->state == WAVE_STATE_CLOSED)
335 return 0;
336
337 emu10k1_timer_uninstall(card, &woinst->timer);
338
339 for (voicenum = 0; voicenum < woinst->num_voices; voicenum++) {
340 emu10k1_voice_free(&woinst->voice[voicenum]);
341
342 if (get_voice(card, woinst, voicenum) < 0) {
343 ERROR();
344 emu10k1_waveout_close(wave_dev);
345 return -1;
346 }
347 }
348
349 delay = (48000 * woinst->buffer.fragment_size) /
350 (woinst->format.samplingrate * woinst->format.bytespervoicesample);
351
352 emu10k1_timer_install(card, &woinst->timer, delay);
353 }
354
355 return 0;
356}
357
358void emu10k1_waveout_stop(struct emu10k1_wavedevice *wave_dev)
359{
360 struct emu10k1_card *card = wave_dev->card;
361 struct woinst *woinst = wave_dev->woinst;
362
363 DPF(2, "emu10k1_waveout_stop()\n");
364
365 if (!(woinst->state & WAVE_STATE_STARTED))
366 return;
367
368 emu10k1_timer_disable(card, &woinst->timer);
369
370 /* Stop actual voices */
371 emu10k1_voices_stop(woinst->voice, woinst->num_voices);
372
373 emu10k1_waveout_update(woinst);
374
375 woinst->state &= ~WAVE_STATE_STARTED;
376}
377
378/**
379 * emu10k1_waveout_getxfersize -
380 *
381 * gives the total free bytes on the voice buffer, including silence bytes
382 * (basically: total_free_bytes = free_bytes + silence_bytes).
383 *
384 */
385void emu10k1_waveout_getxfersize(struct woinst *woinst, u32 *total_free_bytes)
386{
387 struct waveout_buffer *buffer = &woinst->buffer;
388 int pending_bytes;
389
390 if (woinst->mmapped) {
391 *total_free_bytes = buffer->free_bytes;
392 return;
393 }
394
395 pending_bytes = buffer->size - buffer->free_bytes;
396
397 buffer->fill_silence = (pending_bytes < (signed) buffer->fragment_size * 2) ? 1 : 0;
398
399 if (pending_bytes > (signed) buffer->silence_bytes) {
400 *total_free_bytes = (buffer->free_bytes + buffer->silence_bytes);
401 } else {
402 *total_free_bytes = buffer->size;
403 buffer->silence_bytes = pending_bytes;
404 if (pending_bytes < 0) {
405 buffer->silence_pos = buffer->hw_pos;
406 buffer->silence_bytes = 0;
407 buffer->free_bytes = buffer->size;
408 DPF(1, "buffer underrun\n");
409 }
410 }
411}
412
413/**
414 * copy_block -
415 *
416 * copies a block of pcm data to a voice buffer.
417 * Notice that the voice buffer is actually a set of disjointed memory pages.
418 *
419 */
420static void copy_block(void **dst, u32 str, u8 __user *src, u32 len)
421{
422 unsigned int pg;
423 unsigned int pgoff;
424 unsigned int k;
425
426 pg = str / PAGE_SIZE;
427 pgoff = str % PAGE_SIZE;
428
429 if (len > PAGE_SIZE - pgoff) {
430 k = PAGE_SIZE - pgoff;
431 if (__copy_from_user((u8 *)dst[pg] + pgoff, src, k))
432 return;
433 len -= k;
434 while (len > PAGE_SIZE) {
435 if (__copy_from_user(dst[++pg], src + k, PAGE_SIZE))
436 return;
437 k += PAGE_SIZE;
438 len -= PAGE_SIZE;
439 }
440 if (__copy_from_user(dst[++pg], src + k, len))
441 return;
442
443 } else
444 __copy_from_user((u8 *)dst[pg] + pgoff, src, len);
445}
446
447/**
448 * copy_ilv_block -
449 *
450 * copies a block of pcm data containing n interleaved channels to n mono voice buffers.
451 * Notice that the voice buffer is actually a set of disjointed memory pages.
452 *
453 */
454static void copy_ilv_block(struct woinst *woinst, u32 str, u8 __user *src, u32 len)
455{
456 unsigned int pg;
457 unsigned int pgoff;
458 unsigned int voice_num;
459 struct emu_voice *voice = woinst->voice;
460
461 pg = str / PAGE_SIZE;
462 pgoff = str % PAGE_SIZE;
463
464 while (len) {
465 for (voice_num = 0; voice_num < woinst->num_voices; voice_num++) {
466 if (__copy_from_user((u8 *)(voice[voice_num].mem.addr[pg]) + pgoff, src, woinst->format.bytespervoicesample))
467 return;
468 src += woinst->format.bytespervoicesample;
469 }
470
471 len -= woinst->format.bytespervoicesample;
472
473 pgoff += woinst->format.bytespervoicesample;
474 if (pgoff >= PAGE_SIZE) {
475 pgoff = 0;
476 pg++;
477 }
478 }
479}
480
481/**
482 * fill_block -
483 *
484 * fills a set voice buffers with a block of a given sample.
485 *
486 */
487static void fill_block(struct woinst *woinst, u32 str, u8 data, u32 len)
488{
489 unsigned int pg;
490 unsigned int pgoff;
491 unsigned int voice_num;
492 struct emu_voice *voice = woinst->voice;
493 unsigned int k;
494
495 pg = str / PAGE_SIZE;
496 pgoff = str % PAGE_SIZE;
497
498 if (len > PAGE_SIZE - pgoff) {
499 k = PAGE_SIZE - pgoff;
500 for (voice_num = 0; voice_num < woinst->num_voices; voice_num++)
501 memset((u8 *)voice[voice_num].mem.addr[pg] + pgoff, data, k);
502 len -= k;
503 while (len > PAGE_SIZE) {
504 pg++;
505 for (voice_num = 0; voice_num < woinst->num_voices; voice_num++)
506 memset(voice[voice_num].mem.addr[pg], data, PAGE_SIZE);
507
508 len -= PAGE_SIZE;
509 }
510 pg++;
511 for (voice_num = 0; voice_num < woinst->num_voices; voice_num++)
512 memset(voice[voice_num].mem.addr[pg], data, len);
513
514 } else {
515 for (voice_num = 0; voice_num < woinst->num_voices; voice_num++)
516 memset((u8 *)voice[voice_num].mem.addr[pg] + pgoff, data, len);
517 }
518}
519
520/**
521 * emu10k1_waveout_xferdata -
522 *
523 * copies pcm data to the voice buffer. Silence samples
524 * previously added to the buffer are overwritten.
525 *
526 */
527void emu10k1_waveout_xferdata(struct woinst *woinst, u8 __user *data, u32 *size)
528{
529 struct waveout_buffer *buffer = &woinst->buffer;
530 struct voice_mem *mem = &woinst->voice[0].mem;
531 u32 sizetocopy, sizetocopy_now, start;
532 unsigned long flags;
533
534 sizetocopy = min_t(u32, buffer->size, *size);
535 *size = sizetocopy;
536
537 if (!sizetocopy)
538 return;
539
540 spin_lock_irqsave(&woinst->lock, flags);
541 start = (buffer->size + buffer->silence_pos - buffer->silence_bytes) % buffer->size;
542
543 if (sizetocopy > buffer->silence_bytes) {
544 buffer->silence_pos += sizetocopy - buffer->silence_bytes;
545 buffer->free_bytes -= sizetocopy - buffer->silence_bytes;
546 buffer->silence_bytes = 0;
547 } else
548 buffer->silence_bytes -= sizetocopy;
549
550 spin_unlock_irqrestore(&woinst->lock, flags);
551
552 sizetocopy_now = buffer->size - start;
553 if (sizetocopy > sizetocopy_now) {
554 sizetocopy -= sizetocopy_now;
555 if (woinst->num_voices > 1) {
556 copy_ilv_block(woinst, start, data, sizetocopy_now);
557 copy_ilv_block(woinst, 0, data + sizetocopy_now * woinst->num_voices, sizetocopy);
558 } else {
559 copy_block(mem->addr, start, data, sizetocopy_now);
560 copy_block(mem->addr, 0, data + sizetocopy_now, sizetocopy);
561 }
562 } else {
563 if (woinst->num_voices > 1)
564 copy_ilv_block(woinst, start, data, sizetocopy);
565 else
566 copy_block(mem->addr, start, data, sizetocopy);
567 }
568}
569
570/**
571 * emu10k1_waveout_fillsilence -
572 *
573 * adds samples of silence to the voice buffer so that we
574 * don't loop over stale pcm data.
575 *
576 */
577void emu10k1_waveout_fillsilence(struct woinst *woinst)
578{
579 struct waveout_buffer *buffer = &woinst->buffer;
580 u32 sizetocopy, sizetocopy_now, start;
581 u8 filldata;
582 unsigned long flags;
583
584 sizetocopy = buffer->fragment_size;
585
586 if (woinst->format.bitsperchannel == 16)
587 filldata = 0x00;
588 else
589 filldata = 0x80;
590
591 spin_lock_irqsave(&woinst->lock, flags);
592 buffer->silence_bytes += sizetocopy;
593 buffer->free_bytes -= sizetocopy;
594 buffer->silence_pos %= buffer->size;
595 start = buffer->silence_pos;
596 buffer->silence_pos += sizetocopy;
597 spin_unlock_irqrestore(&woinst->lock, flags);
598
599 sizetocopy_now = buffer->size - start;
600
601 if (sizetocopy > sizetocopy_now) {
602 sizetocopy -= sizetocopy_now;
603 fill_block(woinst, start, filldata, sizetocopy_now);
604 fill_block(woinst, 0, filldata, sizetocopy);
605 } else {
606 fill_block(woinst, start, filldata, sizetocopy);
607 }
608}
609
610/**
611 * emu10k1_waveout_update -
612 *
613 * updates the position of the voice buffer hardware pointer (hw_pos)
614 * and the number of free bytes on the buffer (free_bytes).
615 * The free bytes _don't_ include silence bytes that may have been
616 * added to the buffer.
617 *
618 */
619void emu10k1_waveout_update(struct woinst *woinst)
620{
621 u32 hw_pos;
622 u32 diff;
623
624 /* There is no actual start yet */
625 if (!(woinst->state & WAVE_STATE_STARTED)) {
626 hw_pos = woinst->buffer.hw_pos;
627 } else {
628 /* hw_pos in sample units */
629 hw_pos = sblive_readptr(woinst->voice[0].card, CCCA_CURRADDR, woinst->voice[0].num);
630
631 if(hw_pos < woinst->voice[0].start)
632 hw_pos += woinst->buffer.size / woinst->format.bytespervoicesample - woinst->voice[0].start;
633 else
634 hw_pos -= woinst->voice[0].start;
635
636 hw_pos *= woinst->format.bytespervoicesample;
637 }
638
639 diff = (woinst->buffer.size + hw_pos - woinst->buffer.hw_pos) % woinst->buffer.size;
640 woinst->total_played += diff;
641 woinst->buffer.free_bytes += diff;
642 woinst->buffer.hw_pos = hw_pos;
643}
diff --git a/sound/oss/emu10k1/cardwo.h b/sound/oss/emu10k1/cardwo.h
new file mode 100644
index 000000000000..1dece8853e5c
--- /dev/null
+++ b/sound/oss/emu10k1/cardwo.h
@@ -0,0 +1,90 @@
1/*
2 **********************************************************************
3 * cardwo.h -- header file for card wave out functions
4 * Copyright 1999, 2000 Creative Labs, Inc.
5 *
6 **********************************************************************
7 *
8 * Date Author Summary of changes
9 * ---- ------ ------------------
10 * October 20, 1999 Bertrand Lee base code release
11 *
12 **********************************************************************
13 *
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License as
16 * published by the Free Software Foundation; either version 2 of
17 * the License, or (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public
25 * License along with this program; if not, write to the Free
26 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139,
27 * USA.
28 *
29 **********************************************************************
30 */
31
32#ifndef _CARDWO_H
33#define _CARDWO_H
34
35#include "icardwav.h"
36#include "audio.h"
37#include "voicemgr.h"
38#include "timer.h"
39
40/* setting this to other than a power of two may break some applications */
41#define WAVEOUT_MAXBUFSIZE MAXBUFSIZE
42
43#define WAVEOUT_DEFAULTFRAGLEN 20 /* Time to play a fragment in ms (latency) */
44#define WAVEOUT_DEFAULTBUFLEN 500 /* Time to play the entire buffer in ms */
45
46#define WAVEOUT_MINFRAGSHIFT 6 /* Minimum fragment size in bytes is 2^6 */
47#define WAVEOUT_MINFRAGS 3 /* _don't_ go bellow 3, it would break silence filling */
48#define WAVEOUT_MAXVOICES 6
49
50struct waveout_buffer {
51 u16 ossfragshift;
52 u32 numfrags;
53 u32 fragment_size; /* in bytes units */
54 u32 size; /* in bytes units */
55 u32 pages; /* buffer size in page units*/
56 u32 silence_pos; /* software cursor position (including silence bytes) */
57 u32 hw_pos; /* hardware cursor position */
58 u32 free_bytes; /* free bytes available on the buffer (not including silence bytes) */
59 u8 fill_silence;
60 u32 silence_bytes; /* silence bytes on the buffer */
61};
62
63struct woinst
64{
65 u8 state;
66 u8 num_voices;
67 struct emu_voice voice[WAVEOUT_MAXVOICES];
68 struct emu_timer timer;
69 struct wave_format format;
70 struct waveout_buffer buffer;
71 wait_queue_head_t wait_queue;
72 u8 mmapped;
73 u32 total_copied; /* total number of bytes written() to the buffer (excluding silence) */
74 u32 total_played; /* total number of bytes played including silence */
75 u32 blocks;
76 u8 device;
77 spinlock_t lock;
78};
79
80int emu10k1_waveout_open(struct emu10k1_wavedevice *);
81void emu10k1_waveout_close(struct emu10k1_wavedevice *);
82void emu10k1_waveout_start(struct emu10k1_wavedevice *);
83void emu10k1_waveout_stop(struct emu10k1_wavedevice *);
84void emu10k1_waveout_getxfersize(struct woinst*, u32 *);
85void emu10k1_waveout_xferdata(struct woinst*, u8 __user *, u32 *);
86void emu10k1_waveout_fillsilence(struct woinst*);
87int emu10k1_waveout_setformat(struct emu10k1_wavedevice*, struct wave_format*);
88void emu10k1_waveout_update(struct woinst*);
89
90#endif /* _CARDWO_H */
diff --git a/sound/oss/emu10k1/ecard.c b/sound/oss/emu10k1/ecard.c
new file mode 100644
index 000000000000..4ae635fe1402
--- /dev/null
+++ b/sound/oss/emu10k1/ecard.c
@@ -0,0 +1,157 @@
1/*
2 **********************************************************************
3 * ecard.c - E-card initialization code
4 * Copyright 1999, 2000 Creative Labs, Inc.
5 *
6 **********************************************************************
7 *
8 * Date Author Summary of changes
9 * ---- ------ ------------------
10 * October 20, 1999 Bertrand Lee base code release
11 *
12 **********************************************************************
13 *
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License as
16 * published by the Free Software Foundation; either version 2 of
17 * the License, or (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public
25 * License along with this program; if not, write to the Free
26 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139,
27 * USA.
28 *
29 **********************************************************************
30 */
31
32#include "ecard.h"
33#include "hwaccess.h"
34
35/* Private routines */
36static void ecard_setadcgain(struct emu10k1_card *, struct ecard_state *, u16);
37static void ecard_write(struct emu10k1_card *, u32);
38
39/**************************************************************************
40 * @func Set the gain of the ECARD's CS3310 Trim/gain controller. The
41 * trim value consists of a 16bit value which is composed of two
42 * 8 bit gain/trim values, one for the left channel and one for the
43 * right channel. The following table maps from the Gain/Attenuation
44 * value in decibels into the corresponding bit pattern for a single
45 * channel.
46 */
47
48static void ecard_setadcgain(struct emu10k1_card *card, struct ecard_state *ecard, u16 gain)
49{
50 u32 currbit;
51 ecard->adc_gain = gain;
52
53 /* Enable writing to the TRIM registers */
54 ecard_write(card, ecard->control_bits & ~EC_TRIM_CSN);
55
56 /* Do it again to insure that we meet hold time requirements */
57 ecard_write(card, ecard->control_bits & ~EC_TRIM_CSN);
58
59 for (currbit = (1L << 15); currbit; currbit >>= 1) {
60
61 u32 value = ecard->control_bits & ~(EC_TRIM_CSN|EC_TRIM_SDATA);
62
63 if (gain & currbit)
64 value |= EC_TRIM_SDATA;
65
66 /* Clock the bit */
67 ecard_write(card, value);
68 ecard_write(card, value | EC_TRIM_SCLK);
69 ecard_write(card, value);
70 }
71
72 ecard_write(card, ecard->control_bits);
73}
74
75/**************************************************************************
76 * @func Clock bits into the Ecard's control latch. The Ecard uses a
77 * control latch will is loaded bit-serially by toggling the Modem control
78 * lines from function 2 on the E8010. This function hides these details
79 * and presents the illusion that we are actually writing to a distinct
80 * register.
81 */
82static void ecard_write(struct emu10k1_card *card, u32 value)
83{
84 u16 count;
85 u32 data, hcvalue;
86 unsigned long flags;
87
88 spin_lock_irqsave(&card->lock, flags);
89
90 hcvalue = inl(card->iobase + HCFG) & ~(HOOKN_BIT|HANDN_BIT|PULSEN_BIT);
91
92 outl(card->iobase + HCFG, hcvalue);
93
94 for (count = 0 ; count < EC_NUM_CONTROL_BITS; count++) {
95
96 /* Set up the value */
97 data = ((value & 0x1) ? PULSEN_BIT : 0);
98 value >>= 1;
99
100 outl(card->iobase + HCFG, hcvalue | data);
101
102 /* Clock the shift register */
103 outl(card->iobase + HCFG, hcvalue | data | HANDN_BIT);
104 outl(card->iobase + HCFG, hcvalue | data);
105 }
106
107 /* Latch the bits */
108 outl(card->iobase + HCFG, hcvalue | HOOKN_BIT);
109 outl(card->iobase + HCFG, hcvalue);
110
111 spin_unlock_irqrestore(&card->lock, flags);
112}
113
114void __devinit emu10k1_ecard_init(struct emu10k1_card *card)
115{
116 u32 hcvalue;
117 struct ecard_state ecard;
118
119 /* Set up the initial settings */
120 ecard.mux0_setting = EC_DEFAULT_SPDIF0_SEL;
121 ecard.mux1_setting = EC_DEFAULT_SPDIF1_SEL;
122 ecard.mux2_setting = 0;
123 ecard.adc_gain = EC_DEFAULT_ADC_GAIN;
124 ecard.control_bits = EC_RAW_RUN_MODE |
125 EC_SPDIF0_SELECT(ecard.mux0_setting) |
126 EC_SPDIF1_SELECT(ecard.mux1_setting);
127
128
129 /* Step 0: Set the codec type in the hardware control register
130 * and enable audio output */
131 hcvalue = emu10k1_readfn0(card, HCFG);
132 emu10k1_writefn0(card, HCFG, hcvalue | HCFG_AUDIOENABLE | HCFG_CODECFORMAT_I2S);
133
134 /* Step 1: Turn off the led and deassert TRIM_CS */
135 ecard_write(card, EC_ADCCAL | EC_LEDN | EC_TRIM_CSN);
136
137 /* Step 2: Calibrate the ADC and DAC */
138 ecard_write(card, EC_DACCAL | EC_LEDN | EC_TRIM_CSN);
139
140 /* Step 3: Wait for awhile; FIXME: Is this correct? */
141
142 current->state = TASK_INTERRUPTIBLE;
143 schedule_timeout(HZ);
144
145 /* Step 4: Switch off the DAC and ADC calibration. Note
146 * That ADC_CAL is actually an inverted signal, so we assert
147 * it here to stop calibration. */
148 ecard_write(card, EC_ADCCAL | EC_LEDN | EC_TRIM_CSN);
149
150 /* Step 4: Switch into run mode */
151 ecard_write(card, ecard.control_bits);
152
153 /* Step 5: Set the analog input gain */
154 ecard_setadcgain(card, &ecard, ecard.adc_gain);
155}
156
157
diff --git a/sound/oss/emu10k1/ecard.h b/sound/oss/emu10k1/ecard.h
new file mode 100644
index 000000000000..67aead16e8ec
--- /dev/null
+++ b/sound/oss/emu10k1/ecard.h
@@ -0,0 +1,113 @@
1/*
2 **********************************************************************
3 * ecard.h
4 * Copyright 1999, 2000 Creative Labs, Inc.
5 *
6 **********************************************************************
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License as
10 * published by the Free Software Foundation; either version 2 of
11 * the License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public
19 * License along with this program; if not, write to the Free
20 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139,
21 * USA.
22 *
23 **********************************************************************
24 */
25
26#ifndef _ECARD_H
27#define _ECARD_H
28
29#include "8010.h"
30#include "hwaccess.h"
31#include <linux/init.h>
32
33/* In A1 Silicon, these bits are in the HC register */
34#define HOOKN_BIT (1L << 12)
35#define HANDN_BIT (1L << 11)
36#define PULSEN_BIT (1L << 10)
37
38#define EC_GDI1 (1 << 13)
39#define EC_GDI0 (1 << 14)
40
41#define EC_NUM_CONTROL_BITS 20
42
43#define EC_AC3_DATA_SELN 0x0001L
44#define EC_EE_DATA_SEL 0x0002L
45#define EC_EE_CNTRL_SELN 0x0004L
46#define EC_EECLK 0x0008L
47#define EC_EECS 0x0010L
48#define EC_EESDO 0x0020L
49#define EC_TRIM_CSN 0x0040L
50#define EC_TRIM_SCLK 0x0080L
51#define EC_TRIM_SDATA 0x0100L
52#define EC_TRIM_MUTEN 0x0200L
53#define EC_ADCCAL 0x0400L
54#define EC_ADCRSTN 0x0800L
55#define EC_DACCAL 0x1000L
56#define EC_DACMUTEN 0x2000L
57#define EC_LEDN 0x4000L
58
59#define EC_SPDIF0_SEL_SHIFT 15
60#define EC_SPDIF1_SEL_SHIFT 17
61#define EC_SPDIF0_SEL_MASK (0x3L << EC_SPDIF0_SEL_SHIFT)
62#define EC_SPDIF1_SEL_MASK (0x7L << EC_SPDIF1_SEL_SHIFT)
63#define EC_SPDIF0_SELECT(_x) (((_x) << EC_SPDIF0_SEL_SHIFT) & EC_SPDIF0_SEL_MASK)
64#define EC_SPDIF1_SELECT(_x) (((_x) << EC_SPDIF1_SEL_SHIFT) & EC_SPDIF1_SEL_MASK)
65#define EC_CURRENT_PROM_VERSION 0x01 /* Self-explanatory. This should
66 * be incremented any time the EEPROM's
67 * format is changed. */
68
69#define EC_EEPROM_SIZE 0x40 /* ECARD EEPROM has 64 16-bit words */
70
71/* Addresses for special values stored in to EEPROM */
72#define EC_PROM_VERSION_ADDR 0x20 /* Address of the current prom version */
73#define EC_BOARDREV0_ADDR 0x21 /* LSW of board rev */
74#define EC_BOARDREV1_ADDR 0x22 /* MSW of board rev */
75
76#define EC_LAST_PROMFILE_ADDR 0x2f
77
78#define EC_SERIALNUM_ADD 0x30 /* First word of serial number. The number
79 * can be up to 30 characters in length
80 * and is stored as a NULL-terminated
81 * ASCII string. Any unused bytes must be
82 * filled with zeros */
83#define EC_CHECKSUM_ADDR 0x3f /* Location at which checksum is stored */
84
85
86
87/* Most of this stuff is pretty self-evident. According to the hardware
88 * dudes, we need to leave the ADCCAL bit low in order to avoid a DC
89 * offset problem. Weird.
90 */
91#define EC_RAW_RUN_MODE (EC_DACMUTEN | EC_ADCRSTN | EC_TRIM_MUTEN | EC_TRIM_CSN)
92
93
94#define EC_DEFAULT_ADC_GAIN 0xC4C4
95#define EC_DEFAULT_SPDIF0_SEL 0x0
96#define EC_DEFAULT_SPDIF1_SEL 0x4
97
98#define HC_EA 0x01L
99
100/* ECARD state structure. This structure maintains the state
101 * for various portions of the ECARD's onboard hardware.
102 */
103struct ecard_state {
104 u32 control_bits;
105 u16 adc_gain;
106 u16 mux0_setting;
107 u16 mux1_setting;
108 u16 mux2_setting;
109};
110
111void emu10k1_ecard_init(struct emu10k1_card *) __devinit;
112
113#endif /* _ECARD_H */
diff --git a/sound/oss/emu10k1/efxmgr.c b/sound/oss/emu10k1/efxmgr.c
new file mode 100644
index 000000000000..7d5865de4c2e
--- /dev/null
+++ b/sound/oss/emu10k1/efxmgr.c
@@ -0,0 +1,220 @@
1/*
2 **********************************************************************
3 * efxmgr.c
4 * Copyright 1999, 2000 Creative Labs, Inc.
5 *
6 **********************************************************************
7 *
8 * Date Author Summary of changes
9 * ---- ------ ------------------
10 * October 20, 1999 Bertrand Lee base code release
11 *
12 **********************************************************************
13 *
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License as
16 * published by the Free Software Foundation; either version 2 of
17 * the License, or (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public
25 * License along with this program; if not, write to the Free
26 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139,
27 * USA.
28 *
29 **********************************************************************
30 */
31
32#include <linux/bitops.h>
33#include "hwaccess.h"
34#include "efxmgr.h"
35
36int emu10k1_find_control_gpr(struct patch_manager *mgr, const char *patch_name, const char *gpr_name)
37{
38 struct dsp_patch *patch;
39 struct dsp_rpatch *rpatch;
40 char s[PATCH_NAME_SIZE + 4];
41 unsigned long *gpr_used;
42 int i;
43
44 DPD(2, "emu10k1_find_control_gpr(): %s %s\n", patch_name, gpr_name);
45
46 rpatch = &mgr->rpatch;
47 if (!strcmp(rpatch->name, patch_name)) {
48 gpr_used = rpatch->gpr_used;
49 goto match;
50 }
51
52 for (i = 0; i < mgr->current_pages * PATCHES_PER_PAGE; i++) {
53 patch = PATCH(mgr, i);
54 sprintf(s,"%s", patch->name);
55
56 if (!strcmp(s, patch_name)) {
57 gpr_used = patch->gpr_used;
58 goto match;
59 }
60 }
61
62 return -1;
63
64 match:
65 for (i = 0; i < NUM_GPRS; i++)
66 if (mgr->gpr[i].type == GPR_TYPE_CONTROL &&
67 test_bit(i, gpr_used) &&
68 !strcmp(mgr->gpr[i].name, gpr_name))
69 return i;
70
71 return -1;
72}
73
74void emu10k1_set_control_gpr(struct emu10k1_card *card, int addr, s32 val, int flag)
75{
76 struct patch_manager *mgr = &card->mgr;
77
78 DPD(2, "emu10k1_set_control_gpr(): %d %x\n", addr, val);
79
80 if (addr < 0 || addr >= NUM_GPRS)
81 return;
82
83 //fixme: once patch manager is up, remember to fix this for the audigy
84 if (card->is_audigy) {
85 sblive_writeptr(card, A_GPR_BASE + addr, 0, val);
86 } else {
87 if (flag)
88 val += sblive_readptr(card, GPR_BASE + addr, 0);
89 if (val > mgr->gpr[addr].max)
90 val = mgr->gpr[addr].max;
91 else if (val < mgr->gpr[addr].min)
92 val = mgr->gpr[addr].min;
93 sblive_writeptr(card, GPR_BASE + addr, 0, val);
94 }
95
96
97}
98
99//TODO: make this configurable:
100#define VOLCTRL_CHANNEL SOUND_MIXER_VOLUME
101#define VOLCTRL_STEP_SIZE 5
102
103//An internal function for setting OSS mixer controls.
104static void emu10k1_set_oss_vol(struct emu10k1_card *card, int oss_mixer,
105 unsigned int left, unsigned int right)
106{
107 extern char volume_params[SOUND_MIXER_NRDEVICES];
108
109 card->ac97->mixer_state[oss_mixer] = (right << 8) | left;
110
111 if (!card->is_aps)
112 card->ac97->write_mixer(card->ac97, oss_mixer, left, right);
113
114 emu10k1_set_volume_gpr(card, card->mgr.ctrl_gpr[oss_mixer][0], left,
115 volume_params[oss_mixer]);
116
117 emu10k1_set_volume_gpr(card, card->mgr.ctrl_gpr[oss_mixer][1], right,
118 volume_params[oss_mixer]);
119}
120
121//FIXME: mute should unmute when pressed a second time
122void emu10k1_mute_irqhandler(struct emu10k1_card *card)
123{
124 int oss_channel = VOLCTRL_CHANNEL;
125 int left, right;
126 static int val;
127
128 if (val) {
129 left = val & 0xff;
130 right = (val >> 8) & 0xff;
131 val = 0;
132 } else {
133 val = card->ac97->mixer_state[oss_channel];
134 left = 0;
135 right = 0;
136 }
137
138 emu10k1_set_oss_vol(card, oss_channel, left, right);
139}
140
141void emu10k1_volincr_irqhandler(struct emu10k1_card *card)
142{
143 int oss_channel = VOLCTRL_CHANNEL;
144 int left, right;
145
146 left = card->ac97->mixer_state[oss_channel] & 0xff;
147 right = (card->ac97->mixer_state[oss_channel] >> 8) & 0xff;
148
149 if ((left += VOLCTRL_STEP_SIZE) > 100)
150 left = 100;
151
152 if ((right += VOLCTRL_STEP_SIZE) > 100)
153 right = 100;
154
155 emu10k1_set_oss_vol(card, oss_channel, left, right);
156}
157
158void emu10k1_voldecr_irqhandler(struct emu10k1_card *card)
159{
160 int oss_channel = VOLCTRL_CHANNEL;
161 int left, right;
162
163 left = card->ac97->mixer_state[oss_channel] & 0xff;
164 right = (card->ac97->mixer_state[oss_channel] >> 8) & 0xff;
165
166 if ((left -= VOLCTRL_STEP_SIZE) < 0)
167 left = 0;
168
169 if ((right -= VOLCTRL_STEP_SIZE) < 0)
170 right = 0;
171
172 emu10k1_set_oss_vol(card, oss_channel, left, right);
173}
174
175void emu10k1_set_volume_gpr(struct emu10k1_card *card, int addr, s32 vol, int scale)
176{
177 struct patch_manager *mgr = &card->mgr;
178 unsigned long flags;
179
180 static const s32 log2lin[4] ={ // attenuation (dB)
181 0x7fffffff, // 0.0
182 0x7fffffff * 0.840896415253715 , // 1.5
183 0x7fffffff * 0.707106781186548, // 3.0
184 0x7fffffff * 0.594603557501361 , // 4.5
185 };
186
187 if (addr < 0)
188 return;
189
190 vol = (100 - vol ) * scale / 100;
191
192 // Thanks to the comp.dsp newsgroup for this neat trick:
193 vol = (vol >= scale) ? 0 : (log2lin[vol & 3] >> (vol >> 2));
194
195 spin_lock_irqsave(&mgr->lock, flags);
196 emu10k1_set_control_gpr(card, addr, vol, 0);
197 spin_unlock_irqrestore(&mgr->lock, flags);
198}
199
200void emu10k1_dsp_irqhandler(struct emu10k1_card *card)
201{
202 unsigned long flags;
203
204 if (card->pt.state != PT_STATE_INACTIVE) {
205 u32 bc;
206 bc = sblive_readptr(card, GPR_BASE + card->pt.intr_gpr, 0);
207 if (bc != 0) {
208 DPD(3, "pt interrupt, bc = %d\n", bc);
209 spin_lock_irqsave(&card->pt.lock, flags);
210 card->pt.blocks_played = bc;
211 if (card->pt.blocks_played >= card->pt.blocks_copied) {
212 DPF(1, "buffer underrun in passthrough playback\n");
213 emu10k1_pt_stop(card);
214 }
215 wake_up_interruptible(&card->pt.wait);
216 spin_unlock_irqrestore(&card->pt.lock, flags);
217 }
218 }
219}
220
diff --git a/sound/oss/emu10k1/efxmgr.h b/sound/oss/emu10k1/efxmgr.h
new file mode 100644
index 000000000000..ef48e5c70d1f
--- /dev/null
+++ b/sound/oss/emu10k1/efxmgr.h
@@ -0,0 +1,270 @@
1/*
2 **********************************************************************
3 * sblive_fx.h
4 * Copyright 1999, 2000 Creative Labs, Inc.
5 *
6 **********************************************************************
7 *
8 * Date Author Summary of changes
9 * ---- ------ ------------------
10 * October 20, 1999 Bertrand Lee base code release
11 *
12 **********************************************************************
13 *
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License as
16 * published by the Free Software Foundation; either version 2 of
17 * the License, or (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public
25 * License along with this program; if not, write to the Free
26 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139,
27 * USA.
28 *
29 **********************************************************************
30 */
31
32#ifndef _EFXMGR_H
33#define _EFXMGR_H
34
35struct emu_efx_info_t{
36 int opcode_shift;
37 int high_operand_shift;
38 int instruction_start;
39 int gpr_base;
40 int output_base;
41};
42
43
44#define WRITE_EFX(a, b, c) sblive_writeptr((a), emu_efx_info[card->is_audigy].instruction_start + (b), 0, (c))
45
46#define OP(op, z, w, x, y) \
47 do { WRITE_EFX(card, (pc) * 2, ((x) << emu_efx_info[card->is_audigy].high_operand_shift) | (y)); \
48 WRITE_EFX(card, (pc) * 2 + 1, ((op) << emu_efx_info[card->is_audigy].opcode_shift ) | ((z) << emu_efx_info[card->is_audigy].high_operand_shift) | (w)); \
49 ++pc; } while (0)
50
51#define NUM_INPUTS 0x20
52#define NUM_OUTPUTS 0x20
53#define NUM_GPRS 0x100
54
55#define A_NUM_INPUTS 0x60
56#define A_NUM_OUTPUTS 0x60 //fixme: this may or may not be true
57#define A_NUM_GPRS 0x200
58
59#define GPR_NAME_SIZE 32
60#define PATCH_NAME_SIZE 32
61
62struct dsp_rpatch {
63 char name[PATCH_NAME_SIZE];
64 u16 code_start;
65 u16 code_size;
66
67 unsigned long gpr_used[NUM_GPRS / (sizeof(unsigned long) * 8) + 1];
68 unsigned long gpr_input[NUM_GPRS / (sizeof(unsigned long) * 8) + 1];
69 unsigned long route[NUM_OUTPUTS];
70 unsigned long route_v[NUM_OUTPUTS];
71};
72
73struct dsp_patch {
74 char name[PATCH_NAME_SIZE];
75 u8 id;
76 unsigned long input; /* bitmap of the lines used as inputs */
77 unsigned long output; /* bitmap of the lines used as outputs */
78 u16 code_start;
79 u16 code_size;
80
81 unsigned long gpr_used[NUM_GPRS / (sizeof(unsigned long) * 8) + 1]; /* bitmap of used gprs */
82 unsigned long gpr_input[NUM_GPRS / (sizeof(unsigned long) * 8) + 1];
83 u8 traml_istart; /* starting address of the internal tram lines used */
84 u8 traml_isize; /* number of internal tram lines used */
85
86 u8 traml_estart;
87 u8 traml_esize;
88
89 u16 tramb_istart; /* starting address of the internal tram memory used */
90 u16 tramb_isize; /* amount of internal memory used */
91 u32 tramb_estart;
92 u32 tramb_esize;
93};
94
95struct dsp_gpr {
96 u8 type; /* gpr type, STATIC, DYNAMIC, INPUT, OUTPUT, CONTROL */
97 char name[GPR_NAME_SIZE]; /* gpr value, only valid for control gprs */
98 s32 min, max; /* value range for this gpr, only valid for control gprs */
99 u8 line; /* which input/output line is the gpr attached, only valid for input/output gprs */
100 u8 usage;
101};
102
103enum {
104 GPR_TYPE_NULL = 0,
105 GPR_TYPE_IO,
106 GPR_TYPE_STATIC,
107 GPR_TYPE_DYNAMIC,
108 GPR_TYPE_CONTROL,
109 GPR_TYPE_CONSTANT
110};
111
112#define GPR_BASE 0x100
113#define OUTPUT_BASE 0x20
114
115#define A_GPR_BASE 0x400
116#define A_OUTPUT_BASE 0x60
117
118#define MAX_PATCHES_PAGES 32
119
120struct patch_manager {
121 void *patch[MAX_PATCHES_PAGES];
122 int current_pages;
123 struct dsp_rpatch rpatch;
124 struct dsp_gpr gpr[NUM_GPRS]; /* gpr usage table */
125 spinlock_t lock;
126 s16 ctrl_gpr[SOUND_MIXER_NRDEVICES][2];
127};
128
129#define PATCHES_PER_PAGE (PAGE_SIZE / sizeof(struct dsp_patch))
130
131#define PATCH(mgr, i) ((struct dsp_patch *) (mgr)->patch[(i) / PATCHES_PER_PAGE] + (i) % PATCHES_PER_PAGE)
132
133/* PCM volume control */
134#define TMP_PCM_L 0x100 //temp PCM L (after the vol control)
135#define TMP_PCM_R 0x101
136#define VOL_PCM_L 0x102 //vol PCM
137#define VOL_PCM_R 0x103
138
139/* Routing patch */
140#define TMP_AC_L 0x104 //tmp ac97 out
141#define TMP_AC_R 0x105
142#define TMP_REAR_L 0x106 //output - Temp Rear
143#define TMP_REAR_R 0x107
144#define TMP_DIGI_L 0x108 //output - Temp digital
145#define TMP_DIGI_R 0x109
146#define DSP_VOL_L 0x10a // main dsp volume
147#define DSP_VOL_R 0x10b
148
149/* hw inputs */
150#define PCM_IN_L 0x00
151#define PCM_IN_R 0x01
152
153#define PCM1_IN_L 0x04
154#define PCM1_IN_R 0x05
155//mutilchannel playback stream appear here:
156
157#define MULTI_FRONT_L 0x08
158#define MULTI_FRONT_R 0x09
159#define MULTI_REAR_L 0x0a
160#define MULTI_REAR_R 0x0b
161#define MULTI_CENTER 0x0c
162#define MULTI_LFE 0x0d
163
164#define AC97_IN_L 0x10
165#define AC97_IN_R 0x11
166#define SPDIF_CD_L 0x12
167#define SPDIF_CD_R 0x13
168
169/* hw outputs */
170#define AC97_FRONT_L 0x20
171#define AC97_FRONT_R 0x21
172#define DIGITAL_OUT_L 0x22
173#define DIGITAL_OUT_R 0x23
174#define DIGITAL_CENTER 0x24
175#define DIGITAL_LFE 0x25
176
177#define ANALOG_REAR_L 0x28
178#define ANALOG_REAR_R 0x29
179#define ADC_REC_L 0x2a
180#define ADC_REC_R 0x2b
181
182#define ANALOG_CENTER 0x31
183#define ANALOG_LFE 0x32
184
185
186#define INPUT_PATCH_START(patch, nm, ln, i) \
187do { \
188 patch = PATCH(mgr, patch_n); \
189 strcpy(patch->name, nm); \
190 patch->code_start = pc * 2; \
191 patch->input = (1<<(0x1f&ln)); \
192 patch->output= (1<<(0x1f&ln)); \
193 patch->id = i; \
194} while(0)
195
196#define INPUT_PATCH_END(patch) \
197do { \
198 patch->code_size = pc * 2 - patch->code_start; \
199 patch_n++; \
200} while(0)
201
202
203#define ROUTING_PATCH_START(patch, nm) \
204do { \
205 patch = &mgr->rpatch; \
206 strcpy(patch->name, nm); \
207 patch->code_start = pc * 2; \
208} while(0)
209
210#define ROUTING_PATCH_END(patch) \
211do { \
212 patch->code_size = pc * 2 - patch->code_start; \
213} while(0)
214
215#define CONNECT(input, output) set_bit(input, &rpatch->route[(output) - OUTPUT_BASE]);
216
217#define CONNECT_V(input, output) set_bit(input, &rpatch->route_v[(output) - OUTPUT_BASE]);
218
219#define OUTPUT_PATCH_START(patch, nm, ln, i) \
220do { \
221 patch = PATCH(mgr, patch_n); \
222 strcpy(patch->name, nm); \
223 patch->code_start = pc * 2; \
224 patch->input = (1<<(0x1f&ln)); \
225 patch->output= (1<<(0x1f&ln)); \
226 patch->id = i; \
227} while(0)
228
229#define OUTPUT_PATCH_END(patch) \
230do { \
231 patch->code_size = pc * 2 - patch->code_start; \
232 patch_n++; \
233} while(0)
234
235#define GET_OUTPUT_GPR(patch, g, ln) \
236do { \
237 mgr->gpr[(g) - GPR_BASE].type = GPR_TYPE_IO; \
238 mgr->gpr[(g) - GPR_BASE].usage++; \
239 mgr->gpr[(g) - GPR_BASE].line = ln; \
240 set_bit((g) - GPR_BASE, patch->gpr_used); \
241} while(0)
242
243#define GET_INPUT_GPR(patch, g, ln) \
244do { \
245 mgr->gpr[(g) - GPR_BASE].type = GPR_TYPE_IO; \
246 mgr->gpr[(g) - GPR_BASE].usage++; \
247 mgr->gpr[(g) - GPR_BASE].line = ln; \
248 set_bit((g) - GPR_BASE, patch->gpr_used); \
249 set_bit((g) - GPR_BASE, patch->gpr_input); \
250} while(0)
251
252#define GET_DYNAMIC_GPR(patch, g) \
253do { \
254 mgr->gpr[(g) - GPR_BASE].type = GPR_TYPE_DYNAMIC; \
255 mgr->gpr[(g) - GPR_BASE].usage++; \
256 set_bit((g) - GPR_BASE, patch->gpr_used); \
257} while(0)
258
259#define GET_CONTROL_GPR(patch, g, nm, a, b) \
260do { \
261 strcpy(mgr->gpr[(g) - GPR_BASE].name, nm); \
262 mgr->gpr[(g) - GPR_BASE].type = GPR_TYPE_CONTROL; \
263 mgr->gpr[(g) - GPR_BASE].usage++; \
264 mgr->gpr[(g) - GPR_BASE].min = a; \
265 mgr->gpr[(g) - GPR_BASE].max = b; \
266 sblive_writeptr(card, g, 0, b); \
267 set_bit((g) - GPR_BASE, patch->gpr_used); \
268} while(0)
269
270#endif /* _EFXMGR_H */
diff --git a/sound/oss/emu10k1/emuadxmg.c b/sound/oss/emu10k1/emuadxmg.c
new file mode 100644
index 000000000000..d7d2d4caf7ba
--- /dev/null
+++ b/sound/oss/emu10k1/emuadxmg.c
@@ -0,0 +1,104 @@
1
2/*
3 **********************************************************************
4 * emuadxmg.c - Address space manager for emu10k1 driver
5 * Copyright 1999, 2000 Creative Labs, Inc.
6 *
7 **********************************************************************
8 *
9 * Date Author Summary of changes
10 * ---- ------ ------------------
11 * October 20, 1999 Bertrand Lee base code release
12 *
13 **********************************************************************
14 *
15 * This program is free software; you can redistribute it and/or
16 * modify it under the terms of the GNU General Public License as
17 * published by the Free Software Foundation; either version 2 of
18 * the License, or (at your option) any later version.
19 *
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public
26 * License along with this program; if not, write to the Free
27 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139,
28 * USA.
29 *
30 **********************************************************************
31 */
32
33#include "hwaccess.h"
34
35/* Allocates emu address space */
36
37int emu10k1_addxmgr_alloc(u32 size, struct emu10k1_card *card)
38{
39 u16 *pagetable = card->emupagetable;
40 u16 index = 0;
41 u16 numpages;
42 unsigned long flags;
43
44 /* Convert bytes to pages */
45 numpages = (size / EMUPAGESIZE) + ((size % EMUPAGESIZE) ? 1 : 0);
46
47 spin_lock_irqsave(&card->lock, flags);
48
49 while (index < (MAXPAGES - 1)) {
50 if (pagetable[index] & 0x8000) {
51 /* This block of pages is in use, jump to the start of the next block. */
52 index += (pagetable[index] & 0x7fff);
53 } else {
54 /* Found free block */
55 if (pagetable[index] >= numpages) {
56
57 /* Block is large enough */
58
59 /* If free block is larger than the block requested
60 * then adjust the size of the block remaining */
61 if (pagetable[index] > numpages)
62 pagetable[index + numpages] = pagetable[index] - numpages;
63
64 pagetable[index] = (numpages | 0x8000); /* Mark block as used */
65
66 spin_unlock_irqrestore(&card->lock, flags);
67
68 return index;
69 } else {
70 /* Block too small, jump to the start of the next block */
71 index += pagetable[index];
72 }
73 }
74 }
75
76 spin_unlock_irqrestore(&card->lock, flags);
77
78 return -1;
79}
80
81/* Frees a previously allocated emu address space. */
82
83void emu10k1_addxmgr_free(struct emu10k1_card *card, int index)
84{
85 u16 *pagetable = card->emupagetable;
86 u16 origsize = 0;
87 unsigned long flags;
88
89 spin_lock_irqsave(&card->lock, flags);
90
91 if (pagetable[index] & 0x8000) {
92 /* Block is allocated - mark block as free */
93 origsize = pagetable[index] & 0x7fff;
94 pagetable[index] = origsize;
95
96 /* If next block is free, we concat both blocks */
97 if (!(pagetable[index + origsize] & 0x8000))
98 pagetable[index] += pagetable[index + origsize] & 0x7fff;
99 }
100
101 spin_unlock_irqrestore(&card->lock, flags);
102
103 return;
104}
diff --git a/sound/oss/emu10k1/hwaccess.c b/sound/oss/emu10k1/hwaccess.c
new file mode 100644
index 000000000000..2dc16a841fa1
--- /dev/null
+++ b/sound/oss/emu10k1/hwaccess.c
@@ -0,0 +1,507 @@
1/*
2 **********************************************************************
3 * hwaccess.c -- Hardware access layer
4 * Copyright 1999, 2000 Creative Labs, Inc.
5 *
6 **********************************************************************
7 *
8 * Date Author Summary of changes
9 * ---- ------ ------------------
10 * October 20, 1999 Bertrand Lee base code release
11 * December 9, 1999 Jon Taylor rewrote the I/O subsystem
12 *
13 **********************************************************************
14 *
15 * This program is free software; you can redistribute it and/or
16 * modify it under the terms of the GNU General Public License as
17 * published by the Free Software Foundation; either version 2 of
18 * the License, or (at your option) any later version.
19 *
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public
26 * License along with this program; if not, write to the Free
27 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139,
28 * USA.
29 *
30 **********************************************************************
31 */
32
33#include <asm/io.h>
34
35#include "hwaccess.h"
36#include "8010.h"
37#include "icardmid.h"
38
39/*************************************************************************
40* Function : srToPitch *
41* Input : sampleRate - sampling rate *
42* Return : pitch value *
43* About : convert sampling rate to pitch *
44* Note : for 8010, sampling rate is at 48kHz, this function should *
45* be changed. *
46*************************************************************************/
47u32 srToPitch(u32 sampleRate)
48{
49 int i;
50
51 /* FIXME: These tables should be defined in a headerfile */
52 static u32 logMagTable[128] = {
53 0x00000, 0x02dfc, 0x05b9e, 0x088e6, 0x0b5d6, 0x0e26f, 0x10eb3, 0x13aa2,
54 0x1663f, 0x1918a, 0x1bc84, 0x1e72e, 0x2118b, 0x23b9a, 0x2655d, 0x28ed5,
55 0x2b803, 0x2e0e8, 0x30985, 0x331db, 0x359eb, 0x381b6, 0x3a93d, 0x3d081,
56 0x3f782, 0x41e42, 0x444c1, 0x46b01, 0x49101, 0x4b6c4, 0x4dc49, 0x50191,
57 0x5269e, 0x54b6f, 0x57006, 0x59463, 0x5b888, 0x5dc74, 0x60029, 0x623a7,
58 0x646ee, 0x66a00, 0x68cdd, 0x6af86, 0x6d1fa, 0x6f43c, 0x7164b, 0x73829,
59 0x759d4, 0x77b4f, 0x79c9a, 0x7bdb5, 0x7dea1, 0x7ff5e, 0x81fed, 0x8404e,
60 0x86082, 0x88089, 0x8a064, 0x8c014, 0x8df98, 0x8fef1, 0x91e20, 0x93d26,
61 0x95c01, 0x97ab4, 0x9993e, 0x9b79f, 0x9d5d9, 0x9f3ec, 0xa11d8, 0xa2f9d,
62 0xa4d3c, 0xa6ab5, 0xa8808, 0xaa537, 0xac241, 0xadf26, 0xafbe7, 0xb1885,
63 0xb3500, 0xb5157, 0xb6d8c, 0xb899f, 0xba58f, 0xbc15e, 0xbdd0c, 0xbf899,
64 0xc1404, 0xc2f50, 0xc4a7b, 0xc6587, 0xc8073, 0xc9b3f, 0xcb5ed, 0xcd07c,
65 0xceaec, 0xd053f, 0xd1f73, 0xd398a, 0xd5384, 0xd6d60, 0xd8720, 0xda0c3,
66 0xdba4a, 0xdd3b4, 0xded03, 0xe0636, 0xe1f4e, 0xe384a, 0xe512c, 0xe69f3,
67 0xe829f, 0xe9b31, 0xeb3a9, 0xecc08, 0xee44c, 0xefc78, 0xf148a, 0xf2c83,
68 0xf4463, 0xf5c2a, 0xf73da, 0xf8b71, 0xfa2f0, 0xfba57, 0xfd1a7, 0xfe8df
69 };
70
71 static char logSlopeTable[128] = {
72 0x5c, 0x5c, 0x5b, 0x5a, 0x5a, 0x59, 0x58, 0x58,
73 0x57, 0x56, 0x56, 0x55, 0x55, 0x54, 0x53, 0x53,
74 0x52, 0x52, 0x51, 0x51, 0x50, 0x50, 0x4f, 0x4f,
75 0x4e, 0x4d, 0x4d, 0x4d, 0x4c, 0x4c, 0x4b, 0x4b,
76 0x4a, 0x4a, 0x49, 0x49, 0x48, 0x48, 0x47, 0x47,
77 0x47, 0x46, 0x46, 0x45, 0x45, 0x45, 0x44, 0x44,
78 0x43, 0x43, 0x43, 0x42, 0x42, 0x42, 0x41, 0x41,
79 0x41, 0x40, 0x40, 0x40, 0x3f, 0x3f, 0x3f, 0x3e,
80 0x3e, 0x3e, 0x3d, 0x3d, 0x3d, 0x3c, 0x3c, 0x3c,
81 0x3b, 0x3b, 0x3b, 0x3b, 0x3a, 0x3a, 0x3a, 0x39,
82 0x39, 0x39, 0x39, 0x38, 0x38, 0x38, 0x38, 0x37,
83 0x37, 0x37, 0x37, 0x36, 0x36, 0x36, 0x36, 0x35,
84 0x35, 0x35, 0x35, 0x34, 0x34, 0x34, 0x34, 0x34,
85 0x33, 0x33, 0x33, 0x33, 0x32, 0x32, 0x32, 0x32,
86 0x32, 0x31, 0x31, 0x31, 0x31, 0x31, 0x30, 0x30,
87 0x30, 0x30, 0x30, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f
88 };
89
90 if (sampleRate == 0)
91 return 0; /* Bail out if no leading "1" */
92
93 sampleRate *= 11185; /* Scale 48000 to 0x20002380 */
94
95 for (i = 31; i > 0; i--) {
96 if (sampleRate & 0x80000000) { /* Detect leading "1" */
97 return (u32) (((s32) (i - 15) << 20) +
98 logMagTable[0x7f & (sampleRate >> 24)] +
99 (0x7f & (sampleRate >> 17)) * logSlopeTable[0x7f & (sampleRate >> 24)]);
100 }
101 sampleRate = sampleRate << 1;
102 }
103
104 DPF(2, "srToPitch: BUG!\n");
105 return 0; /* Should never reach this point */
106}
107
108/*******************************************
109* write/read PCI function 0 registers *
110********************************************/
111void emu10k1_writefn0(struct emu10k1_card *card, u32 reg, u32 data)
112{
113 unsigned long flags;
114
115 if (reg & 0xff000000) {
116 u32 mask;
117 u8 size, offset;
118
119 size = (reg >> 24) & 0x3f;
120 offset = (reg >> 16) & 0x1f;
121 mask = ((1 << size) - 1) << offset;
122 data = (data << offset) & mask;
123 reg &= 0x7f;
124
125 spin_lock_irqsave(&card->lock, flags);
126 data |= inl(card->iobase + reg) & ~mask;
127 outl(data, card->iobase + reg);
128 spin_unlock_irqrestore(&card->lock, flags);
129 } else {
130 spin_lock_irqsave(&card->lock, flags);
131 outl(data, card->iobase + reg);
132 spin_unlock_irqrestore(&card->lock, flags);
133 }
134
135 return;
136}
137
138#ifdef DBGEMU
139void emu10k1_writefn0_2(struct emu10k1_card *card, u32 reg, u32 data, int size)
140{
141 unsigned long flags;
142
143 spin_lock_irqsave(&card->lock, flags);
144
145 if (size == 32)
146 outl(data, card->iobase + (reg & 0x1F));
147 else if (size == 16)
148 outw(data, card->iobase + (reg & 0x1F));
149 else
150 outb(data, card->iobase + (reg & 0x1F));
151
152 spin_unlock_irqrestore(&card->lock, flags);
153
154 return;
155}
156#endif /* DBGEMU */
157
158u32 emu10k1_readfn0(struct emu10k1_card * card, u32 reg)
159{
160 u32 val;
161 unsigned long flags;
162
163 if (reg & 0xff000000) {
164 u32 mask;
165 u8 size, offset;
166
167 size = (reg >> 24) & 0x3f;
168 offset = (reg >> 16) & 0x1f;
169 mask = ((1 << size) - 1) << offset;
170 reg &= 0x7f;
171
172 spin_lock_irqsave(&card->lock, flags);
173 val = inl(card->iobase + reg);
174 spin_unlock_irqrestore(&card->lock, flags);
175
176 return (val & mask) >> offset;
177 } else {
178 spin_lock_irqsave(&card->lock, flags);
179 val = inl(card->iobase + reg);
180 spin_unlock_irqrestore(&card->lock, flags);
181 return val;
182 }
183}
184
185void emu10k1_timer_set(struct emu10k1_card * card, u16 data)
186{
187 unsigned long flags;
188
189 spin_lock_irqsave(&card->lock, flags);
190 outw(data & TIMER_RATE_MASK, card->iobase + TIMER);
191 spin_unlock_irqrestore(&card->lock, flags);
192}
193
194/************************************************************************
195* write/read Emu10k1 pointer-offset register set, accessed through *
196* the PTR and DATA registers *
197*************************************************************************/
198#define A_PTR_ADDRESS_MASK 0x0fff0000
199void sblive_writeptr(struct emu10k1_card *card, u32 reg, u32 channel, u32 data)
200{
201 u32 regptr;
202 unsigned long flags;
203
204 regptr = ((reg << 16) & A_PTR_ADDRESS_MASK) | (channel & PTR_CHANNELNUM_MASK);
205
206 if (reg & 0xff000000) {
207 u32 mask;
208 u8 size, offset;
209
210 size = (reg >> 24) & 0x3f;
211 offset = (reg >> 16) & 0x1f;
212 mask = ((1 << size) - 1) << offset;
213 data = (data << offset) & mask;
214
215 spin_lock_irqsave(&card->lock, flags);
216 outl(regptr, card->iobase + PTR);
217 data |= inl(card->iobase + DATA) & ~mask;
218 outl(data, card->iobase + DATA);
219 spin_unlock_irqrestore(&card->lock, flags);
220 } else {
221 spin_lock_irqsave(&card->lock, flags);
222 outl(regptr, card->iobase + PTR);
223 outl(data, card->iobase + DATA);
224 spin_unlock_irqrestore(&card->lock, flags);
225 }
226}
227
228/* ... : data, reg, ... , TAGLIST_END */
229void sblive_writeptr_tag(struct emu10k1_card *card, u32 channel, ...)
230{
231 va_list args;
232
233 unsigned long flags;
234 u32 reg;
235
236 va_start(args, channel);
237
238 spin_lock_irqsave(&card->lock, flags);
239 while ((reg = va_arg(args, u32)) != TAGLIST_END) {
240 u32 data = va_arg(args, u32);
241 u32 regptr = (((reg << 16) & A_PTR_ADDRESS_MASK)
242 | (channel & PTR_CHANNELNUM_MASK));
243 outl(regptr, card->iobase + PTR);
244 if (reg & 0xff000000) {
245 int size = (reg >> 24) & 0x3f;
246 int offset = (reg >> 16) & 0x1f;
247 u32 mask = ((1 << size) - 1) << offset;
248 data = (data << offset) & mask;
249
250 data |= inl(card->iobase + DATA) & ~mask;
251 }
252 outl(data, card->iobase + DATA);
253 }
254 spin_unlock_irqrestore(&card->lock, flags);
255
256 va_end(args);
257
258 return;
259}
260
261u32 sblive_readptr(struct emu10k1_card * card, u32 reg, u32 channel)
262{
263 u32 regptr, val;
264 unsigned long flags;
265
266 regptr = ((reg << 16) & A_PTR_ADDRESS_MASK) | (channel & PTR_CHANNELNUM_MASK);
267
268 if (reg & 0xff000000) {
269 u32 mask;
270 u8 size, offset;
271
272 size = (reg >> 24) & 0x3f;
273 offset = (reg >> 16) & 0x1f;
274 mask = ((1 << size) - 1) << offset;
275
276 spin_lock_irqsave(&card->lock, flags);
277 outl(regptr, card->iobase + PTR);
278 val = inl(card->iobase + DATA);
279 spin_unlock_irqrestore(&card->lock, flags);
280
281 return (val & mask) >> offset;
282 } else {
283 spin_lock_irqsave(&card->lock, flags);
284 outl(regptr, card->iobase + PTR);
285 val = inl(card->iobase + DATA);
286 spin_unlock_irqrestore(&card->lock, flags);
287
288 return val;
289 }
290}
291
292void emu10k1_irq_enable(struct emu10k1_card *card, u32 irq_mask)
293{
294 u32 val;
295 unsigned long flags;
296
297 DPF(2,"emu10k1_irq_enable()\n");
298
299 spin_lock_irqsave(&card->lock, flags);
300 val = inl(card->iobase + INTE) | irq_mask;
301 outl(val, card->iobase + INTE);
302 spin_unlock_irqrestore(&card->lock, flags);
303 return;
304}
305
306void emu10k1_irq_disable(struct emu10k1_card *card, u32 irq_mask)
307{
308 u32 val;
309 unsigned long flags;
310
311 DPF(2,"emu10k1_irq_disable()\n");
312
313 spin_lock_irqsave(&card->lock, flags);
314 val = inl(card->iobase + INTE) & ~irq_mask;
315 outl(val, card->iobase + INTE);
316 spin_unlock_irqrestore(&card->lock, flags);
317 return;
318}
319
320void emu10k1_clear_stop_on_loop(struct emu10k1_card *card, u32 voicenum)
321{
322 /* Voice interrupt */
323 if (voicenum >= 32)
324 sblive_writeptr(card, SOLEH | ((0x0100 | (voicenum - 32)) << 16), 0, 0);
325 else
326 sblive_writeptr(card, SOLEL | ((0x0100 | voicenum) << 16), 0, 0);
327
328 return;
329}
330
331static void sblive_wcwait(struct emu10k1_card *card, u32 wait)
332{
333 volatile unsigned uCount;
334 u32 newtime = 0, curtime;
335
336 curtime = emu10k1_readfn0(card, WC_SAMPLECOUNTER);
337 while (wait--) {
338 uCount = 0;
339 while (uCount++ < TIMEOUT) {
340 newtime = emu10k1_readfn0(card, WC_SAMPLECOUNTER);
341 if (newtime != curtime)
342 break;
343 }
344
345 if (uCount >= TIMEOUT)
346 break;
347
348 curtime = newtime;
349 }
350}
351
352u16 emu10k1_ac97_read(struct ac97_codec *codec, u8 reg)
353{
354 struct emu10k1_card *card = codec->private_data;
355 u16 data;
356 unsigned long flags;
357
358 spin_lock_irqsave(&card->lock, flags);
359
360 outb(reg, card->iobase + AC97ADDRESS);
361 data = inw(card->iobase + AC97DATA);
362
363 spin_unlock_irqrestore(&card->lock, flags);
364
365 return data;
366}
367
368void emu10k1_ac97_write(struct ac97_codec *codec, u8 reg, u16 value)
369{
370 struct emu10k1_card *card = codec->private_data;
371 unsigned long flags;
372
373 spin_lock_irqsave(&card->lock, flags);
374
375 outb(reg, card->iobase + AC97ADDRESS);
376 outw(value, card->iobase + AC97DATA);
377 outb( AC97_EXTENDED_ID, card->iobase + AC97ADDRESS);
378 spin_unlock_irqrestore(&card->lock, flags);
379}
380
381/*********************************************************
382* MPU access functions *
383**********************************************************/
384
385int emu10k1_mpu_write_data(struct emu10k1_card *card, u8 data)
386{
387 unsigned long flags;
388 int ret;
389
390 if (card->is_audigy) {
391 if ((sblive_readptr(card, A_MUSTAT,0) & MUSTAT_ORDYN) == 0) {
392 sblive_writeptr(card, A_MUDATA, 0, data);
393 ret = 0;
394 } else
395 ret = -1;
396 } else {
397 spin_lock_irqsave(&card->lock, flags);
398
399 if ((inb(card->iobase + MUSTAT) & MUSTAT_ORDYN) == 0) {
400 outb(data, card->iobase + MUDATA);
401 ret = 0;
402 } else
403 ret = -1;
404
405 spin_unlock_irqrestore(&card->lock, flags);
406 }
407
408 return ret;
409}
410
411int emu10k1_mpu_read_data(struct emu10k1_card *card, u8 * data)
412{
413 unsigned long flags;
414 int ret;
415
416 if (card->is_audigy) {
417 if ((sblive_readptr(card, A_MUSTAT,0) & MUSTAT_IRDYN) == 0) {
418 *data = sblive_readptr(card, A_MUDATA,0);
419 ret = 0;
420 } else
421 ret = -1;
422 } else {
423 spin_lock_irqsave(&card->lock, flags);
424
425 if ((inb(card->iobase + MUSTAT) & MUSTAT_IRDYN) == 0) {
426 *data = inb(card->iobase + MUDATA);
427 ret = 0;
428 } else
429 ret = -1;
430
431 spin_unlock_irqrestore(&card->lock, flags);
432 }
433
434 return ret;
435}
436
437int emu10k1_mpu_reset(struct emu10k1_card *card)
438{
439 u8 status;
440 unsigned long flags;
441
442 DPF(2, "emu10k1_mpu_reset()\n");
443 if (card->is_audigy) {
444 if (card->mpuacqcount == 0) {
445 sblive_writeptr(card, A_MUCMD, 0, MUCMD_RESET);
446 sblive_wcwait(card, 8);
447 sblive_writeptr(card, A_MUCMD, 0, MUCMD_RESET);
448 sblive_wcwait(card, 8);
449 sblive_writeptr(card, A_MUCMD, 0, MUCMD_ENTERUARTMODE);
450 sblive_wcwait(card, 8);
451 status = sblive_readptr(card, A_MUDATA, 0);
452 if (status == 0xfe)
453 return 0;
454 else
455 return -1;
456 }
457
458 return 0;
459 } else {
460 if (card->mpuacqcount == 0) {
461 spin_lock_irqsave(&card->lock, flags);
462 outb(MUCMD_RESET, card->iobase + MUCMD);
463 spin_unlock_irqrestore(&card->lock, flags);
464
465 sblive_wcwait(card, 8);
466
467 spin_lock_irqsave(&card->lock, flags);
468 outb(MUCMD_RESET, card->iobase + MUCMD);
469 spin_unlock_irqrestore(&card->lock, flags);
470
471 sblive_wcwait(card, 8);
472
473 spin_lock_irqsave(&card->lock, flags);
474 outb(MUCMD_ENTERUARTMODE, card->iobase + MUCMD);
475 spin_unlock_irqrestore(&card->lock, flags);
476
477 sblive_wcwait(card, 8);
478
479 spin_lock_irqsave(&card->lock, flags);
480 status = inb(card->iobase + MUDATA);
481 spin_unlock_irqrestore(&card->lock, flags);
482
483 if (status == 0xfe)
484 return 0;
485 else
486 return -1;
487 }
488
489 return 0;
490 }
491}
492
493int emu10k1_mpu_acquire(struct emu10k1_card *card)
494{
495 /* FIXME: This should be a macro */
496 ++card->mpuacqcount;
497
498 return 0;
499}
500
501int emu10k1_mpu_release(struct emu10k1_card *card)
502{
503 /* FIXME: this should be a macro */
504 --card->mpuacqcount;
505
506 return 0;
507}
diff --git a/sound/oss/emu10k1/hwaccess.h b/sound/oss/emu10k1/hwaccess.h
new file mode 100644
index 000000000000..104223a192aa
--- /dev/null
+++ b/sound/oss/emu10k1/hwaccess.h
@@ -0,0 +1,247 @@
1/*
2 **********************************************************************
3 * hwaccess.h
4 * Copyright 1999, 2000 Creative Labs, Inc.
5 *
6 **********************************************************************
7 *
8 * Date Author Summary of changes
9 * ---- ------ ------------------
10 * October 20, 1999 Bertrand Lee base code release
11 *
12 **********************************************************************
13 *
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License as
16 * published by the Free Software Foundation; either version 2 of
17 * the License, or (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public
25 * License along with this program; if not, write to the Free
26 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139,
27 * USA.
28 *
29 **********************************************************************
30 */
31
32#ifndef _HWACCESS_H
33#define _HWACCESS_H
34
35#include <linux/fs.h>
36#include <linux/sound.h>
37#include <linux/soundcard.h>
38#include <linux/ac97_codec.h>
39#include <linux/pci.h>
40#include <linux/slab.h>
41#include <linux/sched.h>
42#include <asm/io.h>
43
44#include "efxmgr.h"
45#include "passthrough.h"
46#include "midi.h"
47
48#define EMUPAGESIZE 4096 /* don't change */
49#define NUM_G 64 /* use all channels */
50#define NUM_FXSENDS 4 /* don't change */
51/* setting this to other than a power of two may break some applications */
52#define MAXBUFSIZE 65536
53#define MAXPAGES 8192
54#define BUFMAXPAGES (MAXBUFSIZE / PAGE_SIZE)
55
56#define FLAGS_AVAILABLE 0x0001
57#define FLAGS_READY 0x0002
58
59struct memhandle
60{
61 dma_addr_t dma_handle;
62 void *addr;
63 u32 size;
64};
65
66#define DEBUG_LEVEL 2
67
68#ifdef EMU10K1_DEBUG
69# define DPD(level,x,y...) do {if(level <= DEBUG_LEVEL) printk( KERN_NOTICE "emu10k1: %s: %d: " x , __FILE__ , __LINE__ , y );} while(0)
70# define DPF(level,x) do {if(level <= DEBUG_LEVEL) printk( KERN_NOTICE "emu10k1: %s: %d: " x , __FILE__ , __LINE__ );} while(0)
71#else
72# define DPD(level,x,y...) do { } while (0) /* not debugging: nothing */
73# define DPF(level,x) do { } while (0)
74#endif /* EMU10K1_DEBUG */
75
76#define ERROR() DPF(1,"error\n")
77
78/* DATA STRUCTURES */
79
80struct emu10k1_waveout
81{
82 u32 send_routing[3];
83 // audigy only:
84 u32 send_routing2[3];
85
86 u32 send_dcba[3];
87 // audigy only:
88 u32 send_hgfe[3];
89};
90#define ROUTE_PCM 0
91#define ROUTE_PT 1
92#define ROUTE_PCM1 2
93
94#define SEND_MONO 0
95#define SEND_LEFT 1
96#define SEND_RIGHT 2
97
98struct emu10k1_wavein
99{
100 struct wiinst *ac97;
101 struct wiinst *mic;
102 struct wiinst *fx;
103
104 u8 recsrc;
105 u32 fxwc;
106};
107
108#define CMD_READ 1
109#define CMD_WRITE 2
110
111struct mixer_private_ioctl {
112 u32 cmd;
113 u32 val[90];
114};
115
116/* bogus ioctls numbers to escape from OSS mixer limitations */
117#define CMD_WRITEFN0 _IOW('D', 0, struct mixer_private_ioctl)
118#define CMD_READFN0 _IOR('D', 1, struct mixer_private_ioctl)
119#define CMD_WRITEPTR _IOW('D', 2, struct mixer_private_ioctl)
120#define CMD_READPTR _IOR('D', 3, struct mixer_private_ioctl)
121#define CMD_SETRECSRC _IOW('D', 4, struct mixer_private_ioctl)
122#define CMD_GETRECSRC _IOR('D', 5, struct mixer_private_ioctl)
123#define CMD_GETVOICEPARAM _IOR('D', 6, struct mixer_private_ioctl)
124#define CMD_SETVOICEPARAM _IOW('D', 7, struct mixer_private_ioctl)
125#define CMD_GETPATCH _IOR('D', 8, struct mixer_private_ioctl)
126#define CMD_GETGPR _IOR('D', 9, struct mixer_private_ioctl)
127#define CMD_GETCTLGPR _IOR('D', 10, struct mixer_private_ioctl)
128#define CMD_SETPATCH _IOW('D', 11, struct mixer_private_ioctl)
129#define CMD_SETGPR _IOW('D', 12, struct mixer_private_ioctl)
130#define CMD_SETCTLGPR _IOW('D', 13, struct mixer_private_ioctl)
131#define CMD_SETGPOUT _IOW('D', 14, struct mixer_private_ioctl)
132#define CMD_GETGPR2OSS _IOR('D', 15, struct mixer_private_ioctl)
133#define CMD_SETGPR2OSS _IOW('D', 16, struct mixer_private_ioctl)
134#define CMD_SETMCH_FX _IOW('D', 17, struct mixer_private_ioctl)
135#define CMD_SETPASSTHROUGH _IOW('D', 18, struct mixer_private_ioctl)
136#define CMD_PRIVATE3_VERSION _IOW('D', 19, struct mixer_private_ioctl)
137#define CMD_AC97_BOOST _IOW('D', 20, struct mixer_private_ioctl)
138
139//up this number when breaking compatibility
140#define PRIVATE3_VERSION 2
141
142struct emu10k1_card
143{
144 struct list_head list;
145
146 struct memhandle virtualpagetable;
147 struct memhandle tankmem;
148 struct memhandle silentpage;
149
150 spinlock_t lock;
151
152 u8 voicetable[NUM_G];
153 u16 emupagetable[MAXPAGES];
154
155 struct list_head timers;
156 u16 timer_delay;
157 spinlock_t timer_lock;
158
159 struct pci_dev *pci_dev;
160 unsigned long iobase;
161 unsigned long length;
162 unsigned short model;
163 unsigned int irq;
164
165 int audio_dev;
166 int audio_dev1;
167 int midi_dev;
168#ifdef EMU10K1_SEQUENCER
169 int seq_dev;
170 struct emu10k1_mididevice *seq_mididev;
171#endif
172
173 struct ac97_codec *ac97;
174 int ac97_supported_mixers;
175 int ac97_stereo_mixers;
176
177 /* Number of first fx voice for multichannel output */
178 u8 mchannel_fx;
179 struct emu10k1_waveout waveout;
180 struct emu10k1_wavein wavein;
181 struct emu10k1_mpuout *mpuout;
182 struct emu10k1_mpuin *mpuin;
183
184 struct semaphore open_sem;
185 mode_t open_mode;
186 wait_queue_head_t open_wait;
187
188 u32 mpuacqcount; // Mpu acquire count
189 u32 has_toslink; // TOSLink detection
190
191 u8 chiprev; /* Chip revision */
192 u8 is_audigy;
193 u8 is_aps;
194
195 struct patch_manager mgr;
196 struct pt_data pt;
197};
198
199int emu10k1_addxmgr_alloc(u32, struct emu10k1_card *);
200void emu10k1_addxmgr_free(struct emu10k1_card *, int);
201
202int emu10k1_find_control_gpr(struct patch_manager *, const char *, const char *);
203void emu10k1_set_control_gpr(struct emu10k1_card *, int , s32, int );
204
205void emu10k1_set_volume_gpr(struct emu10k1_card *, int, s32, int);
206
207
208#define VOL_6BIT 0x40
209#define VOL_5BIT 0x20
210#define VOL_4BIT 0x10
211
212#define TIMEOUT 16384
213
214u32 srToPitch(u32);
215
216extern struct list_head emu10k1_devs;
217
218/* Hardware Abstraction Layer access functions */
219
220void emu10k1_writefn0(struct emu10k1_card *, u32, u32);
221void emu10k1_writefn0_2(struct emu10k1_card *, u32, u32, int);
222u32 emu10k1_readfn0(struct emu10k1_card *, u32);
223
224void emu10k1_timer_set(struct emu10k1_card *, u16);
225
226void sblive_writeptr(struct emu10k1_card *, u32, u32, u32);
227void sblive_writeptr_tag(struct emu10k1_card *, u32, ...);
228#define TAGLIST_END 0
229
230u32 sblive_readptr(struct emu10k1_card *, u32 , u32 );
231
232void emu10k1_irq_enable(struct emu10k1_card *, u32);
233void emu10k1_irq_disable(struct emu10k1_card *, u32);
234void emu10k1_clear_stop_on_loop(struct emu10k1_card *, u32);
235
236/* AC97 Codec register access function */
237u16 emu10k1_ac97_read(struct ac97_codec *, u8);
238void emu10k1_ac97_write(struct ac97_codec *, u8, u16);
239
240/* MPU access function*/
241int emu10k1_mpu_write_data(struct emu10k1_card *, u8);
242int emu10k1_mpu_read_data(struct emu10k1_card *, u8 *);
243int emu10k1_mpu_reset(struct emu10k1_card *);
244int emu10k1_mpu_acquire(struct emu10k1_card *);
245int emu10k1_mpu_release(struct emu10k1_card *);
246
247#endif /* _HWACCESS_H */
diff --git a/sound/oss/emu10k1/icardmid.h b/sound/oss/emu10k1/icardmid.h
new file mode 100644
index 000000000000..6a6ef419401f
--- /dev/null
+++ b/sound/oss/emu10k1/icardmid.h
@@ -0,0 +1,163 @@
1/*
2 **********************************************************************
3 * isblive_mid.h
4 * Copyright 1999, 2000 Creative Labs, Inc.
5 *
6 **********************************************************************
7 *
8 * Date Author Summary of changes
9 * ---- ------ ------------------
10 * October 20, 1999 Bertrand Lee base code release
11 *
12 **********************************************************************
13 *
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License as
16 * published by the Free Software Foundation; either version 2 of
17 * the License, or (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public
25 * License along with this program; if not, write to the Free
26 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139,
27 * USA.
28 *
29 **********************************************************************
30 */
31
32#ifndef _ICARDMIDI_H
33#define _ICARDMIDI_H
34
35/* MIDI defines */
36#define MIDI_DATA_FIRST 0x00
37#define MIDI_DATA_LAST 0x7F
38#define MIDI_STATUS_FIRST 0x80
39#define MIDI_STATUS_LAST 0xFF
40
41/* Channel status bytes */
42#define MIDI_STATUS_CHANNEL_FIRST 0x80
43#define MIDI_STATUS_CHANNEL_LAST 0xE0
44#define MIDI_STATUS_CHANNEL_MASK 0xF0
45
46/* Channel voice messages */
47#define MIDI_VOICE_NOTE_OFF 0x80
48#define MIDI_VOICE_NOTE_ON 0x90
49#define MIDI_VOICE_POLY_PRESSURE 0xA0
50#define MIDI_VOICE_CONTROL_CHANGE 0xB0
51#define MIDI_VOICE_PROGRAM_CHANGE 0xC0
52#define MIDI_VOICE_CHANNEL_PRESSURE 0xD0
53#define MIDI_VOICE_PITCH_BEND 0xE0
54
55/* Channel mode messages */
56#define MIDI_MODE_CHANNEL MIDI_VOICE_CONTROL_CHANGE
57
58/* System status bytes */
59#define MIDI_STATUS_SYSTEM_FIRST 0xF0
60#define MIDI_STATUS_SYSTEM_LAST 0xFF
61
62/* System exclusive messages */
63#define MIDI_SYSEX_BEGIN 0xF0
64#define MIDI_SYSEX_EOX 0xF7
65
66/* System common messages */
67#define MIDI_COMMON_TCQF 0xF1 /* Time code quarter frame */
68#define MIDI_COMMON_SONG_POSITION 0xF2
69#define MIDI_COMMON_SONG_SELECT 0xF3
70#define MIDI_COMMON_UNDEFINED_F4 0xF4
71#define MIDI_COMMON_UNDEFINED_F5 0xF5
72#define MIDI_COMMON_TUNE_REQUEST 0xF6
73
74/* System real-time messages */
75#define MIDI_RTIME_TIMING_CLOCK 0xF8
76#define MIDI_RTIME_UNDEFINED_F9 0xF9
77#define MIDI_RTIME_START 0xFA
78#define MIDI_RTIME_CONTINUE 0xFB
79#define MIDI_RTIME_STOP 0xFC
80#define MIDI_RTIME_UNDEFINED_FD 0xFD
81#define MIDI_RTIME_ACTIVE_SENSING 0xFE
82#define MIDI_RTIME_SYSTEM_RESET 0xFF
83
84/* Flags for flags parm of midiOutCachePatches(), midiOutCacheDrumPatches() */
85#define MIDI_CACHE_ALL 1
86#define MIDI_CACHE_BESTFIT 2
87#define MIDI_CACHE_QUERY 3
88#define MIDI_UNCACHE 4
89
90/* Event declarations for MPU IRQ Callbacks */
91#define ICARDMIDI_INLONGDATA 0x00000001 /* MIM_LONGDATA */
92#define ICARDMIDI_INLONGERROR 0x00000002 /* MIM_LONGERROR */
93#define ICARDMIDI_OUTLONGDATA 0x00000004 /* MOM_DONE for MPU OUT buffer */
94#define ICARDMIDI_INDATA 0x00000010 /* MIM_DATA */
95#define ICARDMIDI_INDATAERROR 0x00000020 /* MIM_ERROR */
96
97/* Declaration for flags in CARDMIDIBUFFERHDR */
98/* Make it the same as MHDR_DONE, MHDR_INQUEUE in mmsystem.h */
99#define MIDIBUF_DONE 0x00000001
100#define MIDIBUF_INQUEUE 0x00000004
101
102/* Declaration for msg parameter in midiCallbackFn */
103#define ICARDMIDI_OUTBUFFEROK 0x00000001
104#define ICARDMIDI_INMIDIOK 0x00000002
105
106/* Declaration for technology in struct midi_caps */
107#define MT_MIDIPORT 0x00000001 /* In original MIDIOUTCAPS structure */
108#define MT_FMSYNTH 0x00000004 /* In original MIDIOUTCAPS structure */
109#define MT_AWESYNTH 0x00001000
110#define MT_PCISYNTH 0x00002000
111#define MT_PCISYNTH64 0x00004000
112#define CARDMIDI_AWEMASK 0x0000F000
113
114enum LocalErrorCode
115{
116 CTSTATUS_NOTENABLED = 0x7000,
117 CTSTATUS_READY,
118 CTSTATUS_BUSY,
119 CTSTATUS_DATAAVAIL,
120 CTSTATUS_NODATA,
121 CTSTATUS_NEXT_BYTE
122};
123
124/* MIDI data block header */
125struct midi_hdr
126{
127 u8 *reserved; /* Pointer to original locked data block */
128 u32 bufferlength; /* Length of data in data block */
129 u32 bytesrecorded; /* Used for input only */
130 u32 user; /* For client's use */
131 u32 flags; /* Assorted flags (see defines) */
132 struct list_head list; /* Reserved for driver */
133 u8 *data; /* Second copy of first pointer */
134};
135
136/* Enumeration for SetControl */
137enum
138{
139 MIDIOBJVOLUME = 0x1,
140 MIDIQUERYACTIVEINST
141};
142
143struct midi_queue
144{
145 struct midi_queue *next;
146 u32 qtype; /* 0 = short message, 1 = long data */
147 u32 length;
148 u32 sizeLeft;
149 u8 *midibyte;
150 unsigned long refdata;
151};
152
153struct midi_openinfo
154{
155 u32 cbsize;
156 u32 flags;
157 unsigned long refdata;
158 u32 streamid;
159};
160
161int emu10k1_midi_callback(unsigned long , unsigned long, unsigned long *);
162
163#endif /* _ICARDMIDI_H */
diff --git a/sound/oss/emu10k1/icardwav.h b/sound/oss/emu10k1/icardwav.h
new file mode 100644
index 000000000000..25be40928b4d
--- /dev/null
+++ b/sound/oss/emu10k1/icardwav.h
@@ -0,0 +1,53 @@
1/*
2 **********************************************************************
3 * icardwav.h
4 * Copyright 1999, 2000 Creative Labs, Inc.
5 *
6 **********************************************************************
7 *
8 * Date Author Summary of changes
9 * ---- ------ ------------------
10 * October 20, 1999 Bertrand Lee base code release
11 *
12 **********************************************************************
13 *
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License as
16 * published by the Free Software Foundation; either version 2 of
17 * the License, or (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public
25 * License along with this program; if not, write to the Free
26 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139,
27 * USA.
28 *
29 **********************************************************************
30 */
31
32#ifndef _ICARDWAV_H
33#define _ICARDWAV_H
34
35struct wave_format
36{
37 int id;
38 int samplingrate;
39 u8 bitsperchannel;
40 u8 channels; /* 1 = Mono, 2 = Stereo, 3, ... = Multichannel */
41 u8 bytesperchannel;
42 u8 bytespervoicesample;
43 u8 bytespersample;
44 int bytespersec;
45 u8 passthrough;
46};
47
48/* emu10k1_wave states */
49#define WAVE_STATE_OPEN 0x01
50#define WAVE_STATE_STARTED 0x02
51#define WAVE_STATE_CLOSED 0x04
52
53#endif /* _ICARDWAV_H */
diff --git a/sound/oss/emu10k1/irqmgr.c b/sound/oss/emu10k1/irqmgr.c
new file mode 100644
index 000000000000..d19b464ba01b
--- /dev/null
+++ b/sound/oss/emu10k1/irqmgr.c
@@ -0,0 +1,113 @@
1/*
2 **********************************************************************
3 * irqmgr.c - IRQ manager for emu10k1 driver
4 * Copyright 1999, 2000 Creative Labs, Inc.
5 *
6 **********************************************************************
7 *
8 * Date Author Summary of changes
9 * ---- ------ ------------------
10 * October 20, 1999 Bertrand Lee base code release
11 *
12 **********************************************************************
13 *
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License as
16 * published by the Free Software Foundation; either version 2 of
17 * the License, or (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public
25 * License along with this program; if not, write to the Free
26 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139,
27 * USA.
28 *
29 **********************************************************************
30 */
31
32#include "hwaccess.h"
33#include "8010.h"
34#include "cardmi.h"
35#include "cardmo.h"
36#include "irqmgr.h"
37
38/* Interrupt handler */
39
40irqreturn_t emu10k1_interrupt(int irq, void *dev_id, struct pt_regs *regs)
41{
42 struct emu10k1_card *card = (struct emu10k1_card *) dev_id;
43 u32 irqstatus, irqstatus_tmp;
44 int handled = 0;
45
46 DPD(4, "emu10k1_interrupt called, irq = %u\n", irq);
47
48 /*
49 ** NOTE :
50 ** We do a 'while loop' here cos on certain machines, with both
51 ** playback and recording going on at the same time, IRQs will
52 ** stop coming in after a while. Checking IPND indeed shows that
53 ** there are interrupts pending but the PIC says no IRQs pending.
54 ** I suspect that some boards need edge-triggered IRQs but are not
55 ** getting that condition if we don't completely clear the IPND
56 ** (make sure no more interrupts are pending).
57 ** - Eric
58 */
59
60 while ((irqstatus = inl(card->iobase + IPR))) {
61 DPD(4, "irq status %#x\n", irqstatus);
62
63 irqstatus_tmp = irqstatus;
64
65 if (irqstatus & IRQTYPE_TIMER) {
66 emu10k1_timer_irqhandler(card);
67 irqstatus &= ~IRQTYPE_TIMER;
68 }
69
70 if (irqstatus & IRQTYPE_DSP) {
71 emu10k1_dsp_irqhandler(card);
72 irqstatus &= ~IRQTYPE_DSP;
73 }
74
75 if (irqstatus & IRQTYPE_MPUIN) {
76 emu10k1_mpuin_irqhandler(card);
77 irqstatus &= ~IRQTYPE_MPUIN;
78 }
79
80 if (irqstatus & IRQTYPE_MPUOUT) {
81 emu10k1_mpuout_irqhandler(card);
82 irqstatus &= ~IRQTYPE_MPUOUT;
83 }
84
85 if (irqstatus & IPR_MUTE) {
86 emu10k1_mute_irqhandler(card);
87 irqstatus &=~IPR_MUTE;
88 }
89
90 if (irqstatus & IPR_VOLINCR) {
91 emu10k1_volincr_irqhandler(card);
92 irqstatus &=~IPR_VOLINCR;
93 }
94
95 if (irqstatus & IPR_VOLDECR) {
96 emu10k1_voldecr_irqhandler(card);
97 irqstatus &=~IPR_VOLDECR;
98 }
99
100 if (irqstatus){
101 printk(KERN_ERR "emu10k1: Warning, unhandled interrupt: %#08x\n", irqstatus);
102 //make sure any interrupts we don't handle are disabled:
103 emu10k1_irq_disable(card, ~(INTE_MIDIRXENABLE | INTE_MIDITXENABLE | INTE_INTERVALTIMERENB |
104 INTE_VOLDECRENABLE | INTE_VOLINCRENABLE | INTE_MUTEENABLE |
105 INTE_FXDSPENABLE));
106 }
107
108 /* acknowledge interrupt */
109 outl(irqstatus_tmp, card->iobase + IPR);
110 handled = 1;
111 }
112 return IRQ_RETVAL(handled);
113}
diff --git a/sound/oss/emu10k1/irqmgr.h b/sound/oss/emu10k1/irqmgr.h
new file mode 100644
index 000000000000..7e7c9ca1098c
--- /dev/null
+++ b/sound/oss/emu10k1/irqmgr.h
@@ -0,0 +1,52 @@
1/*
2 **********************************************************************
3 * irq.h
4 * Copyright 1999, 2000 Creative Labs, Inc.
5 *
6 **********************************************************************
7 *
8 * Date Author Summary of changes
9 * ---- ------ ------------------
10 * October 20, 1999 Bertrand Lee base code release
11 *
12 **********************************************************************
13 *
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License as
16 * published by the Free Software Foundation; either version 2 of
17 * the License, or (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public
25 * License along with this program; if not, write to the Free
26 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139,
27 * USA.
28 *
29 **********************************************************************
30 */
31
32#ifndef _IRQ_H
33#define _IRQ_H
34
35/* EMU Irq Types */
36#define IRQTYPE_PCIBUSERROR IPR_PCIERROR
37#define IRQTYPE_MIXERBUTTON (IPR_VOLINCR | IPR_VOLDECR | IPR_MUTE)
38#define IRQTYPE_VOICE (IPR_CHANNELLOOP | IPR_CHANNELNUMBERMASK)
39#define IRQTYPE_RECORD (IPR_ADCBUFFULL | IPR_ADCBUFHALFFULL | IPR_MICBUFFULL | IPR_MICBUFHALFFULL | IPR_EFXBUFFULL | IPR_EFXBUFHALFFULL)
40#define IRQTYPE_MPUOUT (IPR_MIDITRANSBUFEMPTY | A_IPR_MIDITRANSBUFEMPTY2)
41#define IRQTYPE_MPUIN (IPR_MIDIRECVBUFEMPTY | A_IPR_MIDIRECVBUFEMPTY2)
42#define IRQTYPE_TIMER IPR_INTERVALTIMER
43#define IRQTYPE_SPDIF (IPR_GPSPDIFSTATUSCHANGE | IPR_CDROMSTATUSCHANGE)
44#define IRQTYPE_DSP IPR_FXDSP
45
46void emu10k1_timer_irqhandler(struct emu10k1_card *);
47void emu10k1_dsp_irqhandler(struct emu10k1_card *);
48void emu10k1_mute_irqhandler(struct emu10k1_card *);
49void emu10k1_volincr_irqhandler(struct emu10k1_card *);
50void emu10k1_voldecr_irqhandler(struct emu10k1_card *);
51
52#endif /* _IRQ_H */
diff --git a/sound/oss/emu10k1/main.c b/sound/oss/emu10k1/main.c
new file mode 100644
index 000000000000..9b905bae423e
--- /dev/null
+++ b/sound/oss/emu10k1/main.c
@@ -0,0 +1,1475 @@
1 /*
2 **********************************************************************
3 * main.c - Creative EMU10K1 audio driver
4 * Copyright 1999, 2000 Creative Labs, Inc.
5 *
6 **********************************************************************
7 *
8 * Date Author Summary of changes
9 * ---- ------ ------------------
10 * October 20, 1999 Bertrand Lee base code release
11 * November 2, 1999 Alan Cox cleaned up stuff
12 *
13 **********************************************************************
14 *
15 * This program is free software; you can redistribute it and/or
16 * modify it under the terms of the GNU General Public License as
17 * published by the Free Software Foundation; either version 2 of
18 * the License, or (at your option) any later version.
19 *
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public
26 * License along with this program; if not, write to the Free
27 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139,
28 * USA.
29 *
30 **********************************************************************
31 *
32 * Supported devices:
33 * /dev/dsp: Standard /dev/dsp device, OSS-compatible
34 * /dev/dsp1: Routes to rear speakers only
35 * /dev/mixer: Standard /dev/mixer device, OSS-compatible
36 * /dev/midi: Raw MIDI UART device, mostly OSS-compatible
37 * /dev/sequencer: Sequencer Interface (requires sound.o)
38 *
39 * Revision history:
40 * 0.1 beta Initial release
41 * 0.2 Lowered initial mixer vol. Improved on stuttering wave playback. Added MIDI UART support.
42 * 0.3 Fixed mixer routing bug, added APS, joystick support.
43 * 0.4 Added rear-channel, SPDIF support.
44 * 0.5 Source cleanup, SMP fixes, multiopen support, 64 bit arch fixes,
45 * moved bh's to tasklets, moved to the new PCI driver initialization style.
46 * 0.6 Make use of pci_alloc_consistent, improve compatibility layer for 2.2 kernels,
47 * code reorganization and cleanup.
48 * 0.7 Support for the Emu-APS. Bug fixes for voice cache setup, mmaped sound + poll().
49 * Support for setting external TRAM size.
50 * 0.8 Make use of the kernel ac97 interface. Support for a dsp patch manager.
51 * 0.9 Re-enables rear speakers volume controls
52 * 0.10 Initializes rear speaker volume.
53 * Dynamic patch storage allocation.
54 * New private ioctls to change control gpr values.
55 * Enable volume control interrupts.
56 * By default enable dsp routes to digital out.
57 * 0.11 Fixed fx / 4 problem.
58 * 0.12 Implemented mmaped for recording.
59 * Fixed bug: not unreserving mmaped buffer pages.
60 * IRQ handler cleanup.
61 * 0.13 Fixed problem with dsp1
62 * Simplified dsp patch writing (inside the driver)
63 * Fixed several bugs found by the Stanford tools
64 * 0.14 New control gpr to oss mixer mapping feature (Chris Purnell)
65 * Added AC3 Passthrough Support (Juha Yrjola)
66 * Added Support for 5.1 cards (digital out and the third analog out)
67 * 0.15 Added Sequencer Support (Daniel Mack)
68 * Support for multichannel pcm playback (Eduard Hasenleithner)
69 * 0.16 Mixer improvements, added old treble/bass support (Daniel Bertrand)
70 * Small code format cleanup.
71 * Deadlock bug fix for emu10k1_volxxx_irqhandler().
72 * 0.17 Fix for mixer SOUND_MIXER_INFO ioctl.
73 * Fix for HIGHMEM machines (emu10k1 can only do 31 bit bus master)
74 * midi poll initial implementation.
75 * Small mixer fixes/cleanups.
76 * Improved support for 5.1 cards.
77 * 0.18 Fix for possible leak in pci_alloc_consistent()
78 * Cleaned up poll() functions (audio and midi). Don't start input.
79 * Restrict DMA pages used to 512Mib range.
80 * New AC97_BOOST mixer ioctl.
81 * 0.19a Added Support for Audigy Cards
82 * Real fix for kernel with highmem support (cast dma_handle to u32).
83 * Fix recording buffering parameters calculation.
84 * Use unsigned long for variables in bit ops.
85 * 0.20a Fixed recording startup
86 * Fixed timer rate setting (it's a 16-bit register)
87 * 0.21 Converted code to use pci_name() instead of accessing slot_name
88 * directly (Eugene Teo)
89 *********************************************************************/
90
91/* These are only included once per module */
92#include <linux/module.h>
93#include <linux/slab.h>
94#include <linux/init.h>
95#include <linux/delay.h>
96#include <linux/proc_fs.h>
97
98#include "hwaccess.h"
99#include "8010.h"
100#include "efxmgr.h"
101#include "cardwo.h"
102#include "cardwi.h"
103#include "cardmo.h"
104#include "cardmi.h"
105#include "recmgr.h"
106#include "ecard.h"
107
108
109#ifdef EMU10K1_SEQUENCER
110#define MIDI_SYNTH_NAME "EMU10K1 MIDI"
111#define MIDI_SYNTH_CAPS SYNTH_CAP_INPUT
112
113#include "../sound_config.h"
114#include "../midi_synth.h"
115
116/* this should be in dev_table.h */
117#define SNDCARD_EMU10K1 46
118#endif
119
120
121/* the emu10k1 _seems_ to only supports 29 bit (512MiB) bit bus master */
122#define EMU10K1_DMA_MASK 0x1fffffff /* DMA buffer mask for pci_alloc_consist */
123
124#ifndef PCI_VENDOR_ID_CREATIVE
125#define PCI_VENDOR_ID_CREATIVE 0x1102
126#endif
127
128#ifndef PCI_DEVICE_ID_CREATIVE_EMU10K1
129#define PCI_DEVICE_ID_CREATIVE_EMU10K1 0x0002
130#endif
131#ifndef PCI_DEVICE_ID_CREATIVE_AUDIGY
132#define PCI_DEVICE_ID_CREATIVE_AUDIGY 0x0004
133#endif
134
135#define EMU_APS_SUBID 0x40011102
136
137enum {
138 EMU10K1 = 0,
139 AUDIGY,
140};
141
142static char *card_names[] __devinitdata = {
143 "EMU10K1",
144 "Audigy",
145};
146
147static struct pci_device_id emu10k1_pci_tbl[] = {
148 {PCI_VENDOR_ID_CREATIVE, PCI_DEVICE_ID_CREATIVE_EMU10K1,
149 PCI_ANY_ID, PCI_ANY_ID, 0, 0, EMU10K1},
150 {PCI_VENDOR_ID_CREATIVE, PCI_DEVICE_ID_CREATIVE_AUDIGY,
151 PCI_ANY_ID, PCI_ANY_ID, 0, 0, AUDIGY},
152 {0,}
153};
154
155MODULE_DEVICE_TABLE(pci, emu10k1_pci_tbl);
156
157/* Global var instantiation */
158
159LIST_HEAD(emu10k1_devs);
160
161extern struct file_operations emu10k1_audio_fops;
162extern struct file_operations emu10k1_mixer_fops;
163extern struct file_operations emu10k1_midi_fops;
164
165#ifdef EMU10K1_SEQUENCER
166static struct midi_operations emu10k1_midi_operations;
167#endif
168
169extern irqreturn_t emu10k1_interrupt(int, void *, struct pt_regs *s);
170
171static int __devinit emu10k1_audio_init(struct emu10k1_card *card)
172{
173 /* Assign default playback voice parameters */
174 if (card->is_audigy)
175 card->mchannel_fx = 0;
176 else
177 card->mchannel_fx = 8;
178
179
180 if (card->is_audigy) {
181 /* mono voice */
182 card->waveout.send_dcba[SEND_MONO] = 0xffffffff;
183 card->waveout.send_hgfe[SEND_MONO] = 0x0000ffff;
184
185 /* stereo voice */
186 /* left */
187 card->waveout.send_dcba[SEND_LEFT] = 0x00ff00ff;
188 card->waveout.send_hgfe[SEND_LEFT] = 0x00007f7f;
189 /* right */
190 card->waveout.send_dcba[SEND_RIGHT] = 0xff00ff00;
191 card->waveout.send_hgfe[SEND_RIGHT] = 0x00007f7f;
192
193 card->waveout.send_routing[ROUTE_PCM] = 0x03020100; // Regular pcm
194 card->waveout.send_routing2[ROUTE_PCM] = 0x07060504;
195
196 card->waveout.send_routing[ROUTE_PT] = 0x3f3f3d3c; // Passthrough
197 card->waveout.send_routing2[ROUTE_PT] = 0x3f3f3f3f;
198
199 card->waveout.send_routing[ROUTE_PCM1] = 0x03020100; // Spare
200 card->waveout.send_routing2[ROUTE_PCM1] = 0x07060404;
201
202 } else {
203 /* mono voice */
204 card->waveout.send_dcba[SEND_MONO] = 0x0000ffff;
205
206 /* stereo voice */
207 /* left */
208 card->waveout.send_dcba[SEND_LEFT] = 0x000000ff;
209 /* right */
210 card->waveout.send_dcba[SEND_RIGHT] = 0x0000ff00;
211
212 card->waveout.send_routing[ROUTE_PCM] = 0x3210; // pcm
213 card->waveout.send_routing[ROUTE_PT] = 0x3210; // passthrough
214 card->waveout.send_routing[ROUTE_PCM1] = 0x7654; // /dev/dsp1
215 }
216
217 /* Assign default recording parameters */
218 /* FIXME */
219 if (card->is_aps)
220 card->wavein.recsrc = WAVERECORD_FX;
221 else
222 card->wavein.recsrc = WAVERECORD_AC97;
223
224 card->wavein.fxwc = 0x0003;
225 return 0;
226}
227
228static void emu10k1_audio_cleanup(struct emu10k1_card *card)
229{
230}
231
232static int __devinit emu10k1_register_devices(struct emu10k1_card *card)
233{
234 card->audio_dev = register_sound_dsp(&emu10k1_audio_fops, -1);
235 if (card->audio_dev < 0) {
236 printk(KERN_ERR "emu10k1: cannot register first audio device!\n");
237 goto err_dev;
238 }
239
240 card->audio_dev1 = register_sound_dsp(&emu10k1_audio_fops, -1);
241 if (card->audio_dev1 < 0) {
242 printk(KERN_ERR "emu10k1: cannot register second audio device!\n");
243 goto err_dev1;
244 }
245
246 card->ac97->dev_mixer = register_sound_mixer(&emu10k1_mixer_fops, -1);
247 if (card->ac97->dev_mixer < 0) {
248 printk(KERN_ERR "emu10k1: cannot register mixer device\n");
249 goto err_mixer;
250 }
251
252 card->midi_dev = register_sound_midi(&emu10k1_midi_fops, -1);
253 if (card->midi_dev < 0) {
254 printk(KERN_ERR "emu10k1: cannot register midi device!\n");
255 goto err_midi;
256 }
257
258#ifdef EMU10K1_SEQUENCER
259 card->seq_dev = sound_alloc_mididev();
260 if (card->seq_dev == -1)
261 printk(KERN_WARNING "emu10k1: unable to register sequencer device!");
262 else {
263 std_midi_synth.midi_dev = card->seq_dev;
264 midi_devs[card->seq_dev] =
265 (struct midi_operations *)
266 kmalloc(sizeof(struct midi_operations), GFP_KERNEL);
267
268 if (midi_devs[card->seq_dev] == NULL) {
269 printk(KERN_ERR "emu10k1: unable to allocate memory!");
270 sound_unload_mididev(card->seq_dev);
271 card->seq_dev = -1;
272 /* return without error */
273 } else {
274 memcpy((char *)midi_devs[card->seq_dev],
275 (char *)&emu10k1_midi_operations,
276 sizeof(struct midi_operations));
277 midi_devs[card->seq_dev]->devc = card;
278 sequencer_init();
279 card->seq_mididev = NULL;
280 }
281 }
282#endif
283 return 0;
284
285err_midi:
286 unregister_sound_mixer(card->ac97->dev_mixer);
287err_mixer:
288 unregister_sound_dsp(card->audio_dev);
289err_dev1:
290 unregister_sound_dsp(card->audio_dev);
291err_dev:
292 return -ENODEV;
293}
294
295static void emu10k1_unregister_devices(struct emu10k1_card *card)
296{
297#ifdef EMU10K1_SEQUENCER
298 if (card->seq_dev > -1) {
299 kfree(midi_devs[card->seq_dev]);
300 midi_devs[card->seq_dev] = NULL;
301 sound_unload_mididev(card->seq_dev);
302 card->seq_dev = -1;
303 }
304#endif
305
306 unregister_sound_midi(card->midi_dev);
307 unregister_sound_mixer(card->ac97->dev_mixer);
308 unregister_sound_dsp(card->audio_dev1);
309 unregister_sound_dsp(card->audio_dev);
310}
311
312static int emu10k1_info_proc (char *page, char **start, off_t off,
313 int count, int *eof, void *data)
314{
315 struct emu10k1_card *card = data;
316 int len = 0;
317
318 if (card == NULL)
319 return -ENODEV;
320
321 len += sprintf (page + len, "Driver Version : %s\n", DRIVER_VERSION);
322 len += sprintf (page + len, "Card type : %s\n", card->is_aps ? "Aps" : (card->is_audigy ? "Audigy" : "Emu10k1"));
323 len += sprintf (page + len, "Revision : %d\n", card->chiprev);
324 len += sprintf (page + len, "Model : %#06x\n", card->model);
325 len += sprintf (page + len, "IO : %#06lx-%#06lx\n", card->iobase, card->iobase + card->length - 1);
326 len += sprintf (page + len, "IRQ : %d\n\n", card->irq);
327
328 len += sprintf (page + len, "Registered /dev Entries:\n");
329 len += sprintf (page + len, "/dev/dsp%d\n", card->audio_dev / 16);
330 len += sprintf (page + len, "/dev/dsp%d\n", card->audio_dev1 / 16);
331 len += sprintf (page + len, "/dev/mixer%d\n", card->ac97->dev_mixer / 16);
332 len += sprintf (page + len, "/dev/midi%d\n", card->midi_dev / 16);
333
334#ifdef EMU10K1_SEQUENCER
335 len += sprintf (page + len, "/dev/sequencer\n");
336#endif
337
338 return len;
339}
340
341static int __devinit emu10k1_proc_init(struct emu10k1_card *card)
342{
343 char s[48];
344
345 if (!proc_mkdir ("driver/emu10k1", NULL)) {
346 printk(KERN_ERR "emu10k1: unable to create proc directory driver/emu10k1\n");
347 goto err_out;
348 }
349
350 sprintf(s, "driver/emu10k1/%s", pci_name(card->pci_dev));
351 if (!proc_mkdir (s, NULL)) {
352 printk(KERN_ERR "emu10k1: unable to create proc directory %s\n", s);
353 goto err_emu10k1_proc;
354 }
355
356 sprintf(s, "driver/emu10k1/%s/info", pci_name(card->pci_dev));
357 if (!create_proc_read_entry (s, 0, NULL, emu10k1_info_proc, card)) {
358 printk(KERN_ERR "emu10k1: unable to create proc entry %s\n", s);
359 goto err_dev_proc;
360 }
361
362 if (!card->is_aps) {
363 sprintf(s, "driver/emu10k1/%s/ac97", pci_name(card->pci_dev));
364 if (!create_proc_read_entry (s, 0, NULL, ac97_read_proc, card->ac97)) {
365 printk(KERN_ERR "emu10k1: unable to create proc entry %s\n", s);
366 goto err_proc_ac97;
367 }
368 }
369
370 return 0;
371
372err_proc_ac97:
373 sprintf(s, "driver/emu10k1/%s/info", pci_name(card->pci_dev));
374 remove_proc_entry(s, NULL);
375
376err_dev_proc:
377 sprintf(s, "driver/emu10k1/%s", pci_name(card->pci_dev));
378 remove_proc_entry(s, NULL);
379
380err_emu10k1_proc:
381 remove_proc_entry("driver/emu10k1", NULL);
382
383err_out:
384 return -EIO;
385}
386
387static void emu10k1_proc_cleanup(struct emu10k1_card *card)
388{
389 char s[48];
390
391 if (!card->is_aps) {
392 sprintf(s, "driver/emu10k1/%s/ac97", pci_name(card->pci_dev));
393 remove_proc_entry(s, NULL);
394 }
395
396 sprintf(s, "driver/emu10k1/%s/info", pci_name(card->pci_dev));
397 remove_proc_entry(s, NULL);
398
399 sprintf(s, "driver/emu10k1/%s", pci_name(card->pci_dev));
400 remove_proc_entry(s, NULL);
401
402 remove_proc_entry("driver/emu10k1", NULL);
403}
404
405static int __devinit emu10k1_mixer_init(struct emu10k1_card *card)
406{
407 struct ac97_codec *codec = ac97_alloc_codec();
408
409 if(codec == NULL)
410 {
411 printk(KERN_ERR "emu10k1: cannot allocate mixer\n");
412 return -EIO;
413 }
414 card->ac97 = codec;
415 card->ac97->private_data = card;
416
417 if (!card->is_aps) {
418 card->ac97->id = 0;
419 card->ac97->codec_read = emu10k1_ac97_read;
420 card->ac97->codec_write = emu10k1_ac97_write;
421
422 if (ac97_probe_codec (card->ac97) == 0) {
423 printk(KERN_ERR "emu10k1: unable to probe AC97 codec\n");
424 goto err_out;
425 }
426 /* 5.1: Enable the additional AC97 Slots and unmute extra channels on AC97 codec */
427 if (codec->codec_read(codec, AC97_EXTENDED_ID) & 0x0080){
428 printk(KERN_INFO "emu10k1: SBLive! 5.1 card detected\n");
429 sblive_writeptr(card, AC97SLOT, 0, AC97SLOT_CNTR | AC97SLOT_LFE);
430 codec->codec_write(codec, AC97_SURROUND_MASTER, 0x0);
431 }
432
433 // Force 5bit:
434 //card->ac97->bit_resolution=5;
435
436 /* these will store the original values and never be modified */
437 card->ac97_supported_mixers = card->ac97->supported_mixers;
438 card->ac97_stereo_mixers = card->ac97->stereo_mixers;
439 }
440
441 return 0;
442
443 err_out:
444 ac97_release_codec(card->ac97);
445 return -EIO;
446}
447
448static void emu10k1_mixer_cleanup(struct emu10k1_card *card)
449{
450 ac97_release_codec(card->ac97);
451}
452
453static int __devinit emu10k1_midi_init(struct emu10k1_card *card)
454{
455 int ret;
456
457 card->mpuout = kmalloc(sizeof(struct emu10k1_mpuout), GFP_KERNEL);
458 if (card->mpuout == NULL) {
459 printk(KERN_WARNING "emu10k1: Unable to allocate emu10k1_mpuout: out of memory\n");
460 ret = -ENOMEM;
461 goto err_out1;
462 }
463
464 memset(card->mpuout, 0, sizeof(struct emu10k1_mpuout));
465
466 card->mpuout->intr = 1;
467 card->mpuout->status = FLAGS_AVAILABLE;
468 card->mpuout->state = CARDMIDIOUT_STATE_DEFAULT;
469
470 tasklet_init(&card->mpuout->tasklet, emu10k1_mpuout_bh, (unsigned long) card);
471
472 spin_lock_init(&card->mpuout->lock);
473
474 card->mpuin = kmalloc(sizeof(struct emu10k1_mpuin), GFP_KERNEL);
475 if (card->mpuin == NULL) {
476 printk(KERN_WARNING "emu10k1: Unable to allocate emu10k1_mpuin: out of memory\n");
477 ret = -ENOMEM;
478 goto err_out2;
479 }
480
481 memset(card->mpuin, 0, sizeof(struct emu10k1_mpuin));
482
483 card->mpuin->status = FLAGS_AVAILABLE;
484
485 tasklet_init(&card->mpuin->tasklet, emu10k1_mpuin_bh, (unsigned long) card->mpuin);
486
487 spin_lock_init(&card->mpuin->lock);
488
489 /* Reset the MPU port */
490 if (emu10k1_mpu_reset(card) < 0) {
491 ERROR();
492 ret = -EIO;
493 goto err_out3;
494 }
495
496 return 0;
497
498err_out3:
499 kfree(card->mpuin);
500err_out2:
501 kfree(card->mpuout);
502err_out1:
503 return ret;
504}
505
506static void emu10k1_midi_cleanup(struct emu10k1_card *card)
507{
508 tasklet_kill(&card->mpuout->tasklet);
509 kfree(card->mpuout);
510
511 tasklet_kill(&card->mpuin->tasklet);
512 kfree(card->mpuin);
513}
514
515static void __devinit voice_init(struct emu10k1_card *card)
516{
517 int i;
518
519 for (i = 0; i < NUM_G; i++)
520 card->voicetable[i] = VOICE_USAGE_FREE;
521}
522
523static void __devinit timer_init(struct emu10k1_card *card)
524{
525 INIT_LIST_HEAD(&card->timers);
526 card->timer_delay = TIMER_STOPPED;
527 spin_lock_init(&card->timer_lock);
528}
529
530static void __devinit addxmgr_init(struct emu10k1_card *card)
531{
532 u32 count;
533
534 for (count = 0; count < MAXPAGES; count++)
535 card->emupagetable[count] = 0;
536
537 /* Mark first page as used */
538 /* This page is reserved by the driver */
539 card->emupagetable[0] = 0x8001;
540 card->emupagetable[1] = MAXPAGES - 1;
541}
542
543static void fx_cleanup(struct patch_manager *mgr)
544{
545 int i;
546 for(i = 0; i < mgr->current_pages; i++)
547 free_page((unsigned long) mgr->patch[i]);
548}
549
550static int __devinit fx_init(struct emu10k1_card *card)
551{
552 struct patch_manager *mgr = &card->mgr;
553 struct dsp_patch *patch;
554 struct dsp_rpatch *rpatch;
555 s32 left, right;
556 int i;
557 u32 pc = 0;
558 u32 patch_n=0;
559 struct emu_efx_info_t emu_efx_info[2]=
560 {{ 20, 10, 0x400, 0x100, 0x20 },
561 { 24, 12, 0x600, 0x400, 0x60 },
562 };
563
564
565 for (i = 0; i < SOUND_MIXER_NRDEVICES; i++) {
566 mgr->ctrl_gpr[i][0] = -1;
567 mgr->ctrl_gpr[i][1] = -1;
568 }
569
570
571 if (card->is_audigy)
572 mgr->current_pages = (2 + PATCHES_PER_PAGE - 1) / PATCHES_PER_PAGE;
573 else
574 /* !! The number below must equal the number of patches, currently 11 !! */
575 mgr->current_pages = (11 + PATCHES_PER_PAGE - 1) / PATCHES_PER_PAGE;
576
577 for (i = 0; i < mgr->current_pages; i++) {
578 mgr->patch[i] = (void *)__get_free_page(GFP_KERNEL);
579 if (mgr->patch[i] == NULL) {
580 mgr->current_pages = i;
581 fx_cleanup(mgr);
582 return -ENOMEM;
583 }
584 memset(mgr->patch[i], 0, PAGE_SIZE);
585 }
586
587 if (card->is_audigy) {
588 for (i = 0; i < 1024; i++)
589 OP(0xf, 0x0c0, 0x0c0, 0x0cf, 0x0c0);
590
591 for (i = 0; i < 512 ; i++)
592 sblive_writeptr(card, A_GPR_BASE+i,0,0);
593
594 pc=0;
595
596 //Pcm input volume
597 OP(0, 0x402, 0x0c0, 0x406, 0x000);
598 OP(0, 0x403, 0x0c0, 0x407, 0x001);
599
600 //CD-Digital input Volume
601 OP(0, 0x404, 0x0c0, 0x40d, 0x42);
602 OP(0, 0x405, 0x0c0, 0x40f, 0x43);
603
604 // CD + PCM
605 OP(6, 0x400, 0x0c0, 0x402, 0x404);
606 OP(6, 0x401, 0x0c0, 0x403, 0x405);
607
608 // Front Output + Master Volume
609 OP(0, 0x68, 0x0c0, 0x408, 0x400);
610 OP(0, 0x69, 0x0c0, 0x409, 0x401);
611
612 // Add-in analog inputs for other speakers
613 OP(6, 0x400, 0x40, 0x400, 0xc0);
614 OP(6, 0x401, 0x41, 0x401, 0xc0);
615
616 // Digital Front + Master Volume
617 OP(0, 0x60, 0x0c0, 0x408, 0x400);
618 OP(0, 0x61, 0x0c0, 0x409, 0x401);
619
620 // Rear Output + Rear Volume
621 OP(0, 0x06e, 0x0c0, 0x419, 0x400);
622 OP(0, 0x06f, 0x0c0, 0x41a, 0x401);
623
624 // Digital Rear Output + Rear Volume
625 OP(0, 0x066, 0x0c0, 0x419, 0x400);
626 OP(0, 0x067, 0x0c0, 0x41a, 0x401);
627
628 // Audigy Drive, Headphone out
629 OP(6, 0x64, 0x0c0, 0x0c0, 0x400);
630 OP(6, 0x65, 0x0c0, 0x0c0, 0x401);
631
632 // ac97 Recording
633 OP(6, 0x76, 0x0c0, 0x0c0, 0x40);
634 OP(6, 0x77, 0x0c0, 0x0c0, 0x41);
635
636 // Center = sub = Left/2 + Right/2
637 OP(0xe, 0x400, 0x401, 0xcd, 0x400);
638
639 // center/sub Volume (master)
640 OP(0, 0x06a, 0x0c0, 0x408, 0x400);
641 OP(0, 0x06b, 0x0c0, 0x409, 0x400);
642
643 // Digital center/sub Volume (master)
644 OP(0, 0x062, 0x0c0, 0x408, 0x400);
645 OP(0, 0x063, 0x0c0, 0x409, 0x400);
646
647 ROUTING_PATCH_START(rpatch, "Routing");
648 ROUTING_PATCH_END(rpatch);
649
650 /* delimiter patch */
651 patch = PATCH(mgr, patch_n);
652 patch->code_size = 0;
653
654
655 sblive_writeptr(card, 0x53, 0, 0);
656 } else {
657 for (i = 0; i < 512 ; i++)
658 OP(6, 0x40, 0x40, 0x40, 0x40);
659
660 for (i = 0; i < 256; i++)
661 sblive_writeptr_tag(card, 0,
662 FXGPREGBASE + i, 0,
663 TANKMEMADDRREGBASE + i, 0,
664 TAGLIST_END);
665
666
667 pc = 0;
668
669 //first free GPR = 0x11b
670
671
672 /* FX volume correction and Volume control*/
673 INPUT_PATCH_START(patch, "Pcm L vol", 0x0, 0);
674 GET_OUTPUT_GPR(patch, 0x100, 0x0);
675 GET_CONTROL_GPR(patch, 0x106, "Vol", 0, 0x7fffffff);
676 GET_DYNAMIC_GPR(patch, 0x112);
677
678 OP(4, 0x112, 0x40, PCM_IN_L, 0x44); //*4
679 OP(0, 0x100, 0x040, 0x112, 0x106); //*vol
680 INPUT_PATCH_END(patch);
681
682
683 INPUT_PATCH_START(patch, "Pcm R vol", 0x1, 0);
684 GET_OUTPUT_GPR(patch, 0x101, 0x1);
685 GET_CONTROL_GPR(patch, 0x107, "Vol", 0, 0x7fffffff);
686 GET_DYNAMIC_GPR(patch, 0x112);
687
688 OP(4, 0x112, 0x40, PCM_IN_R, 0x44);
689 OP(0, 0x101, 0x040, 0x112, 0x107);
690
691 INPUT_PATCH_END(patch);
692
693
694 // CD-Digital In Volume control
695 INPUT_PATCH_START(patch, "CD-Digital Vol L", 0x12, 0);
696 GET_OUTPUT_GPR(patch, 0x10c, 0x12);
697 GET_CONTROL_GPR(patch, 0x10d, "Vol", 0, 0x7fffffff);
698
699 OP(0, 0x10c, 0x040, SPDIF_CD_L, 0x10d);
700 INPUT_PATCH_END(patch);
701
702 INPUT_PATCH_START(patch, "CD-Digital Vol R", 0x13, 0);
703 GET_OUTPUT_GPR(patch, 0x10e, 0x13);
704 GET_CONTROL_GPR(patch, 0x10f, "Vol", 0, 0x7fffffff);
705
706 OP(0, 0x10e, 0x040, SPDIF_CD_R, 0x10f);
707 INPUT_PATCH_END(patch);
708
709 //Volume Correction for Multi-channel Inputs
710 INPUT_PATCH_START(patch, "Multi-Channel Gain", 0x08, 0);
711 patch->input=patch->output=0x3F00;
712
713 GET_OUTPUT_GPR(patch, 0x113, MULTI_FRONT_L);
714 GET_OUTPUT_GPR(patch, 0x114, MULTI_FRONT_R);
715 GET_OUTPUT_GPR(patch, 0x115, MULTI_REAR_L);
716 GET_OUTPUT_GPR(patch, 0x116, MULTI_REAR_R);
717 GET_OUTPUT_GPR(patch, 0x117, MULTI_CENTER);
718 GET_OUTPUT_GPR(patch, 0x118, MULTI_LFE);
719
720 OP(4, 0x113, 0x40, MULTI_FRONT_L, 0x44);
721 OP(4, 0x114, 0x40, MULTI_FRONT_R, 0x44);
722 OP(4, 0x115, 0x40, MULTI_REAR_L, 0x44);
723 OP(4, 0x116, 0x40, MULTI_REAR_R, 0x44);
724 OP(4, 0x117, 0x40, MULTI_CENTER, 0x44);
725 OP(4, 0x118, 0x40, MULTI_LFE, 0x44);
726
727 INPUT_PATCH_END(patch);
728
729
730 //Routing patch start
731 ROUTING_PATCH_START(rpatch, "Routing");
732 GET_INPUT_GPR(rpatch, 0x100, 0x0);
733 GET_INPUT_GPR(rpatch, 0x101, 0x1);
734 GET_INPUT_GPR(rpatch, 0x10c, 0x12);
735 GET_INPUT_GPR(rpatch, 0x10e, 0x13);
736 GET_INPUT_GPR(rpatch, 0x113, MULTI_FRONT_L);
737 GET_INPUT_GPR(rpatch, 0x114, MULTI_FRONT_R);
738 GET_INPUT_GPR(rpatch, 0x115, MULTI_REAR_L);
739 GET_INPUT_GPR(rpatch, 0x116, MULTI_REAR_R);
740 GET_INPUT_GPR(rpatch, 0x117, MULTI_CENTER);
741 GET_INPUT_GPR(rpatch, 0x118, MULTI_LFE);
742
743 GET_DYNAMIC_GPR(rpatch, 0x102);
744 GET_DYNAMIC_GPR(rpatch, 0x103);
745
746 GET_OUTPUT_GPR(rpatch, 0x104, 0x8);
747 GET_OUTPUT_GPR(rpatch, 0x105, 0x9);
748 GET_OUTPUT_GPR(rpatch, 0x10a, 0x2);
749 GET_OUTPUT_GPR(rpatch, 0x10b, 0x3);
750
751
752 /* input buffer */
753 OP(6, 0x102, AC97_IN_L, 0x40, 0x40);
754 OP(6, 0x103, AC97_IN_R, 0x40, 0x40);
755
756
757 /* Digital In + PCM + MULTI_FRONT-> AC97 out (front speakers)*/
758 OP(6, AC97_FRONT_L, 0x100, 0x10c, 0x113);
759
760 CONNECT(MULTI_FRONT_L, AC97_FRONT_L);
761 CONNECT(PCM_IN_L, AC97_FRONT_L);
762 CONNECT(SPDIF_CD_L, AC97_FRONT_L);
763
764 OP(6, AC97_FRONT_R, 0x101, 0x10e, 0x114);
765
766 CONNECT(MULTI_FRONT_R, AC97_FRONT_R);
767 CONNECT(PCM_IN_R, AC97_FRONT_R);
768 CONNECT(SPDIF_CD_R, AC97_FRONT_R);
769
770 /* Digital In + PCM + AC97 In + PCM1 + MULTI_REAR --> Rear Channel */
771 OP(6, 0x104, PCM1_IN_L, 0x100, 0x115);
772 OP(6, 0x104, 0x104, 0x10c, 0x102);
773
774 CONNECT(MULTI_REAR_L, ANALOG_REAR_L);
775 CONNECT(AC97_IN_L, ANALOG_REAR_L);
776 CONNECT(PCM_IN_L, ANALOG_REAR_L);
777 CONNECT(SPDIF_CD_L, ANALOG_REAR_L);
778 CONNECT(PCM1_IN_L, ANALOG_REAR_L);
779
780 OP(6, 0x105, PCM1_IN_R, 0x101, 0x116);
781 OP(6, 0x105, 0x105, 0x10e, 0x103);
782
783 CONNECT(MULTI_REAR_R, ANALOG_REAR_R);
784 CONNECT(AC97_IN_R, ANALOG_REAR_R);
785 CONNECT(PCM_IN_R, ANALOG_REAR_R);
786 CONNECT(SPDIF_CD_R, ANALOG_REAR_R);
787 CONNECT(PCM1_IN_R, ANALOG_REAR_R);
788
789 /* Digital In + PCM + AC97 In + MULTI_FRONT --> Digital out */
790 OP(6, 0x10b, 0x100, 0x102, 0x10c);
791 OP(6, 0x10b, 0x10b, 0x113, 0x40);
792
793 CONNECT(MULTI_FRONT_L, DIGITAL_OUT_L);
794 CONNECT(PCM_IN_L, DIGITAL_OUT_L);
795 CONNECT(AC97_IN_L, DIGITAL_OUT_L);
796 CONNECT(SPDIF_CD_L, DIGITAL_OUT_L);
797
798 OP(6, 0x10a, 0x101, 0x103, 0x10e);
799 OP(6, 0x10b, 0x10b, 0x114, 0x40);
800
801 CONNECT(MULTI_FRONT_R, DIGITAL_OUT_R);
802 CONNECT(PCM_IN_R, DIGITAL_OUT_R);
803 CONNECT(AC97_IN_R, DIGITAL_OUT_R);
804 CONNECT(SPDIF_CD_R, DIGITAL_OUT_R);
805
806 /* AC97 In --> ADC Recording Buffer */
807 OP(6, ADC_REC_L, 0x102, 0x40, 0x40);
808
809 CONNECT(AC97_IN_L, ADC_REC_L);
810
811 OP(6, ADC_REC_R, 0x103, 0x40, 0x40);
812
813 CONNECT(AC97_IN_R, ADC_REC_R);
814
815
816 /* fx12:Analog-Center */
817 OP(6, ANALOG_CENTER, 0x117, 0x40, 0x40);
818 CONNECT(MULTI_CENTER, ANALOG_CENTER);
819
820 /* fx11:Analog-LFE */
821 OP(6, ANALOG_LFE, 0x118, 0x40, 0x40);
822 CONNECT(MULTI_LFE, ANALOG_LFE);
823
824 /* fx12:Digital-Center */
825 OP(6, DIGITAL_CENTER, 0x117, 0x40, 0x40);
826 CONNECT(MULTI_CENTER, DIGITAL_CENTER);
827
828 /* fx11:Analog-LFE */
829 OP(6, DIGITAL_LFE, 0x118, 0x40, 0x40);
830 CONNECT(MULTI_LFE, DIGITAL_LFE);
831
832 ROUTING_PATCH_END(rpatch);
833
834
835 // Rear volume control
836 OUTPUT_PATCH_START(patch, "Vol Rear L", 0x8, 0);
837 GET_INPUT_GPR(patch, 0x104, 0x8);
838 GET_CONTROL_GPR(patch, 0x119, "Vol", 0, 0x7fffffff);
839
840 OP(0, ANALOG_REAR_L, 0x040, 0x104, 0x119);
841 OUTPUT_PATCH_END(patch);
842
843 OUTPUT_PATCH_START(patch, "Vol Rear R", 0x9, 0);
844 GET_INPUT_GPR(patch, 0x105, 0x9);
845 GET_CONTROL_GPR(patch, 0x11a, "Vol", 0, 0x7fffffff);
846
847 OP(0, ANALOG_REAR_R, 0x040, 0x105, 0x11a);
848 OUTPUT_PATCH_END(patch);
849
850
851 //Master volume control on front-digital
852 OUTPUT_PATCH_START(patch, "Vol Master L", 0x2, 1);
853 GET_INPUT_GPR(patch, 0x10a, 0x2);
854 GET_CONTROL_GPR(patch, 0x108, "Vol", 0, 0x7fffffff);
855
856 OP(0, DIGITAL_OUT_L, 0x040, 0x10a, 0x108);
857 OUTPUT_PATCH_END(patch);
858
859
860 OUTPUT_PATCH_START(patch, "Vol Master R", 0x3, 1);
861 GET_INPUT_GPR(patch, 0x10b, 0x3);
862 GET_CONTROL_GPR(patch, 0x109, "Vol", 0, 0x7fffffff);
863
864 OP(0, DIGITAL_OUT_R, 0x040, 0x10b, 0x109);
865 OUTPUT_PATCH_END(patch);
866
867
868 /* delimiter patch */
869 patch = PATCH(mgr, patch_n);
870 patch->code_size = 0;
871
872
873 sblive_writeptr(card, DBG, 0, 0);
874 }
875
876 spin_lock_init(&mgr->lock);
877
878 // Set up Volume controls, try to keep this the same for both Audigy and Live
879
880 //Master volume
881 mgr->ctrl_gpr[SOUND_MIXER_VOLUME][0] = 8;
882 mgr->ctrl_gpr[SOUND_MIXER_VOLUME][1] = 9;
883
884 left = card->ac97->mixer_state[SOUND_MIXER_VOLUME] & 0xff;
885 right = (card->ac97->mixer_state[SOUND_MIXER_VOLUME] >> 8) & 0xff;
886
887 emu10k1_set_volume_gpr(card, 8, left, 1 << card->ac97->bit_resolution);
888 emu10k1_set_volume_gpr(card, 9, right, 1 << card->ac97->bit_resolution);
889
890 //Rear volume
891 mgr->ctrl_gpr[ SOUND_MIXER_OGAIN ][0] = 0x19;
892 mgr->ctrl_gpr[ SOUND_MIXER_OGAIN ][1] = 0x1a;
893
894 left = right = 67;
895 card->ac97->mixer_state[SOUND_MIXER_OGAIN] = (right << 8) | left;
896
897 card->ac97->supported_mixers |= SOUND_MASK_OGAIN;
898 card->ac97->stereo_mixers |= SOUND_MASK_OGAIN;
899
900 emu10k1_set_volume_gpr(card, 0x19, left, VOL_5BIT);
901 emu10k1_set_volume_gpr(card, 0x1a, right, VOL_5BIT);
902
903 //PCM Volume
904 mgr->ctrl_gpr[SOUND_MIXER_PCM][0] = 6;
905 mgr->ctrl_gpr[SOUND_MIXER_PCM][1] = 7;
906
907 left = card->ac97->mixer_state[SOUND_MIXER_PCM] & 0xff;
908 right = (card->ac97->mixer_state[SOUND_MIXER_PCM] >> 8) & 0xff;
909
910 emu10k1_set_volume_gpr(card, 6, left, VOL_5BIT);
911 emu10k1_set_volume_gpr(card, 7, right, VOL_5BIT);
912
913 //CD-Digital Volume
914 mgr->ctrl_gpr[SOUND_MIXER_DIGITAL1][0] = 0xd;
915 mgr->ctrl_gpr[SOUND_MIXER_DIGITAL1][1] = 0xf;
916
917 left = right = 67;
918 card->ac97->mixer_state[SOUND_MIXER_DIGITAL1] = (right << 8) | left;
919
920 card->ac97->supported_mixers |= SOUND_MASK_DIGITAL1;
921 card->ac97->stereo_mixers |= SOUND_MASK_DIGITAL1;
922
923 emu10k1_set_volume_gpr(card, 0xd, left, VOL_5BIT);
924 emu10k1_set_volume_gpr(card, 0xf, right, VOL_5BIT);
925
926
927 //hard wire the ac97's pcm, pcm volume is done above using dsp code.
928 if (card->is_audigy)
929 //for Audigy, we mute it and use the philips 6 channel DAC instead
930 emu10k1_ac97_write(card->ac97, 0x18, 0x8000);
931 else
932 //For the Live we hardwire it to full volume
933 emu10k1_ac97_write(card->ac97, 0x18, 0x0);
934
935 //remove it from the ac97_codec's control
936 card->ac97_supported_mixers &= ~SOUND_MASK_PCM;
937 card->ac97_stereo_mixers &= ~SOUND_MASK_PCM;
938
939 //set Igain to 0dB by default, maybe consider hardwiring it here.
940 emu10k1_ac97_write(card->ac97, AC97_RECORD_GAIN, 0x0000);
941 card->ac97->mixer_state[SOUND_MIXER_IGAIN] = 0x101;
942
943 return 0;
944}
945
946static int __devinit hw_init(struct emu10k1_card *card)
947{
948 int nCh;
949 u32 pagecount; /* tmp */
950 int ret;
951
952 /* Disable audio and lock cache */
953 emu10k1_writefn0(card, HCFG, HCFG_LOCKSOUNDCACHE | HCFG_LOCKTANKCACHE_MASK | HCFG_MUTEBUTTONENABLE);
954
955 /* Reset recording buffers */
956 sblive_writeptr_tag(card, 0,
957 MICBS, ADCBS_BUFSIZE_NONE,
958 MICBA, 0,
959 FXBS, ADCBS_BUFSIZE_NONE,
960 FXBA, 0,
961 ADCBS, ADCBS_BUFSIZE_NONE,
962 ADCBA, 0,
963 TAGLIST_END);
964
965 /* Disable channel interrupt */
966 emu10k1_writefn0(card, INTE, 0);
967 sblive_writeptr_tag(card, 0,
968 CLIEL, 0,
969 CLIEH, 0,
970 SOLEL, 0,
971 SOLEH, 0,
972 TAGLIST_END);
973
974 if (card->is_audigy) {
975 sblive_writeptr_tag(card,0,
976 0x5e,0xf00,
977 0x5f,0x3,
978 TAGLIST_END);
979 }
980
981 /* Init envelope engine */
982 for (nCh = 0; nCh < NUM_G; nCh++) {
983 sblive_writeptr_tag(card, nCh,
984 DCYSUSV, 0,
985 IP, 0,
986 VTFT, 0xffff,
987 CVCF, 0xffff,
988 PTRX, 0,
989 //CPF, 0,
990 CCR, 0,
991
992 PSST, 0,
993 DSL, 0x10,
994 CCCA, 0,
995 Z1, 0,
996 Z2, 0,
997 FXRT, 0xd01c0000,
998
999 ATKHLDM, 0,
1000 DCYSUSM, 0,
1001 IFATN, 0xffff,
1002 PEFE, 0,
1003 FMMOD, 0,
1004 TREMFRQ, 24, /* 1 Hz */
1005 FM2FRQ2, 24, /* 1 Hz */
1006 TEMPENV, 0,
1007
1008 /*** These are last so OFF prevents writing ***/
1009 LFOVAL2, 0,
1010 LFOVAL1, 0,
1011 ATKHLDV, 0,
1012 ENVVOL, 0,
1013 ENVVAL, 0,
1014 TAGLIST_END);
1015 sblive_writeptr(card, CPF, nCh, 0);
1016 /*
1017 Audigy FXRT initialization
1018 reversed eng'd, may not be accurate.
1019 */
1020 if (card->is_audigy) {
1021 sblive_writeptr_tag(card,nCh,
1022 0x4c,0x0,
1023 0x4d,0x0,
1024 0x4e,0x0,
1025 0x4f,0x0,
1026 A_FXRT1, 0x3f3f3f3f,
1027 A_FXRT2, 0x3f3f3f3f,
1028 A_SENDAMOUNTS, 0,
1029 TAGLIST_END);
1030 }
1031 }
1032
1033
1034 /*
1035 ** Init to 0x02109204 :
1036 ** Clock accuracy = 0 (1000ppm)
1037 ** Sample Rate = 2 (48kHz)
1038 ** Audio Channel = 1 (Left of 2)
1039 ** Source Number = 0 (Unspecified)
1040 ** Generation Status = 1 (Original for Cat Code 12)
1041 ** Cat Code = 12 (Digital Signal Mixer)
1042 ** Mode = 0 (Mode 0)
1043 ** Emphasis = 0 (None)
1044 ** CP = 1 (Copyright unasserted)
1045 ** AN = 0 (Digital audio)
1046 ** P = 0 (Consumer)
1047 */
1048
1049 sblive_writeptr_tag(card, 0,
1050
1051 /* SPDIF0 */
1052 SPCS0, (SPCS_CLKACCY_1000PPM | 0x002000000 |
1053 SPCS_CHANNELNUM_LEFT | SPCS_SOURCENUM_UNSPEC | SPCS_GENERATIONSTATUS | 0x00001200 | SPCS_EMPHASIS_NONE | SPCS_COPYRIGHT),
1054
1055 /* SPDIF1 */
1056 SPCS1, (SPCS_CLKACCY_1000PPM | 0x002000000 |
1057 SPCS_CHANNELNUM_LEFT | SPCS_SOURCENUM_UNSPEC | SPCS_GENERATIONSTATUS | 0x00001200 | SPCS_EMPHASIS_NONE | SPCS_COPYRIGHT),
1058
1059 /* SPDIF2 & SPDIF3 */
1060 SPCS2, (SPCS_CLKACCY_1000PPM | 0x002000000 |
1061 SPCS_CHANNELNUM_LEFT | SPCS_SOURCENUM_UNSPEC | SPCS_GENERATIONSTATUS | 0x00001200 | SPCS_EMPHASIS_NONE | SPCS_COPYRIGHT),
1062
1063 TAGLIST_END);
1064
1065 if (card->is_audigy && (card->chiprev == 4)) {
1066 /* Hacks for Alice3 to work independent of haP16V driver */
1067 u32 tmp;
1068
1069 //Setup SRCMulti_I2S SamplingRate
1070 tmp = sblive_readptr(card, A_SPDIF_SAMPLERATE, 0);
1071 tmp &= 0xfffff1ff;
1072 tmp |= (0x2<<9);
1073 sblive_writeptr(card, A_SPDIF_SAMPLERATE, 0, tmp);
1074
1075 /* Setup SRCSel (Enable Spdif,I2S SRCMulti) */
1076 emu10k1_writefn0(card, 0x20, 0x600000);
1077 emu10k1_writefn0(card, 0x24, 0x14);
1078
1079 /* Setup SRCMulti Input Audio Enable */
1080 emu10k1_writefn0(card, 0x20, 0x6E0000);
1081 emu10k1_writefn0(card, 0x24, 0xFF00FF00);
1082 }
1083
1084 ret = fx_init(card); /* initialize effects engine */
1085 if (ret < 0)
1086 return ret;
1087
1088 card->tankmem.size = 0;
1089
1090 card->virtualpagetable.size = MAXPAGES * sizeof(u32);
1091
1092 card->virtualpagetable.addr = pci_alloc_consistent(card->pci_dev, card->virtualpagetable.size, &card->virtualpagetable.dma_handle);
1093 if (card->virtualpagetable.addr == NULL) {
1094 ERROR();
1095 ret = -ENOMEM;
1096 goto err0;
1097 }
1098
1099 card->silentpage.size = EMUPAGESIZE;
1100
1101 card->silentpage.addr = pci_alloc_consistent(card->pci_dev, card->silentpage.size, &card->silentpage.dma_handle);
1102 if (card->silentpage.addr == NULL) {
1103 ERROR();
1104 ret = -ENOMEM;
1105 goto err1;
1106 }
1107
1108 for (pagecount = 0; pagecount < MAXPAGES; pagecount++)
1109 ((u32 *) card->virtualpagetable.addr)[pagecount] = cpu_to_le32(((u32) card->silentpage.dma_handle * 2) | pagecount);
1110
1111 /* Init page table & tank memory base register */
1112 sblive_writeptr_tag(card, 0,
1113 PTB, (u32) card->virtualpagetable.dma_handle,
1114 TCB, 0,
1115 TCBS, 0,
1116 TAGLIST_END);
1117
1118 for (nCh = 0; nCh < NUM_G; nCh++) {
1119 sblive_writeptr_tag(card, nCh,
1120 MAPA, MAP_PTI_MASK | ((u32) card->silentpage.dma_handle * 2),
1121 MAPB, MAP_PTI_MASK | ((u32) card->silentpage.dma_handle * 2),
1122 TAGLIST_END);
1123 }
1124
1125 /* Hokay, now enable the AUD bit */
1126 /* Enable Audio = 1 */
1127 /* Mute Disable Audio = 0 */
1128 /* Lock Tank Memory = 1 */
1129 /* Lock Sound Memory = 0 */
1130 /* Auto Mute = 1 */
1131 if (card->is_audigy) {
1132 if (card->chiprev == 4)
1133 emu10k1_writefn0(card, HCFG, HCFG_AUDIOENABLE | HCFG_AC3ENABLE_CDSPDIF | HCFG_AC3ENABLE_GPSPDIF | HCFG_AUTOMUTE | HCFG_JOYENABLE);
1134 else
1135 emu10k1_writefn0(card, HCFG, HCFG_AUDIOENABLE | HCFG_AUTOMUTE | HCFG_JOYENABLE);
1136 } else {
1137 if (card->model == 0x20 || card->model == 0xc400 ||
1138 (card->model == 0x21 && card->chiprev < 6))
1139 emu10k1_writefn0(card, HCFG, HCFG_AUDIOENABLE | HCFG_LOCKTANKCACHE_MASK | HCFG_AUTOMUTE);
1140 else
1141 emu10k1_writefn0(card, HCFG, HCFG_AUDIOENABLE | HCFG_LOCKTANKCACHE_MASK | HCFG_AUTOMUTE | HCFG_JOYENABLE);
1142 }
1143 /* Enable Vol_Ctrl irqs */
1144 emu10k1_irq_enable(card, INTE_VOLINCRENABLE | INTE_VOLDECRENABLE | INTE_MUTEENABLE | INTE_FXDSPENABLE);
1145
1146 if (card->is_audigy && (card->chiprev == 4)) {
1147 /* Unmute Analog now. Set GPO6 to 1 for Apollo.
1148 * This has to be done after init ALice3 I2SOut beyond 48KHz.
1149 * So, sequence is important. */
1150 u32 tmp = emu10k1_readfn0(card, A_IOCFG);
1151 tmp |= 0x0040;
1152 emu10k1_writefn0(card, A_IOCFG, tmp);
1153 }
1154
1155 /* FIXME: TOSLink detection */
1156 card->has_toslink = 0;
1157
1158 /* Initialize digital passthrough variables */
1159 card->pt.pos_gpr = card->pt.intr_gpr = card->pt.enable_gpr = -1;
1160 card->pt.selected = 0;
1161 card->pt.state = PT_STATE_INACTIVE;
1162 card->pt.spcs_to_use = 0x01;
1163 card->pt.patch_name = "AC3pass";
1164 card->pt.intr_gpr_name = "count";
1165 card->pt.enable_gpr_name = "enable";
1166 card->pt.pos_gpr_name = "ptr";
1167 spin_lock_init(&card->pt.lock);
1168 init_waitqueue_head(&card->pt.wait);
1169
1170/* tmp = sblive_readfn0(card, HCFG);
1171 if (tmp & (HCFG_GPINPUT0 | HCFG_GPINPUT1)) {
1172 sblive_writefn0(card, HCFG, tmp | 0x800);
1173
1174 udelay(512);
1175
1176 if (tmp != (sblive_readfn0(card, HCFG) & ~0x800)) {
1177 card->has_toslink = 1;
1178 sblive_writefn0(card, HCFG, tmp);
1179 }
1180 }
1181*/
1182 return 0;
1183
1184 err1:
1185 pci_free_consistent(card->pci_dev, card->virtualpagetable.size, card->virtualpagetable.addr, card->virtualpagetable.dma_handle);
1186 err0:
1187 fx_cleanup(&card->mgr);
1188
1189 return ret;
1190}
1191
1192static int __devinit emu10k1_init(struct emu10k1_card *card)
1193{
1194 /* Init Card */
1195 if (hw_init(card) < 0)
1196 return -1;
1197
1198 voice_init(card);
1199 timer_init(card);
1200 addxmgr_init(card);
1201
1202 DPD(2, " hw control register -> %#x\n", emu10k1_readfn0(card, HCFG));
1203
1204 return 0;
1205}
1206
1207static void emu10k1_cleanup(struct emu10k1_card *card)
1208{
1209 int ch;
1210
1211 emu10k1_writefn0(card, INTE, 0);
1212
1213 /** Shutdown the chip **/
1214 for (ch = 0; ch < NUM_G; ch++)
1215 sblive_writeptr(card, DCYSUSV, ch, 0);
1216
1217 for (ch = 0; ch < NUM_G; ch++) {
1218 sblive_writeptr_tag(card, ch,
1219 VTFT, 0,
1220 CVCF, 0,
1221 PTRX, 0,
1222 //CPF, 0,
1223 TAGLIST_END);
1224 sblive_writeptr(card, CPF, ch, 0);
1225 }
1226
1227 /* Disable audio and lock cache */
1228 emu10k1_writefn0(card, HCFG, HCFG_LOCKSOUNDCACHE | HCFG_LOCKTANKCACHE_MASK | HCFG_MUTEBUTTONENABLE);
1229
1230 sblive_writeptr_tag(card, 0,
1231 PTB, 0,
1232
1233 /* Reset recording buffers */
1234 MICBS, ADCBS_BUFSIZE_NONE,
1235 MICBA, 0,
1236 FXBS, ADCBS_BUFSIZE_NONE,
1237 FXBA, 0,
1238 FXWC, 0,
1239 ADCBS, ADCBS_BUFSIZE_NONE,
1240 ADCBA, 0,
1241 TCBS, 0,
1242 TCB, 0,
1243 DBG, 0x8000,
1244
1245 /* Disable channel interrupt */
1246 CLIEL, 0,
1247 CLIEH, 0,
1248 SOLEL, 0,
1249 SOLEH, 0,
1250 TAGLIST_END);
1251
1252 if (card->is_audigy)
1253 sblive_writeptr(card, 0, A_DBG, A_DBG_SINGLE_STEP);
1254
1255 pci_free_consistent(card->pci_dev, card->virtualpagetable.size, card->virtualpagetable.addr, card->virtualpagetable.dma_handle);
1256 pci_free_consistent(card->pci_dev, card->silentpage.size, card->silentpage.addr, card->silentpage.dma_handle);
1257
1258 if(card->tankmem.size != 0)
1259 pci_free_consistent(card->pci_dev, card->tankmem.size, card->tankmem.addr, card->tankmem.dma_handle);
1260
1261 /* release patch storage memory */
1262 fx_cleanup(&card->mgr);
1263}
1264
1265/* Driver initialization routine */
1266static int __devinit emu10k1_probe(struct pci_dev *pci_dev, const struct pci_device_id *pci_id)
1267{
1268 struct emu10k1_card *card;
1269 u32 subsysvid;
1270 int ret;
1271
1272 if (pci_set_dma_mask(pci_dev, EMU10K1_DMA_MASK)) {
1273 printk(KERN_ERR "emu10k1: architecture does not support 29bit PCI busmaster DMA\n");
1274 return -ENODEV;
1275 }
1276
1277 if (pci_enable_device(pci_dev))
1278 return -EIO;
1279
1280 pci_set_master(pci_dev);
1281
1282 if ((card = kmalloc(sizeof(struct emu10k1_card), GFP_KERNEL)) == NULL) {
1283 printk(KERN_ERR "emu10k1: out of memory\n");
1284 return -ENOMEM;
1285 }
1286 memset(card, 0, sizeof(struct emu10k1_card));
1287
1288 card->iobase = pci_resource_start(pci_dev, 0);
1289 card->length = pci_resource_len(pci_dev, 0);
1290
1291 if (request_region(card->iobase, card->length, card_names[pci_id->driver_data]) == NULL) {
1292 printk(KERN_ERR "emu10k1: IO space in use\n");
1293 ret = -EBUSY;
1294 goto err_region;
1295 }
1296
1297 pci_set_drvdata(pci_dev, card);
1298
1299 card->irq = pci_dev->irq;
1300 card->pci_dev = pci_dev;
1301
1302 /* Reserve IRQ Line */
1303 if (request_irq(card->irq, emu10k1_interrupt, SA_SHIRQ, card_names[pci_id->driver_data], card)) {
1304 printk(KERN_ERR "emu10k1: IRQ in use\n");
1305 ret = -EBUSY;
1306 goto err_irq;
1307 }
1308
1309 pci_read_config_byte(pci_dev, PCI_REVISION_ID, &card->chiprev);
1310 pci_read_config_word(pci_dev, PCI_SUBSYSTEM_ID, &card->model);
1311
1312 printk(KERN_INFO "emu10k1: %s rev %d model %#04x found, IO at %#04lx-%#04lx, IRQ %d\n",
1313 card_names[pci_id->driver_data], card->chiprev, card->model, card->iobase,
1314 card->iobase + card->length - 1, card->irq);
1315
1316 if (pci_id->device == PCI_DEVICE_ID_CREATIVE_AUDIGY)
1317 card->is_audigy = 1;
1318
1319 pci_read_config_dword(pci_dev, PCI_SUBSYSTEM_VENDOR_ID, &subsysvid);
1320 card->is_aps = (subsysvid == EMU_APS_SUBID);
1321
1322 spin_lock_init(&card->lock);
1323 init_MUTEX(&card->open_sem);
1324 card->open_mode = 0;
1325 init_waitqueue_head(&card->open_wait);
1326
1327 ret = emu10k1_audio_init(card);
1328 if (ret < 0) {
1329 printk(KERN_ERR "emu10k1: cannot initialize audio devices\n");
1330 goto err_audio;
1331 }
1332
1333 ret = emu10k1_mixer_init(card);
1334 if (ret < 0) {
1335 printk(KERN_ERR "emu10k1: cannot initialize AC97 codec\n");
1336 goto err_mixer;
1337 }
1338
1339 ret = emu10k1_midi_init(card);
1340 if (ret < 0) {
1341 printk(KERN_ERR "emu10k1: cannot register midi device\n");
1342 goto err_midi;
1343 }
1344
1345 ret = emu10k1_init(card);
1346 if (ret < 0) {
1347 printk(KERN_ERR "emu10k1: cannot initialize device\n");
1348 goto err_emu10k1_init;
1349 }
1350
1351 if (card->is_aps)
1352 emu10k1_ecard_init(card);
1353
1354 ret = emu10k1_register_devices(card);
1355 if (ret < 0)
1356 goto err_register;
1357
1358 /* proc entries must be created after registering devices, as
1359 * emu10k1_info_proc prints card->audio_dev &co. */
1360 ret = emu10k1_proc_init(card);
1361 if (ret < 0) {
1362 printk(KERN_ERR "emu10k1: cannot initialize proc directory\n");
1363 goto err_proc;
1364 }
1365
1366 list_add(&card->list, &emu10k1_devs);
1367
1368 return 0;
1369
1370err_proc:
1371 emu10k1_unregister_devices(card);
1372
1373err_register:
1374 emu10k1_cleanup(card);
1375
1376err_emu10k1_init:
1377 emu10k1_midi_cleanup(card);
1378
1379err_midi:
1380 emu10k1_mixer_cleanup(card);
1381
1382err_mixer:
1383 emu10k1_audio_cleanup(card);
1384
1385err_audio:
1386 free_irq(card->irq, card);
1387
1388err_irq:
1389 release_region(card->iobase, card->length);
1390 pci_set_drvdata(pci_dev, NULL);
1391
1392err_region:
1393 kfree(card);
1394
1395 return ret;
1396}
1397
1398static void __devexit emu10k1_remove(struct pci_dev *pci_dev)
1399{
1400 struct emu10k1_card *card = pci_get_drvdata(pci_dev);
1401
1402 list_del(&card->list);
1403
1404 emu10k1_unregister_devices(card);
1405 emu10k1_cleanup(card);
1406 emu10k1_midi_cleanup(card);
1407 emu10k1_mixer_cleanup(card);
1408 emu10k1_proc_cleanup(card);
1409 emu10k1_audio_cleanup(card);
1410 free_irq(card->irq, card);
1411 release_region(card->iobase, card->length);
1412 kfree(card);
1413 pci_set_drvdata(pci_dev, NULL);
1414}
1415
1416MODULE_AUTHOR("Bertrand Lee, Cai Ying. (Email to: emu10k1-devel@lists.sourceforge.net)");
1417MODULE_DESCRIPTION("Creative EMU10K1 PCI Audio Driver v" DRIVER_VERSION "\nCopyright (C) 1999 Creative Technology Ltd.");
1418MODULE_LICENSE("GPL");
1419
1420static struct pci_driver emu10k1_pci_driver = {
1421 .name = "emu10k1",
1422 .id_table = emu10k1_pci_tbl,
1423 .probe = emu10k1_probe,
1424 .remove = __devexit_p(emu10k1_remove),
1425};
1426
1427static int __init emu10k1_init_module(void)
1428{
1429 printk(KERN_INFO "Creative EMU10K1 PCI Audio Driver, version " DRIVER_VERSION ", " __TIME__ " " __DATE__ "\n");
1430
1431 return pci_module_init(&emu10k1_pci_driver);
1432}
1433
1434static void __exit emu10k1_cleanup_module(void)
1435{
1436 pci_unregister_driver(&emu10k1_pci_driver);
1437
1438 return;
1439}
1440
1441module_init(emu10k1_init_module);
1442module_exit(emu10k1_cleanup_module);
1443
1444#ifdef EMU10K1_SEQUENCER
1445
1446/* in midi.c */
1447extern int emu10k1_seq_midi_open(int dev, int mode,
1448 void (*input)(int dev, unsigned char midi_byte),
1449 void (*output)(int dev));
1450extern void emu10k1_seq_midi_close(int dev);
1451extern int emu10k1_seq_midi_out(int dev, unsigned char midi_byte);
1452extern int emu10k1_seq_midi_start_read(int dev);
1453extern int emu10k1_seq_midi_end_read(int dev);
1454extern void emu10k1_seq_midi_kick(int dev);
1455extern int emu10k1_seq_midi_buffer_status(int dev);
1456
1457static struct midi_operations emu10k1_midi_operations =
1458{
1459 THIS_MODULE,
1460 {"EMU10K1 MIDI", 0, 0, SNDCARD_EMU10K1},
1461 &std_midi_synth,
1462 {0},
1463 emu10k1_seq_midi_open,
1464 emu10k1_seq_midi_close,
1465 NULL,
1466 emu10k1_seq_midi_out,
1467 emu10k1_seq_midi_start_read,
1468 emu10k1_seq_midi_end_read,
1469 emu10k1_seq_midi_kick,
1470 NULL,
1471 emu10k1_seq_midi_buffer_status,
1472 NULL
1473};
1474
1475#endif
diff --git a/sound/oss/emu10k1/midi.c b/sound/oss/emu10k1/midi.c
new file mode 100644
index 000000000000..33dea3d56c1e
--- /dev/null
+++ b/sound/oss/emu10k1/midi.c
@@ -0,0 +1,613 @@
1/*
2 **********************************************************************
3 * midi.c - /dev/midi interface for emu10k1 driver
4 * Copyright 1999, 2000 Creative Labs, Inc.
5 *
6 **********************************************************************
7 *
8 * Date Author Summary of changes
9 * ---- ------ ------------------
10 * October 20, 1999 Bertrand Lee base code release
11 *
12 **********************************************************************
13 *
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License as
16 * published by the Free Software Foundation; either version 2 of
17 * the License, or (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public
25 * License along with this program; if not, write to the Free
26 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139,
27 * USA.
28 *
29 **********************************************************************
30 */
31
32#include <linux/module.h>
33#include <linux/poll.h>
34#include <linux/slab.h>
35#include <linux/sched.h>
36#include <linux/smp_lock.h>
37#include <asm/uaccess.h>
38
39#include "hwaccess.h"
40#include "cardmo.h"
41#include "cardmi.h"
42#include "midi.h"
43
44#ifdef EMU10K1_SEQUENCER
45#include "../sound_config.h"
46#endif
47
48static DEFINE_SPINLOCK(midi_spinlock __attribute((unused)));
49
50static void init_midi_hdr(struct midi_hdr *midihdr)
51{
52 midihdr->bufferlength = MIDIIN_BUFLEN;
53 midihdr->bytesrecorded = 0;
54 midihdr->flags = 0;
55}
56
57static int midiin_add_buffer(struct emu10k1_mididevice *midi_dev, struct midi_hdr **midihdrptr)
58{
59 struct midi_hdr *midihdr;
60
61 if ((midihdr = (struct midi_hdr *) kmalloc(sizeof(struct midi_hdr), GFP_KERNEL)) == NULL) {
62 ERROR();
63 return -EINVAL;
64 }
65
66 init_midi_hdr(midihdr);
67
68 if ((midihdr->data = (u8 *) kmalloc(MIDIIN_BUFLEN, GFP_KERNEL)) == NULL) {
69 ERROR();
70 kfree(midihdr);
71 return -1;
72 }
73
74 if (emu10k1_mpuin_add_buffer(midi_dev->card->mpuin, midihdr) < 0) {
75 ERROR();
76 kfree(midihdr->data);
77 kfree(midihdr);
78 return -1;
79 }
80
81 *midihdrptr = midihdr;
82 list_add_tail(&midihdr->list, &midi_dev->mid_hdrs);
83
84 return 0;
85}
86
87static int emu10k1_midi_open(struct inode *inode, struct file *file)
88{
89 int minor = iminor(inode);
90 struct emu10k1_card *card = NULL;
91 struct emu10k1_mididevice *midi_dev;
92 struct list_head *entry;
93
94 DPF(2, "emu10k1_midi_open()\n");
95
96 /* Check for correct device to open */
97 list_for_each(entry, &emu10k1_devs) {
98 card = list_entry(entry, struct emu10k1_card, list);
99
100 if (card->midi_dev == minor)
101 goto match;
102 }
103
104 return -ENODEV;
105
106match:
107#ifdef EMU10K1_SEQUENCER
108 if (card->seq_mididev) /* card is opened by sequencer */
109 return -EBUSY;
110#endif
111
112 /* Wait for device to become free */
113 down(&card->open_sem);
114 while (card->open_mode & (file->f_mode << FMODE_MIDI_SHIFT)) {
115 if (file->f_flags & O_NONBLOCK) {
116 up(&card->open_sem);
117 return -EBUSY;
118 }
119
120 up(&card->open_sem);
121 interruptible_sleep_on(&card->open_wait);
122
123 if (signal_pending(current)) {
124 return -ERESTARTSYS;
125 }
126
127 down(&card->open_sem);
128 }
129
130 if ((midi_dev = (struct emu10k1_mididevice *) kmalloc(sizeof(*midi_dev), GFP_KERNEL)) == NULL)
131 return -EINVAL;
132
133 midi_dev->card = card;
134 midi_dev->mistate = MIDIIN_STATE_STOPPED;
135 init_waitqueue_head(&midi_dev->oWait);
136 init_waitqueue_head(&midi_dev->iWait);
137 midi_dev->ird = 0;
138 midi_dev->iwr = 0;
139 midi_dev->icnt = 0;
140 INIT_LIST_HEAD(&midi_dev->mid_hdrs);
141
142 if (file->f_mode & FMODE_READ) {
143 struct midi_openinfo dsCardMidiOpenInfo;
144 struct midi_hdr *midihdr1;
145 struct midi_hdr *midihdr2;
146
147 dsCardMidiOpenInfo.refdata = (unsigned long) midi_dev;
148
149 if (emu10k1_mpuin_open(card, &dsCardMidiOpenInfo) < 0) {
150 ERROR();
151 kfree(midi_dev);
152 return -ENODEV;
153 }
154
155 /* Add two buffers to receive sysex buffer */
156 if (midiin_add_buffer(midi_dev, &midihdr1) < 0) {
157 kfree(midi_dev);
158 return -ENODEV;
159 }
160
161 if (midiin_add_buffer(midi_dev, &midihdr2) < 0) {
162 list_del(&midihdr1->list);
163 kfree(midihdr1->data);
164 kfree(midihdr1);
165 kfree(midi_dev);
166 return -ENODEV;
167 }
168 }
169
170 if (file->f_mode & FMODE_WRITE) {
171 struct midi_openinfo dsCardMidiOpenInfo;
172
173 dsCardMidiOpenInfo.refdata = (unsigned long) midi_dev;
174
175 if (emu10k1_mpuout_open(card, &dsCardMidiOpenInfo) < 0) {
176 ERROR();
177 kfree(midi_dev);
178 return -ENODEV;
179 }
180 }
181
182 file->private_data = (void *) midi_dev;
183
184 card->open_mode |= (file->f_mode << FMODE_MIDI_SHIFT) & (FMODE_MIDI_READ | FMODE_MIDI_WRITE);
185
186 up(&card->open_sem);
187
188 return nonseekable_open(inode, file);
189}
190
191static int emu10k1_midi_release(struct inode *inode, struct file *file)
192{
193 struct emu10k1_mididevice *midi_dev = (struct emu10k1_mididevice *) file->private_data;
194 struct emu10k1_card *card;
195
196 lock_kernel();
197
198 card = midi_dev->card;
199 DPF(2, "emu10k1_midi_release()\n");
200
201 if (file->f_mode & FMODE_WRITE) {
202 if (!(file->f_flags & O_NONBLOCK)) {
203
204 while (!signal_pending(current) && (card->mpuout->firstmidiq != NULL)) {
205 DPF(4, "Cannot close - buffers not empty\n");
206
207 interruptible_sleep_on(&midi_dev->oWait);
208
209 }
210 }
211
212 emu10k1_mpuout_close(card);
213 }
214
215 if (file->f_mode & FMODE_READ) {
216 struct midi_hdr *midihdr;
217
218 if (midi_dev->mistate == MIDIIN_STATE_STARTED) {
219 emu10k1_mpuin_stop(card);
220 midi_dev->mistate = MIDIIN_STATE_STOPPED;
221 }
222
223 emu10k1_mpuin_reset(card);
224 emu10k1_mpuin_close(card);
225
226 while (!list_empty(&midi_dev->mid_hdrs)) {
227 midihdr = list_entry(midi_dev->mid_hdrs.next, struct midi_hdr, list);
228
229 list_del(midi_dev->mid_hdrs.next);
230 kfree(midihdr->data);
231 kfree(midihdr);
232 }
233 }
234
235 kfree(midi_dev);
236
237 down(&card->open_sem);
238 card->open_mode &= ~((file->f_mode << FMODE_MIDI_SHIFT) & (FMODE_MIDI_READ | FMODE_MIDI_WRITE));
239 up(&card->open_sem);
240 wake_up_interruptible(&card->open_wait);
241
242 unlock_kernel();
243
244 return 0;
245}
246
247static ssize_t emu10k1_midi_read(struct file *file, char __user *buffer, size_t count, loff_t * pos)
248{
249 struct emu10k1_mididevice *midi_dev = (struct emu10k1_mididevice *) file->private_data;
250 ssize_t ret = 0;
251 u16 cnt;
252 unsigned long flags;
253
254 DPD(4, "emu10k1_midi_read(), count %#x\n", (u32) count);
255
256 if (!access_ok(VERIFY_WRITE, buffer, count))
257 return -EFAULT;
258
259 if (midi_dev->mistate == MIDIIN_STATE_STOPPED) {
260 if (emu10k1_mpuin_start(midi_dev->card) < 0) {
261 ERROR();
262 return -EINVAL;
263 }
264
265 midi_dev->mistate = MIDIIN_STATE_STARTED;
266 }
267
268 while (count > 0) {
269 cnt = MIDIIN_BUFLEN - midi_dev->ird;
270
271 spin_lock_irqsave(&midi_spinlock, flags);
272
273 if (midi_dev->icnt < cnt)
274 cnt = midi_dev->icnt;
275
276 spin_unlock_irqrestore(&midi_spinlock, flags);
277
278 if (cnt > count)
279 cnt = count;
280
281 if (cnt <= 0) {
282 if (file->f_flags & O_NONBLOCK)
283 return ret ? ret : -EAGAIN;
284 DPF(2, " Go to sleep...\n");
285
286 interruptible_sleep_on(&midi_dev->iWait);
287
288 if (signal_pending(current))
289 return ret ? ret : -ERESTARTSYS;
290
291 continue;
292 }
293
294 if (copy_to_user(buffer, midi_dev->iBuf + midi_dev->ird, cnt)) {
295 ERROR();
296 return ret ? ret : -EFAULT;
297 }
298
299 midi_dev->ird += cnt;
300 midi_dev->ird %= MIDIIN_BUFLEN;
301
302 spin_lock_irqsave(&midi_spinlock, flags);
303
304 midi_dev->icnt -= cnt;
305
306 spin_unlock_irqrestore(&midi_spinlock, flags);
307
308 count -= cnt;
309 buffer += cnt;
310 ret += cnt;
311
312 if (midi_dev->icnt == 0)
313 break;
314 }
315
316 return ret;
317}
318
319static ssize_t emu10k1_midi_write(struct file *file, const char __user *buffer, size_t count, loff_t * pos)
320{
321 struct emu10k1_mididevice *midi_dev = (struct emu10k1_mididevice *) file->private_data;
322 struct midi_hdr *midihdr;
323 unsigned long flags;
324
325 DPD(4, "emu10k1_midi_write(), count=%#x\n", (u32) count);
326
327 if (!access_ok(VERIFY_READ, buffer, count))
328 return -EFAULT;
329
330 if ((midihdr = (struct midi_hdr *) kmalloc(sizeof(struct midi_hdr), GFP_KERNEL)) == NULL)
331 return -EINVAL;
332
333 midihdr->bufferlength = count;
334 midihdr->bytesrecorded = 0;
335 midihdr->flags = 0;
336
337 if ((midihdr->data = (u8 *) kmalloc(count, GFP_KERNEL)) == NULL) {
338 ERROR();
339 kfree(midihdr);
340 return -EINVAL;
341 }
342
343 if (copy_from_user(midihdr->data, buffer, count)) {
344 kfree(midihdr->data);
345 kfree(midihdr);
346 return -EFAULT;
347 }
348
349 spin_lock_irqsave(&midi_spinlock, flags);
350
351 if (emu10k1_mpuout_add_buffer(midi_dev->card, midihdr) < 0) {
352 ERROR();
353 kfree(midihdr->data);
354 kfree(midihdr);
355 spin_unlock_irqrestore(&midi_spinlock, flags);
356 return -EINVAL;
357 }
358
359 spin_unlock_irqrestore(&midi_spinlock, flags);
360
361 return count;
362}
363
364static unsigned int emu10k1_midi_poll(struct file *file, struct poll_table_struct *wait)
365{
366 struct emu10k1_mididevice *midi_dev = (struct emu10k1_mididevice *) file->private_data;
367 unsigned long flags;
368 unsigned int mask = 0;
369
370 DPF(4, "emu10k1_midi_poll() called\n");
371
372 if (file->f_mode & FMODE_WRITE)
373 poll_wait(file, &midi_dev->oWait, wait);
374
375 if (file->f_mode & FMODE_READ)
376 poll_wait(file, &midi_dev->iWait, wait);
377
378 spin_lock_irqsave(&midi_spinlock, flags);
379
380 if (file->f_mode & FMODE_WRITE)
381 mask |= POLLOUT | POLLWRNORM;
382
383 if (file->f_mode & FMODE_READ) {
384 if (midi_dev->mistate == MIDIIN_STATE_STARTED)
385 if (midi_dev->icnt > 0)
386 mask |= POLLIN | POLLRDNORM;
387 }
388
389 spin_unlock_irqrestore(&midi_spinlock, flags);
390
391 return mask;
392}
393
394int emu10k1_midi_callback(unsigned long msg, unsigned long refdata, unsigned long *pmsg)
395{
396 struct emu10k1_mididevice *midi_dev = (struct emu10k1_mididevice *) refdata;
397 struct midi_hdr *midihdr = NULL;
398 unsigned long flags;
399 int i;
400
401 DPF(4, "emu10k1_midi_callback()\n");
402
403 spin_lock_irqsave(&midi_spinlock, flags);
404
405 switch (msg) {
406 case ICARDMIDI_OUTLONGDATA:
407 midihdr = (struct midi_hdr *) pmsg[2];
408
409 kfree(midihdr->data);
410 kfree(midihdr);
411 wake_up_interruptible(&midi_dev->oWait);
412
413 break;
414
415 case ICARDMIDI_INLONGDATA:
416 midihdr = (struct midi_hdr *) pmsg[2];
417
418 for (i = 0; i < midihdr->bytesrecorded; i++) {
419 midi_dev->iBuf[midi_dev->iwr++] = midihdr->data[i];
420 midi_dev->iwr %= MIDIIN_BUFLEN;
421 }
422
423 midi_dev->icnt += midihdr->bytesrecorded;
424
425 if (midi_dev->mistate == MIDIIN_STATE_STARTED) {
426 init_midi_hdr(midihdr);
427 emu10k1_mpuin_add_buffer(midi_dev->card->mpuin, midihdr);
428 wake_up_interruptible(&midi_dev->iWait);
429 }
430 break;
431
432 case ICARDMIDI_INDATA:
433 {
434 u8 *pBuf = (u8 *) & pmsg[1];
435 u16 bytesvalid = pmsg[2];
436
437 for (i = 0; i < bytesvalid; i++) {
438 midi_dev->iBuf[midi_dev->iwr++] = pBuf[i];
439 midi_dev->iwr %= MIDIIN_BUFLEN;
440 }
441
442 midi_dev->icnt += bytesvalid;
443 }
444
445 wake_up_interruptible(&midi_dev->iWait);
446 break;
447
448 default: /* Unknown message */
449 spin_unlock_irqrestore(&midi_spinlock, flags);
450 return -1;
451 }
452
453 spin_unlock_irqrestore(&midi_spinlock, flags);
454
455 return 0;
456}
457
458/* MIDI file operations */
459struct file_operations emu10k1_midi_fops = {
460 .owner = THIS_MODULE,
461 .read = emu10k1_midi_read,
462 .write = emu10k1_midi_write,
463 .poll = emu10k1_midi_poll,
464 .open = emu10k1_midi_open,
465 .release = emu10k1_midi_release,
466};
467
468
469#ifdef EMU10K1_SEQUENCER
470
471/* functions used for sequencer access */
472
473int emu10k1_seq_midi_open(int dev, int mode,
474 void (*input) (int dev, unsigned char data),
475 void (*output) (int dev))
476{
477 struct emu10k1_card *card;
478 struct midi_openinfo dsCardMidiOpenInfo;
479 struct emu10k1_mididevice *midi_dev;
480
481 if (midi_devs[dev] == NULL || midi_devs[dev]->devc == NULL)
482 return -EINVAL;
483
484 card = midi_devs[dev]->devc;
485
486 if (card->open_mode) /* card is opened native */
487 return -EBUSY;
488
489 DPF(2, "emu10k1_seq_midi_open()\n");
490
491 if ((midi_dev = (struct emu10k1_mididevice *) kmalloc(sizeof(*midi_dev), GFP_KERNEL)) == NULL)
492 return -EINVAL;
493
494 midi_dev->card = card;
495 midi_dev->mistate = MIDIIN_STATE_STOPPED;
496 init_waitqueue_head(&midi_dev->oWait);
497 init_waitqueue_head(&midi_dev->iWait);
498 midi_dev->ird = 0;
499 midi_dev->iwr = 0;
500 midi_dev->icnt = 0;
501 INIT_LIST_HEAD(&midi_dev->mid_hdrs);
502
503 dsCardMidiOpenInfo.refdata = (unsigned long) midi_dev;
504
505 if (emu10k1_mpuout_open(card, &dsCardMidiOpenInfo) < 0) {
506 ERROR();
507 return -ENODEV;
508 }
509
510 card->seq_mididev = midi_dev;
511
512 return 0;
513}
514
515void emu10k1_seq_midi_close(int dev)
516{
517 struct emu10k1_card *card;
518
519 DPF(2, "emu10k1_seq_midi_close()\n");
520 if (midi_devs[dev] == NULL || midi_devs[dev]->devc == NULL)
521 return;
522
523 card = midi_devs[dev]->devc;
524 emu10k1_mpuout_close(card);
525
526 if (card->seq_mididev) {
527 kfree(card->seq_mididev);
528 card->seq_mididev = NULL;
529 }
530}
531
532int emu10k1_seq_midi_out(int dev, unsigned char midi_byte)
533{
534 struct emu10k1_card *card;
535 struct midi_hdr *midihdr;
536 unsigned long flags;
537
538 if (midi_devs[dev] == NULL || midi_devs[dev]->devc == NULL)
539 return -EINVAL;
540
541 card = midi_devs[dev]->devc;
542
543 if ((midihdr = (struct midi_hdr *) kmalloc(sizeof(struct midi_hdr), GFP_KERNEL)) == NULL)
544 return -EINVAL;
545
546 midihdr->bufferlength = 1;
547 midihdr->bytesrecorded = 0;
548 midihdr->flags = 0;
549
550 if ((midihdr->data = (u8 *) kmalloc(1, GFP_KERNEL)) == NULL) {
551 ERROR();
552 kfree(midihdr);
553 return -EINVAL;
554 }
555
556 *(midihdr->data) = midi_byte;
557
558 spin_lock_irqsave(&midi_spinlock, flags);
559
560 if (emu10k1_mpuout_add_buffer(card, midihdr) < 0) {
561 ERROR();
562 kfree(midihdr->data);
563 kfree(midihdr);
564 spin_unlock_irqrestore(&midi_spinlock, flags);
565 return -EINVAL;
566 }
567
568 spin_unlock_irqrestore(&midi_spinlock, flags);
569
570 return 1;
571}
572
573int emu10k1_seq_midi_start_read(int dev)
574{
575 return 0;
576}
577
578int emu10k1_seq_midi_end_read(int dev)
579{
580 return 0;
581}
582
583void emu10k1_seq_midi_kick(int dev)
584{
585}
586
587int emu10k1_seq_midi_buffer_status(int dev)
588{
589 int count;
590 struct midi_queue *queue;
591 struct emu10k1_card *card;
592
593 if (midi_devs[dev] == NULL || midi_devs[dev]->devc == NULL)
594 return -EINVAL;
595
596 count = 0;
597
598 card = midi_devs[dev]->devc;
599 queue = card->mpuout->firstmidiq;
600
601 while (queue != NULL) {
602 count++;
603 if (queue == card->mpuout->lastmidiq)
604 break;
605
606 queue = queue->next;
607 }
608
609 return count;
610}
611
612#endif
613
diff --git a/sound/oss/emu10k1/midi.h b/sound/oss/emu10k1/midi.h
new file mode 100644
index 000000000000..2459ec929e8d
--- /dev/null
+++ b/sound/oss/emu10k1/midi.h
@@ -0,0 +1,78 @@
1/*
2 **********************************************************************
3 * midi.h
4 * Copyright 1999, 2000 Creative Labs, Inc.
5 *
6 **********************************************************************
7 *
8 * Date Author Summary of changes
9 * ---- ------ ------------------
10 * October 20, 1999 Bertrand Lee base code release
11 *
12 **********************************************************************
13 *
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License as
16 * published by the Free Software Foundation; either version 2 of
17 * the License, or (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public
25 * License along with this program; if not, write to the Free
26 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139,
27 * USA.
28 *
29 **********************************************************************
30 */
31
32#ifndef _MIDI_H
33#define _MIDI_H
34
35#define FMODE_MIDI_SHIFT 3
36#define FMODE_MIDI_READ (FMODE_READ << FMODE_MIDI_SHIFT)
37#define FMODE_MIDI_WRITE (FMODE_WRITE << FMODE_MIDI_SHIFT)
38
39#define MIDIIN_STATE_STARTED 0x00000001
40#define MIDIIN_STATE_STOPPED 0x00000002
41
42#define MIDIIN_BUFLEN 1024
43
44struct emu10k1_mididevice
45{
46 struct emu10k1_card *card;
47 u32 mistate;
48 wait_queue_head_t oWait;
49 wait_queue_head_t iWait;
50 s8 iBuf[MIDIIN_BUFLEN];
51 u16 ird, iwr, icnt;
52 struct list_head mid_hdrs;
53};
54
55/* uncomment next line to use midi port on Audigy drive */
56//#define USE_AUDIGY_DRIVE_MIDI
57
58#ifdef USE_AUDIGY_DRIVE_MIDI
59#define A_MUDATA A_MUDATA2
60#define A_MUCMD A_MUCMD2
61#define A_MUSTAT A_MUCMD2
62#define A_IPR_MIDITRANSBUFEMPTY A_IPR_MIDITRANSBUFEMPTY2
63#define A_IPR_MIDIRECVBUFEMPTY A_IPR_MIDIRECVBUFEMPTY2
64#define A_INTE_MIDITXENABLE A_INTE_MIDITXENABLE2
65#define A_INTE_MIDIRXENABLE A_INTE_MIDIRXENABLE2
66#else
67#define A_MUDATA A_MUDATA1
68#define A_MUCMD A_MUCMD1
69#define A_MUSTAT A_MUCMD1
70#define A_IPR_MIDITRANSBUFEMPTY A_IPR_MIDITRANSBUFEMPTY1
71#define A_IPR_MIDIRECVBUFEMPTY A_IPR_MIDIRECVBUFEMPTY1
72#define A_INTE_MIDITXENABLE A_INTE_MIDITXENABLE1
73#define A_INTE_MIDIRXENABLE A_INTE_MIDIRXENABLE1
74#endif
75
76
77#endif /* _MIDI_H */
78
diff --git a/sound/oss/emu10k1/mixer.c b/sound/oss/emu10k1/mixer.c
new file mode 100644
index 000000000000..cbcaaa34189a
--- /dev/null
+++ b/sound/oss/emu10k1/mixer.c
@@ -0,0 +1,690 @@
1/*
2 **********************************************************************
3 * mixer.c - /dev/mixer interface for emu10k1 driver
4 * Copyright 1999, 2000 Creative Labs, Inc.
5 *
6 **********************************************************************
7 *
8 * Date Author Summary of changes
9 * ---- ------ ------------------
10 * October 20, 1999 Bertrand Lee base code release
11 * November 2, 1999 Alan Cox cleaned up stuff
12 *
13 **********************************************************************
14 *
15 * This program is free software; you can redistribute it and/or
16 * modify it under the terms of the GNU General Public License as
17 * published by the Free Software Foundation; either version 2 of
18 * the License, or (at your option) any later version.
19 *
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public
26 * License along with this program; if not, write to the Free
27 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139,
28 * USA.
29 *
30 **********************************************************************
31 */
32
33#include <linux/module.h>
34#include <asm/uaccess.h>
35#include <linux/fs.h>
36
37#include "hwaccess.h"
38#include "8010.h"
39#include "recmgr.h"
40
41
42static const u32 bass_table[41][5] = {
43 { 0x3e4f844f, 0x84ed4cc3, 0x3cc69927, 0x7b03553a, 0xc4da8486 },
44 { 0x3e69a17a, 0x84c280fb, 0x3cd77cd4, 0x7b2f2a6f, 0xc4b08d1d },
45 { 0x3e82ff42, 0x849991d5, 0x3ce7466b, 0x7b5917c6, 0xc48863ee },
46 { 0x3e9bab3c, 0x847267f0, 0x3cf5ffe8, 0x7b813560, 0xc461f22c },
47 { 0x3eb3b275, 0x844ced29, 0x3d03b295, 0x7ba79a1c, 0xc43d223b },
48 { 0x3ecb2174, 0x84290c8b, 0x3d106714, 0x7bcc5ba3, 0xc419dfa5 },
49 { 0x3ee2044b, 0x8406b244, 0x3d1c2561, 0x7bef8e77, 0xc3f8170f },
50 { 0x3ef86698, 0x83e5cb96, 0x3d26f4d8, 0x7c114600, 0xc3d7b625 },
51 { 0x3f0e5390, 0x83c646c9, 0x3d30dc39, 0x7c319498, 0xc3b8ab97 },
52 { 0x3f23d60b, 0x83a81321, 0x3d39e1af, 0x7c508b9c, 0xc39ae704 },
53 { 0x3f38f884, 0x838b20d2, 0x3d420ad2, 0x7c6e3b75, 0xc37e58f1 },
54 { 0x3f4dc52c, 0x836f60ef, 0x3d495cab, 0x7c8ab3a6, 0xc362f2be },
55 { 0x3f6245e8, 0x8354c565, 0x3d4fdbb8, 0x7ca602d6, 0xc348a69b },
56 { 0x3f76845f, 0x833b40ec, 0x3d558bf0, 0x7cc036df, 0xc32f677c },
57 { 0x3f8a8a03, 0x8322c6fb, 0x3d5a70c4, 0x7cd95cd7, 0xc317290b },
58 { 0x3f9e6014, 0x830b4bc3, 0x3d5e8d25, 0x7cf1811a, 0xc2ffdfa5 },
59 { 0x3fb20fae, 0x82f4c420, 0x3d61e37f, 0x7d08af56, 0xc2e9804a },
60 { 0x3fc5a1cc, 0x82df2592, 0x3d6475c3, 0x7d1ef294, 0xc2d40096 },
61 { 0x3fd91f55, 0x82ca6632, 0x3d664564, 0x7d345541, 0xc2bf56b9 },
62 { 0x3fec9120, 0x82b67cac, 0x3d675356, 0x7d48e138, 0xc2ab796e },
63 { 0x40000000, 0x82a36037, 0x3d67a012, 0x7d5c9fc9, 0xc2985fee },
64 { 0x401374c7, 0x8291088a, 0x3d672b93, 0x7d6f99c3, 0xc28601f2 },
65 { 0x4026f857, 0x827f6dd7, 0x3d65f559, 0x7d81d77c, 0xc27457a3 },
66 { 0x403a939f, 0x826e88c5, 0x3d63fc63, 0x7d9360d4, 0xc2635996 },
67 { 0x404e4faf, 0x825e5266, 0x3d613f32, 0x7da43d42, 0xc25300c6 },
68 { 0x406235ba, 0x824ec434, 0x3d5dbbc3, 0x7db473d7, 0xc243468e },
69 { 0x40764f1f, 0x823fd80c, 0x3d596f8f, 0x7dc40b44, 0xc23424a2 },
70 { 0x408aa576, 0x82318824, 0x3d545787, 0x7dd309e2, 0xc2259509 },
71 { 0x409f4296, 0x8223cf0b, 0x3d4e7012, 0x7de175b5, 0xc2179218 },
72 { 0x40b430a0, 0x8216a7a1, 0x3d47b505, 0x7def5475, 0xc20a1670 },
73 { 0x40c97a0a, 0x820a0d12, 0x3d4021a1, 0x7dfcab8d, 0xc1fd1cf5 },
74 { 0x40df29a6, 0x81fdfad6, 0x3d37b08d, 0x7e098028, 0xc1f0a0ca },
75 { 0x40f54ab1, 0x81f26ca9, 0x3d2e5bd1, 0x7e15d72b, 0xc1e49d52 },
76 { 0x410be8da, 0x81e75e89, 0x3d241cce, 0x7e21b544, 0xc1d90e24 },
77 { 0x41231051, 0x81dcccb3, 0x3d18ec37, 0x7e2d1ee6, 0xc1cdef10 },
78 { 0x413acdd0, 0x81d2b39e, 0x3d0cc20a, 0x7e38184e, 0xc1c33c13 },
79 { 0x41532ea7, 0x81c90ffb, 0x3cff9585, 0x7e42a58b, 0xc1b8f15a },
80 { 0x416c40cd, 0x81bfdeb2, 0x3cf15d21, 0x7e4cca7c, 0xc1af0b3f },
81 { 0x418612ea, 0x81b71cdc, 0x3ce20e85, 0x7e568ad3, 0xc1a58640 },
82 { 0x41a0b465, 0x81aec7c5, 0x3cd19e7c, 0x7e5fea1e, 0xc19c5f03 },
83 { 0x41bc3573, 0x81a6dcea, 0x3cc000e9, 0x7e68ebc2, 0xc1939250 }
84};
85
86static const u32 treble_table[41][5] = {
87 { 0x0125cba9, 0xfed5debd, 0x00599b6c, 0x0d2506da, 0xfa85b354 },
88 { 0x0142f67e, 0xfeb03163, 0x0066cd0f, 0x0d14c69d, 0xfa914473 },
89 { 0x016328bd, 0xfe860158, 0x0075b7f2, 0x0d03eb27, 0xfa9d32d2 },
90 { 0x0186b438, 0xfe56c982, 0x00869234, 0x0cf27048, 0xfaa97fca },
91 { 0x01adf358, 0xfe21f5fe, 0x00999842, 0x0ce051c2, 0xfab62ca5 },
92 { 0x01d949fa, 0xfde6e287, 0x00af0d8d, 0x0ccd8b4a, 0xfac33aa7 },
93 { 0x02092669, 0xfda4d8bf, 0x00c73d4c, 0x0cba1884, 0xfad0ab07 },
94 { 0x023e0268, 0xfd5b0e4a, 0x00e27b54, 0x0ca5f509, 0xfade7ef2 },
95 { 0x0278645c, 0xfd08a2b0, 0x01012509, 0x0c911c63, 0xfaecb788 },
96 { 0x02b8e091, 0xfcac9d1a, 0x0123a262, 0x0c7b8a14, 0xfafb55df },
97 { 0x03001a9a, 0xfc45e9ce, 0x014a6709, 0x0c65398f, 0xfb0a5aff },
98 { 0x034ec6d7, 0xfbd3576b, 0x0175f397, 0x0c4e2643, 0xfb19c7e4 },
99 { 0x03a5ac15, 0xfb5393ee, 0x01a6d6ed, 0x0c364b94, 0xfb299d7c },
100 { 0x0405a562, 0xfac52968, 0x01ddafae, 0x0c1da4e2, 0xfb39dca5 },
101 { 0x046fa3fe, 0xfa267a66, 0x021b2ddd, 0x0c042d8d, 0xfb4a8631 },
102 { 0x04e4b17f, 0xf975be0f, 0x0260149f, 0x0be9e0f2, 0xfb5b9ae0 },
103 { 0x0565f220, 0xf8b0fbe5, 0x02ad3c29, 0x0bceba73, 0xfb6d1b60 },
104 { 0x05f4a745, 0xf7d60722, 0x030393d4, 0x0bb2b578, 0xfb7f084d },
105 { 0x06923236, 0xf6e279bd, 0x03642465, 0x0b95cd75, 0xfb916233 },
106 { 0x07401713, 0xf5d3aef9, 0x03d01283, 0x0b77fded, 0xfba42984 },
107 { 0x08000000, 0xf4a6bd88, 0x0448a161, 0x0b594278, 0xfbb75e9f },
108 { 0x08d3c097, 0xf3587131, 0x04cf35a4, 0x0b3996c9, 0xfbcb01cb },
109 { 0x09bd59a2, 0xf1e543f9, 0x05655880, 0x0b18f6b2, 0xfbdf1333 },
110 { 0x0abefd0f, 0xf04956ca, 0x060cbb12, 0x0af75e2c, 0xfbf392e8 },
111 { 0x0bdb123e, 0xee806984, 0x06c739fe, 0x0ad4c962, 0xfc0880dd },
112 { 0x0d143a94, 0xec85d287, 0x0796e150, 0x0ab134b0, 0xfc1ddce5 },
113 { 0x0e6d5664, 0xea547598, 0x087df0a0, 0x0a8c9cb6, 0xfc33a6ad },
114 { 0x0fe98a2a, 0xe7e6ba35, 0x097edf83, 0x0a66fe5b, 0xfc49ddc2 },
115 { 0x118c4421, 0xe536813a, 0x0a9c6248, 0x0a4056d7, 0xfc608185 },
116 { 0x1359422e, 0xe23d19eb, 0x0bd96efb, 0x0a18a3bf, 0xfc77912c },
117 { 0x1554982b, 0xdef33645, 0x0d3942bd, 0x09efe312, 0xfc8f0bc1 },
118 { 0x1782b68a, 0xdb50deb1, 0x0ebf676d, 0x09c6133f, 0xfca6f019 },
119 { 0x19e8715d, 0xd74d64fd, 0x106fb999, 0x099b3337, 0xfcbf3cd6 },
120 { 0x1c8b07b8, 0xd2df56ab, 0x124e6ec8, 0x096f4274, 0xfcd7f060 },
121 { 0x1f702b6d, 0xcdfc6e92, 0x14601c10, 0x0942410b, 0xfcf108e5 },
122 { 0x229e0933, 0xc89985cd, 0x16a9bcfa, 0x09142fb5, 0xfd0a8451 },
123 { 0x261b5118, 0xc2aa8409, 0x1930bab6, 0x08e50fdc, 0xfd24604d },
124 { 0x29ef3f5d, 0xbc224f28, 0x1bfaf396, 0x08b4e3aa, 0xfd3e9a3b },
125 { 0x2e21a59b, 0xb4f2ba46, 0x1f0ec2d6, 0x0883ae15, 0xfd592f33 },
126 { 0x32baf44b, 0xad0c7429, 0x227308a3, 0x085172eb, 0xfd741bfd },
127 { 0x37c4448b, 0xa45ef51d, 0x262f3267, 0x081e36dc, 0xfd8f5d14 }
128};
129
130
131static void set_bass(struct emu10k1_card *card, int l, int r)
132{
133 int i;
134
135 l = (l * 40 + 50) / 100;
136 r = (r * 40 + 50) / 100;
137
138 for (i = 0; i < 5; i++)
139 sblive_writeptr(card, (card->is_audigy ? A_GPR_BASE : GPR_BASE) + card->mgr.ctrl_gpr[SOUND_MIXER_BASS][0] + i, 0, bass_table[l][i]);
140}
141
142static void set_treble(struct emu10k1_card *card, int l, int r)
143{
144 int i;
145
146 l = (l * 40 + 50) / 100;
147 r = (r * 40 + 50) / 100;
148
149 for (i = 0; i < 5; i++)
150 sblive_writeptr(card, (card->is_audigy ? A_GPR_BASE : GPR_BASE) + card->mgr.ctrl_gpr[SOUND_MIXER_TREBLE][0] + i , 0, treble_table[l][i]);
151}
152
153const char volume_params[SOUND_MIXER_NRDEVICES]= {
154/* Used by the ac97 driver */
155 [SOUND_MIXER_VOLUME] = VOL_6BIT,
156 [SOUND_MIXER_BASS] = VOL_4BIT,
157 [SOUND_MIXER_TREBLE] = VOL_4BIT,
158 [SOUND_MIXER_PCM] = VOL_5BIT,
159 [SOUND_MIXER_SPEAKER] = VOL_4BIT,
160 [SOUND_MIXER_LINE] = VOL_5BIT,
161 [SOUND_MIXER_MIC] = VOL_5BIT,
162 [SOUND_MIXER_CD] = VOL_5BIT,
163 [SOUND_MIXER_ALTPCM] = VOL_6BIT,
164 [SOUND_MIXER_IGAIN] = VOL_4BIT,
165 [SOUND_MIXER_LINE1] = VOL_5BIT,
166 [SOUND_MIXER_PHONEIN] = VOL_5BIT,
167 [SOUND_MIXER_PHONEOUT] = VOL_6BIT,
168 [SOUND_MIXER_VIDEO] = VOL_5BIT,
169/* Not used by the ac97 driver */
170 [SOUND_MIXER_SYNTH] = VOL_5BIT,
171 [SOUND_MIXER_IMIX] = VOL_5BIT,
172 [SOUND_MIXER_RECLEV] = VOL_5BIT,
173 [SOUND_MIXER_OGAIN] = VOL_5BIT,
174 [SOUND_MIXER_LINE2] = VOL_5BIT,
175 [SOUND_MIXER_LINE3] = VOL_5BIT,
176 [SOUND_MIXER_DIGITAL1] = VOL_5BIT,
177 [SOUND_MIXER_DIGITAL2] = VOL_5BIT,
178 [SOUND_MIXER_DIGITAL3] = VOL_5BIT,
179 [SOUND_MIXER_RADIO] = VOL_5BIT,
180 [SOUND_MIXER_MONITOR] = VOL_5BIT
181};
182
183/* Mixer file operations */
184static int emu10k1_private_mixer(struct emu10k1_card *card, unsigned int cmd, unsigned long arg)
185{
186 struct mixer_private_ioctl *ctl;
187 struct dsp_patch *patch;
188 u32 size, page;
189 int addr, size_reg, i, ret;
190 unsigned int id, ch;
191 void __user *argp = (void __user *)arg;
192
193 switch (cmd) {
194
195 case SOUND_MIXER_PRIVATE3:
196
197 ctl = (struct mixer_private_ioctl *) kmalloc(sizeof(struct mixer_private_ioctl), GFP_KERNEL);
198 if (ctl == NULL)
199 return -ENOMEM;
200
201 if (copy_from_user(ctl, argp, sizeof(struct mixer_private_ioctl))) {
202 kfree(ctl);
203 return -EFAULT;
204 }
205
206 ret = 0;
207 switch (ctl->cmd) {
208#ifdef DBGEMU
209 case CMD_WRITEFN0:
210 emu10k1_writefn0_2(card, ctl->val[0], ctl->val[1], ctl->val[2]);
211 break;
212#endif
213 case CMD_WRITEPTR:
214#ifdef DBGEMU
215 if (ctl->val[1] >= 0x40 || ctl->val[0] >= 0x1000) {
216#else
217 if (ctl->val[1] >= 0x40 || ctl->val[0] >= 0x1000 || ((ctl->val[0] < 0x100 ) &&
218 //Any register allowed raw access goes here:
219 (ctl->val[0] != A_SPDIF_SAMPLERATE) && (ctl->val[0] != A_DBG)
220 )
221 ) {
222#endif
223 ret = -EINVAL;
224 break;
225 }
226 sblive_writeptr(card, ctl->val[0], ctl->val[1], ctl->val[2]);
227 break;
228
229 case CMD_READFN0:
230 ctl->val[2] = emu10k1_readfn0(card, ctl->val[0]);
231
232 if (copy_to_user(argp, ctl, sizeof(struct mixer_private_ioctl)))
233 ret = -EFAULT;
234
235 break;
236
237 case CMD_READPTR:
238 if (ctl->val[1] >= 0x40 || (ctl->val[0] & 0x7ff) > 0xff) {
239 ret = -EINVAL;
240 break;
241 }
242
243 if ((ctl->val[0] & 0x7ff) > 0x3f)
244 ctl->val[1] = 0x00;
245
246 ctl->val[2] = sblive_readptr(card, ctl->val[0], ctl->val[1]);
247
248 if (copy_to_user(argp, ctl, sizeof(struct mixer_private_ioctl)))
249 ret = -EFAULT;
250
251 break;
252
253 case CMD_SETRECSRC:
254 switch (ctl->val[0]) {
255 case WAVERECORD_AC97:
256 if (card->is_aps) {
257 ret = -EINVAL;
258 break;
259 }
260
261 card->wavein.recsrc = WAVERECORD_AC97;
262 break;
263
264 case WAVERECORD_MIC:
265 card->wavein.recsrc = WAVERECORD_MIC;
266 break;
267
268 case WAVERECORD_FX:
269 card->wavein.recsrc = WAVERECORD_FX;
270 card->wavein.fxwc = ctl->val[1] & 0xffff;
271
272 if (!card->wavein.fxwc)
273 ret = -EINVAL;
274
275 break;
276
277 default:
278 ret = -EINVAL;
279 break;
280 }
281 break;
282
283 case CMD_GETRECSRC:
284 ctl->val[0] = card->wavein.recsrc;
285 ctl->val[1] = card->wavein.fxwc;
286 if (copy_to_user(argp, ctl, sizeof(struct mixer_private_ioctl)))
287 ret = -EFAULT;
288
289 break;
290
291 case CMD_GETVOICEPARAM:
292 ctl->val[0] = card->waveout.send_routing[0];
293 ctl->val[1] = card->waveout.send_dcba[0];
294
295 ctl->val[2] = card->waveout.send_routing[1];
296 ctl->val[3] = card->waveout.send_dcba[1];
297
298 ctl->val[4] = card->waveout.send_routing[2];
299 ctl->val[5] = card->waveout.send_dcba[2];
300
301 if (copy_to_user(argp, ctl, sizeof(struct mixer_private_ioctl)))
302 ret = -EFAULT;
303
304 break;
305
306 case CMD_SETVOICEPARAM:
307 card->waveout.send_routing[0] = ctl->val[0];
308 card->waveout.send_dcba[0] = ctl->val[1];
309
310 card->waveout.send_routing[1] = ctl->val[2];
311 card->waveout.send_dcba[1] = ctl->val[3];
312
313 card->waveout.send_routing[2] = ctl->val[4];
314 card->waveout.send_dcba[2] = ctl->val[5];
315
316 break;
317
318 case CMD_SETMCH_FX:
319 card->mchannel_fx = ctl->val[0] & 0x000f;
320 break;
321
322 case CMD_GETPATCH:
323 if (ctl->val[0] == 0) {
324 if (copy_to_user(argp, &card->mgr.rpatch, sizeof(struct dsp_rpatch)))
325 ret = -EFAULT;
326 } else {
327 if ((ctl->val[0] - 1) / PATCHES_PER_PAGE >= card->mgr.current_pages) {
328 ret = -EINVAL;
329 break;
330 }
331
332 if (copy_to_user(argp, PATCH(&card->mgr, ctl->val[0] - 1), sizeof(struct dsp_patch)))
333 ret = -EFAULT;
334 }
335
336 break;
337
338 case CMD_GETGPR:
339 id = ctl->val[0];
340
341 if (id > NUM_GPRS) {
342 ret = -EINVAL;
343 break;
344 }
345
346 if (copy_to_user(argp, &card->mgr.gpr[id], sizeof(struct dsp_gpr)))
347 ret = -EFAULT;
348
349 break;
350
351 case CMD_GETCTLGPR:
352 addr = emu10k1_find_control_gpr(&card->mgr, (char *) ctl->val, &((char *) ctl->val)[PATCH_NAME_SIZE]);
353 ctl->val[0] = sblive_readptr(card, addr, 0);
354
355 if (copy_to_user(argp, ctl, sizeof(struct mixer_private_ioctl)))
356 ret = -EFAULT;
357
358 break;
359
360 case CMD_SETPATCH:
361 if (ctl->val[0] == 0)
362 memcpy(&card->mgr.rpatch, &ctl->val[1], sizeof(struct dsp_rpatch));
363 else {
364 page = (ctl->val[0] - 1) / PATCHES_PER_PAGE;
365 if (page > MAX_PATCHES_PAGES) {
366 ret = -EINVAL;
367 break;
368 }
369
370 if (page >= card->mgr.current_pages) {
371 for (i = card->mgr.current_pages; i < page + 1; i++) {
372 card->mgr.patch[i] = (void *)__get_free_page(GFP_KERNEL);
373 if(card->mgr.patch[i] == NULL) {
374 card->mgr.current_pages = i;
375 ret = -ENOMEM;
376 break;
377 }
378 memset(card->mgr.patch[i], 0, PAGE_SIZE);
379 }
380 card->mgr.current_pages = page + 1;
381 }
382
383 patch = PATCH(&card->mgr, ctl->val[0] - 1);
384
385 memcpy(patch, &ctl->val[1], sizeof(struct dsp_patch));
386
387 if (patch->code_size == 0) {
388 for(i = page + 1; i < card->mgr.current_pages; i++)
389 free_page((unsigned long) card->mgr.patch[i]);
390
391 card->mgr.current_pages = page + 1;
392 }
393 }
394 break;
395
396 case CMD_SETGPR:
397 if (ctl->val[0] > NUM_GPRS) {
398 ret = -EINVAL;
399 break;
400 }
401
402 memcpy(&card->mgr.gpr[ctl->val[0]], &ctl->val[1], sizeof(struct dsp_gpr));
403 break;
404
405 case CMD_SETCTLGPR:
406 addr = emu10k1_find_control_gpr(&card->mgr, (char *) ctl->val, (char *) ctl->val + PATCH_NAME_SIZE);
407 emu10k1_set_control_gpr(card, addr, *((s32 *)((char *) ctl->val + 2 * PATCH_NAME_SIZE)), 0);
408 break;
409
410 case CMD_SETGPOUT:
411 if ( ((ctl->val[0] > 2) && (!card->is_audigy))
412 || (ctl->val[0] > 15) || ctl->val[1] > 1) {
413 ret= -EINVAL;
414 break;
415 }
416
417 if (card->is_audigy)
418 emu10k1_writefn0(card, (1 << 24) | ((ctl->val[0]) << 16) | A_IOCFG, ctl->val[1]);
419 else
420 emu10k1_writefn0(card, (1 << 24) | (((ctl->val[0]) + 10) << 16) | HCFG, ctl->val[1]);
421 break;
422
423 case CMD_GETGPR2OSS:
424 id = ctl->val[0];
425 ch = ctl->val[1];
426
427 if (id >= SOUND_MIXER_NRDEVICES || ch >= 2) {
428 ret = -EINVAL;
429 break;
430 }
431
432 ctl->val[2] = card->mgr.ctrl_gpr[id][ch];
433
434 if (copy_to_user(argp, ctl, sizeof(struct mixer_private_ioctl)))
435 ret = -EFAULT;
436
437 break;
438
439 case CMD_SETGPR2OSS:
440 id = ctl->val[0];
441 /* 0 == left, 1 == right */
442 ch = ctl->val[1];
443 addr = ctl->val[2];
444
445 if (id >= SOUND_MIXER_NRDEVICES || ch >= 2) {
446 ret = -EINVAL;
447 break;
448 }
449
450 card->mgr.ctrl_gpr[id][ch] = addr;
451
452 if (card->is_aps)
453 break;
454
455 if (addr >= 0) {
456 unsigned int state = card->ac97->mixer_state[id];
457
458 if (ch == 1) {
459 state >>= 8;
460 card->ac97->stereo_mixers |= (1 << id);
461 }
462
463 card->ac97->supported_mixers |= (1 << id);
464
465 if (id == SOUND_MIXER_TREBLE) {
466 set_treble(card, card->ac97->mixer_state[id] & 0xff, (card->ac97->mixer_state[id] >> 8) & 0xff);
467 } else if (id == SOUND_MIXER_BASS) {
468 set_bass(card, card->ac97->mixer_state[id] & 0xff, (card->ac97->mixer_state[id] >> 8) & 0xff);
469 } else
470 emu10k1_set_volume_gpr(card, addr, state & 0xff,
471 volume_params[id]);
472 } else {
473 card->ac97->stereo_mixers &= ~(1 << id);
474 card->ac97->stereo_mixers |= card->ac97_stereo_mixers;
475
476 if (ch == 0) {
477 card->ac97->supported_mixers &= ~(1 << id);
478 card->ac97->supported_mixers |= card->ac97_supported_mixers;
479 }
480 }
481 break;
482
483 case CMD_SETPASSTHROUGH:
484 card->pt.selected = ctl->val[0] ? 1 : 0;
485 if (card->pt.state != PT_STATE_INACTIVE)
486 break;
487
488 card->pt.spcs_to_use = ctl->val[0] & 0x07;
489 break;
490
491 case CMD_PRIVATE3_VERSION:
492 ctl->val[0] = PRIVATE3_VERSION; //private3 version
493 ctl->val[1] = MAJOR_VER; //major driver version
494 ctl->val[2] = MINOR_VER; //minor driver version
495 ctl->val[3] = card->is_audigy; //1=card is audigy
496
497 if (card->is_audigy)
498 ctl->val[4]=emu10k1_readfn0(card, 0x18);
499
500 if (copy_to_user(argp, ctl, sizeof(struct mixer_private_ioctl)))
501 ret = -EFAULT;
502 break;
503
504 case CMD_AC97_BOOST:
505 if (ctl->val[0])
506 emu10k1_ac97_write(card->ac97, 0x18, 0x0);
507 else
508 emu10k1_ac97_write(card->ac97, 0x18, 0x0808);
509 break;
510 default:
511 ret = -EINVAL;
512 break;
513 }
514
515 kfree(ctl);
516 return ret;
517 break;
518
519 case SOUND_MIXER_PRIVATE4:
520
521 if (copy_from_user(&size, argp, sizeof(size)))
522 return -EFAULT;
523
524 DPD(2, "External tram size %#x\n", size);
525
526 if (size > 0x1fffff)
527 return -EINVAL;
528
529 size_reg = 0;
530
531 if (size != 0) {
532 size = (size - 1) >> 14;
533
534 while (size) {
535 size >>= 1;
536 size_reg++;
537 }
538
539 size = 0x4000 << size_reg;
540 }
541
542 DPD(2, "External tram size %#x %#x\n", size, size_reg);
543
544 if (size != card->tankmem.size) {
545 if (card->tankmem.size > 0) {
546 emu10k1_writefn0(card, HCFG_LOCKTANKCACHE, 1);
547
548 sblive_writeptr_tag(card, 0, TCB, 0, TCBS, 0, TAGLIST_END);
549
550 pci_free_consistent(card->pci_dev, card->tankmem.size, card->tankmem.addr, card->tankmem.dma_handle);
551
552 card->tankmem.size = 0;
553 }
554
555 if (size != 0) {
556 card->tankmem.addr = pci_alloc_consistent(card->pci_dev, size, &card->tankmem.dma_handle);
557 if (card->tankmem.addr == NULL)
558 return -ENOMEM;
559
560 card->tankmem.size = size;
561
562 sblive_writeptr_tag(card, 0, TCB, (u32) card->tankmem.dma_handle, TCBS,(u32) size_reg, TAGLIST_END);
563
564 emu10k1_writefn0(card, HCFG_LOCKTANKCACHE, 0);
565 }
566 }
567 return 0;
568 break;
569
570 default:
571 break;
572 }
573
574 return -EINVAL;
575}
576
577static int emu10k1_dsp_mixer(struct emu10k1_card *card, unsigned int oss_mixer, unsigned long arg)
578{
579 unsigned int left, right;
580 int val;
581 int scale;
582
583 card->ac97->modcnt++;
584
585 if (get_user(val, (int __user *)arg))
586 return -EFAULT;
587
588 /* cleanse input a little */
589 right = ((val >> 8) & 0xff);
590 left = (val & 0xff);
591
592 if (right > 100) right = 100;
593 if (left > 100) left = 100;
594
595 card->ac97->mixer_state[oss_mixer] = (right << 8) | left;
596 if (oss_mixer == SOUND_MIXER_TREBLE) {
597 set_treble(card, left, right);
598 return 0;
599 } if (oss_mixer == SOUND_MIXER_BASS) {
600 set_bass(card, left, right);
601 return 0;
602 }
603
604 if (oss_mixer == SOUND_MIXER_VOLUME)
605 scale = 1 << card->ac97->bit_resolution;
606 else
607 scale = volume_params[oss_mixer];
608
609 emu10k1_set_volume_gpr(card, card->mgr.ctrl_gpr[oss_mixer][0], left, scale);
610 emu10k1_set_volume_gpr(card, card->mgr.ctrl_gpr[oss_mixer][1], right, scale);
611
612 if (card->ac97_supported_mixers & (1 << oss_mixer))
613 card->ac97->write_mixer(card->ac97, oss_mixer, left, right);
614
615 return 0;
616}
617
618static int emu10k1_mixer_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
619{
620 int ret;
621 struct emu10k1_card *card = file->private_data;
622 unsigned int oss_mixer = _IOC_NR(cmd);
623
624 ret = -EINVAL;
625 if (!card->is_aps) {
626 if (cmd == SOUND_MIXER_INFO) {
627 mixer_info info;
628
629 strlcpy(info.id, card->ac97->name, sizeof(info.id));
630
631 if (card->is_audigy)
632 strlcpy(info.name, "Audigy - Emu10k1", sizeof(info.name));
633 else
634 strlcpy(info.name, "Creative SBLive - Emu10k1", sizeof(info.name));
635
636 info.modify_counter = card->ac97->modcnt;
637
638 if (copy_to_user((void __user *)arg, &info, sizeof(info)))
639 return -EFAULT;
640
641 return 0;
642 }
643
644 if ((_SIOC_DIR(cmd) == (_SIOC_WRITE|_SIOC_READ)) && oss_mixer <= SOUND_MIXER_NRDEVICES)
645 ret = emu10k1_dsp_mixer(card, oss_mixer, arg);
646 else
647 ret = card->ac97->mixer_ioctl(card->ac97, cmd, arg);
648 }
649
650 if (ret < 0)
651 ret = emu10k1_private_mixer(card, cmd, arg);
652
653 return ret;
654}
655
656static int emu10k1_mixer_open(struct inode *inode, struct file *file)
657{
658 int minor = iminor(inode);
659 struct emu10k1_card *card = NULL;
660 struct list_head *entry;
661
662 DPF(4, "emu10k1_mixer_open()\n");
663
664 list_for_each(entry, &emu10k1_devs) {
665 card = list_entry(entry, struct emu10k1_card, list);
666
667 if (card->ac97->dev_mixer == minor)
668 goto match;
669 }
670
671 return -ENODEV;
672
673 match:
674 file->private_data = card;
675 return 0;
676}
677
678static int emu10k1_mixer_release(struct inode *inode, struct file *file)
679{
680 DPF(4, "emu10k1_mixer_release()\n");
681 return 0;
682}
683
684struct file_operations emu10k1_mixer_fops = {
685 .owner = THIS_MODULE,
686 .llseek = no_llseek,
687 .ioctl = emu10k1_mixer_ioctl,
688 .open = emu10k1_mixer_open,
689 .release = emu10k1_mixer_release,
690};
diff --git a/sound/oss/emu10k1/passthrough.c b/sound/oss/emu10k1/passthrough.c
new file mode 100644
index 000000000000..4094be55f3be
--- /dev/null
+++ b/sound/oss/emu10k1/passthrough.c
@@ -0,0 +1,236 @@
1/*
2 **********************************************************************
3 * passthrough.c -- Emu10k1 digital passthrough
4 * Copyright (C) 2001 Juha Yrjölä <jyrjola@cc.hut.fi>
5 *
6 **********************************************************************
7 *
8 * Date Author Summary of changes
9 * ---- ------ ------------------
10 * May 15, 2001 Juha Yrjölä base code release
11 *
12 **********************************************************************
13 *
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License as
16 * published by the Free Software Foundation; either version 2 of
17 * the License, or (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public
25 * License along with this program; if not, write to the Free
26 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139,
27 * USA.
28 *
29 **********************************************************************
30 */
31
32#include <linux/module.h>
33#include <linux/poll.h>
34#include <linux/slab.h>
35#include <linux/bitops.h>
36#include <asm/io.h>
37#include <linux/sched.h>
38#include <linux/smp_lock.h>
39
40#include "hwaccess.h"
41#include "cardwo.h"
42#include "cardwi.h"
43#include "recmgr.h"
44#include "irqmgr.h"
45#include "audio.h"
46#include "8010.h"
47
48static void pt_putsamples(struct pt_data *pt, u16 *ptr, u16 left, u16 right)
49{
50 unsigned int idx;
51
52 ptr[pt->copyptr] = left;
53 idx = pt->copyptr + PT_SAMPLES/2;
54 idx %= PT_SAMPLES;
55 ptr[idx] = right;
56}
57
58static inline int pt_can_write(struct pt_data *pt)
59{
60 return pt->blocks_copied < pt->blocks_played + 8;
61}
62
63static int pt_wait_for_write(struct emu10k1_wavedevice *wavedev, int nonblock)
64{
65 struct emu10k1_card *card = wavedev->card;
66 struct pt_data *pt = &card->pt;
67
68 if (nonblock && !pt_can_write(pt))
69 return -EAGAIN;
70 while (!pt_can_write(pt) && pt->state != PT_STATE_INACTIVE) {
71 interruptible_sleep_on(&pt->wait);
72 if (signal_pending(current))
73 return -ERESTARTSYS;
74 }
75 if (pt->state == PT_STATE_INACTIVE)
76 return -EAGAIN;
77
78 return 0;
79}
80
81static int pt_putblock(struct emu10k1_wavedevice *wave_dev, u16 *block, int nonblock)
82{
83 struct woinst *woinst = wave_dev->woinst;
84 struct emu10k1_card *card = wave_dev->card;
85 struct pt_data *pt = &card->pt;
86 u16 *ptr = (u16 *) card->tankmem.addr;
87 int i = 0, r;
88 unsigned long flags;
89
90 r = pt_wait_for_write(wave_dev, nonblock);
91 if (r < 0)
92 return r;
93 spin_lock_irqsave(&card->pt.lock, flags);
94 while (i < PT_BLOCKSAMPLES) {
95 pt_putsamples(pt, ptr, block[2*i], block[2*i+1]);
96 if (pt->copyptr == 0)
97 pt->copyptr = PT_SAMPLES;
98 pt->copyptr--;
99 i++;
100 }
101 woinst->total_copied += PT_BLOCKSIZE;
102 pt->blocks_copied++;
103 if (pt->blocks_copied >= 4 && pt->state != PT_STATE_PLAYING) {
104 DPF(2, "activating digital pass-through playback\n");
105 sblive_writeptr(card, GPR_BASE + pt->enable_gpr, 0, 1);
106 pt->state = PT_STATE_PLAYING;
107 }
108 spin_unlock_irqrestore(&card->pt.lock, flags);
109 return 0;
110}
111
112int emu10k1_pt_setup(struct emu10k1_wavedevice *wave_dev)
113{
114 u32 bits;
115 struct emu10k1_card *card = wave_dev->card;
116 struct pt_data *pt = &card->pt;
117 int i;
118
119 for (i = 0; i < 3; i++) {
120 pt->old_spcs[i] = sblive_readptr(card, SPCS0 + i, 0);
121 if (pt->spcs_to_use & (1 << i)) {
122 DPD(2, "using S/PDIF port %d\n", i);
123 bits = SPCS_CLKACCY_1000PPM | SPCS_SAMPLERATE_48 |
124 SPCS_CHANNELNUM_LEFT | SPCS_SOURCENUM_UNSPEC | SPCS_GENERATIONSTATUS |
125 0x00001200 | SPCS_EMPHASIS_NONE | SPCS_COPYRIGHT;
126 if (pt->ac3data)
127 bits |= SPCS_NOTAUDIODATA;
128 sblive_writeptr(card, SPCS0 + i, 0, bits);
129 }
130 }
131 return 0;
132}
133
134ssize_t emu10k1_pt_write(struct file *file, const char __user *buffer, size_t count)
135{
136 struct emu10k1_wavedevice *wave_dev = (struct emu10k1_wavedevice *) file->private_data;
137 struct emu10k1_card *card = wave_dev->card;
138 struct pt_data *pt = &card->pt;
139 int nonblock, i, r, blocks, blocks_copied, bytes_copied = 0;
140
141 DPD(3, "emu10k1_pt_write(): %d bytes\n", count);
142
143 nonblock = file->f_flags & O_NONBLOCK;
144
145 if (card->tankmem.size < PT_SAMPLES*2)
146 return -EFAULT;
147 if (pt->state == PT_STATE_INACTIVE) {
148 DPF(2, "bufptr init\n");
149 pt->playptr = PT_SAMPLES-1;
150 pt->copyptr = PT_INITPTR;
151 pt->blocks_played = pt->blocks_copied = 0;
152 memset(card->tankmem.addr, 0, card->tankmem.size);
153 pt->state = PT_STATE_ACTIVATED;
154 pt->buf = kmalloc(PT_BLOCKSIZE, GFP_KERNEL);
155 pt->prepend_size = 0;
156 if (pt->buf == NULL)
157 return -ENOMEM;
158 emu10k1_pt_setup(wave_dev);
159 }
160 if (pt->prepend_size) {
161 int needed = PT_BLOCKSIZE - pt->prepend_size;
162
163 DPD(3, "prepend size %d, prepending %d bytes\n", pt->prepend_size, needed);
164 if (count < needed) {
165 copy_from_user(pt->buf + pt->prepend_size, buffer, count);
166 pt->prepend_size += count;
167 DPD(3, "prepend size now %d\n", pt->prepend_size);
168 return count;
169 }
170 copy_from_user(pt->buf + pt->prepend_size, buffer, needed);
171 r = pt_putblock(wave_dev, (u16 *) pt->buf, nonblock);
172 if (r)
173 return r;
174 bytes_copied += needed;
175 pt->prepend_size = 0;
176 }
177 blocks = (count-bytes_copied)/PT_BLOCKSIZE;
178 blocks_copied = 0;
179 while (blocks > 0) {
180 u16 __user *bufptr = (u16 __user *) buffer + (bytes_copied/2);
181 copy_from_user(pt->buf, bufptr, PT_BLOCKSIZE);
182 r = pt_putblock(wave_dev, (u16 *)pt->buf, nonblock);
183 if (r) {
184 if (bytes_copied)
185 return bytes_copied;
186 else
187 return r;
188 }
189 bytes_copied += PT_BLOCKSIZE;
190 blocks--;
191 blocks_copied++;
192 }
193 i = count - bytes_copied;
194 if (i) {
195 pt->prepend_size = i;
196 copy_from_user(pt->buf, buffer + bytes_copied, i);
197 bytes_copied += i;
198 DPD(3, "filling prepend buffer with %d bytes", i);
199 }
200 return bytes_copied;
201}
202
203void emu10k1_pt_stop(struct emu10k1_card *card)
204{
205 struct pt_data *pt = &card->pt;
206 int i;
207
208 if (pt->state != PT_STATE_INACTIVE) {
209 DPF(2, "digital pass-through stopped\n");
210 sblive_writeptr(card, (card->is_audigy ? A_GPR_BASE : GPR_BASE) + pt->enable_gpr, 0, 0);
211 for (i = 0; i < 3; i++) {
212 if (pt->spcs_to_use & (1 << i))
213 sblive_writeptr(card, SPCS0 + i, 0, pt->old_spcs[i]);
214 }
215 pt->state = PT_STATE_INACTIVE;
216 if(pt->buf)
217 kfree(pt->buf);
218 }
219}
220
221void emu10k1_pt_waveout_update(struct emu10k1_wavedevice *wave_dev)
222{
223 struct woinst *woinst = wave_dev->woinst;
224 struct pt_data *pt = &wave_dev->card->pt;
225 u32 pos;
226
227 if (pt->state == PT_STATE_PLAYING && pt->pos_gpr >= 0) {
228 pos = sblive_readptr(wave_dev->card, GPR_BASE + pt->pos_gpr, 0);
229 if (pos > PT_BLOCKSAMPLES)
230 pos = PT_BLOCKSAMPLES;
231 pos = 4 * (PT_BLOCKSAMPLES - pos);
232 } else
233 pos = 0;
234 woinst->total_played = pt->blocks_played * woinst->buffer.fragment_size + pos;
235 woinst->buffer.hw_pos = pos;
236}
diff --git a/sound/oss/emu10k1/passthrough.h b/sound/oss/emu10k1/passthrough.h
new file mode 100644
index 000000000000..420cc9784251
--- /dev/null
+++ b/sound/oss/emu10k1/passthrough.h
@@ -0,0 +1,99 @@
1/*
2 **********************************************************************
3 * passthrough.h -- Emu10k1 digital passthrough header file
4 * Copyright (C) 2001 Juha Yrjölä <jyrjola@cc.hut.fi>
5 *
6 **********************************************************************
7 *
8 * Date Author Summary of changes
9 * ---- ------ ------------------
10 * May 15, 2001 Juha Yrjölä base code release
11 *
12 **********************************************************************
13 *
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License as
16 * published by the Free Software Foundation; either version 2 of
17 * the License, or (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public
25 * License along with this program; if not, write to the Free
26 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139,
27 * USA.
28 *
29 **********************************************************************
30 */
31
32#ifndef _PASSTHROUGH_H
33#define _PASSTHROUGH_H
34
35#include "audio.h"
36
37/* number of 16-bit stereo samples in XTRAM buffer */
38#define PT_SAMPLES 0x8000
39#define PT_BLOCKSAMPLES 0x400
40#define PT_BLOCKSIZE (PT_BLOCKSAMPLES*4)
41#define PT_BLOCKSIZE_LOG2 12
42#define PT_BLOCKCOUNT (PT_SAMPLES/PT_BLOCKSAMPLES)
43#define PT_INITPTR (PT_SAMPLES/2-1)
44
45#define PT_STATE_INACTIVE 0
46#define PT_STATE_ACTIVATED 1
47#define PT_STATE_PLAYING 2
48
49/* passthrough struct */
50struct pt_data
51{
52 u8 selected, state, spcs_to_use;
53 int intr_gpr, enable_gpr, pos_gpr;
54 u32 blocks_played, blocks_copied, old_spcs[3];
55 u32 playptr, copyptr;
56 u32 prepend_size;
57 u8 *buf;
58 u8 ac3data;
59
60 char *patch_name, *intr_gpr_name, *enable_gpr_name, *pos_gpr_name;
61
62 wait_queue_head_t wait;
63 spinlock_t lock;
64};
65
66/*
67 Passthrough can be done in two methods:
68
69 Method 1 : tram
70 In original emu10k1, we couldn't bypass the sample rate converters. Even at 48kHz
71 (the internal sample rate of the emu10k1) the samples would get messed up.
72 To over come this, samples are copied into the tram and a special dsp patch copies
73 the samples out and generates interrupts when a block has finnished playing.
74
75 Method 2 : Interpolator bypass
76
77 Creative fixed the sample rate convert problem in emu10k1 rev 7 and higher
78 (including the emu10k2 (audigy)). This allows us to use the regular, and much simpler
79 playback method.
80
81
82 In both methods, dsp code is used to mux audio and passthrough. This ensures that the spdif
83 doesn't receive audio and pasthrough data at the same time. The spdif flag SPCS_NOTAUDIODATA
84 is set to tell
85
86 */
87
88// emu10k1 revs greater than or equal to 7 can use method2
89
90#define USE_PT_METHOD2 (card->is_audigy)
91#define USE_PT_METHOD1 !USE_PT_METHOD2
92
93ssize_t emu10k1_pt_write(struct file *file, const char __user *buf, size_t count);
94
95int emu10k1_pt_setup(struct emu10k1_wavedevice *wave_dev);
96void emu10k1_pt_stop(struct emu10k1_card *card);
97void emu10k1_pt_waveout_update(struct emu10k1_wavedevice *wave_dev);
98
99#endif /* _PASSTHROUGH_H */
diff --git a/sound/oss/emu10k1/recmgr.c b/sound/oss/emu10k1/recmgr.c
new file mode 100644
index 000000000000..67c3fd04cfdd
--- /dev/null
+++ b/sound/oss/emu10k1/recmgr.c
@@ -0,0 +1,147 @@
1/*
2 **********************************************************************
3 * recmgr.c -- Recording manager for emu10k1 driver
4 * Copyright 1999, 2000 Creative Labs, Inc.
5 *
6 **********************************************************************
7 *
8 * Date Author Summary of changes
9 * ---- ------ ------------------
10 * October 20, 1999 Bertrand Lee base code release
11 *
12 **********************************************************************
13 *
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License as
16 * published by the Free Software Foundation; either version 2 of
17 * the License, or (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public
25 * License along with this program; if not, write to the Free
26 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139,
27 * USA.
28 *
29 **********************************************************************
30 */
31
32#include <asm/delay.h>
33#include "8010.h"
34#include "recmgr.h"
35
36void emu10k1_reset_record(struct emu10k1_card *card, struct wavein_buffer *buffer)
37{
38 DPF(2, "emu10k1_reset_record()\n");
39
40 sblive_writeptr(card, buffer->sizereg, 0, ADCBS_BUFSIZE_NONE);
41
42 sblive_writeptr(card, buffer->sizereg, 0, buffer->sizeregval);
43
44 while (sblive_readptr(card, buffer->idxreg, 0))
45 udelay(5);
46}
47
48void emu10k1_start_record(struct emu10k1_card *card, struct wavein_buffer *buffer)
49{
50 DPF(2, "emu10k1_start_record()\n");
51
52 if (buffer->adcctl)
53 sblive_writeptr(card, ADCCR, 0, buffer->adcctl);
54}
55
56void emu10k1_stop_record(struct emu10k1_card *card, struct wavein_buffer *buffer)
57{
58 DPF(2, "emu10k1_stop_record()\n");
59
60 /* Disable record transfer */
61 if (buffer->adcctl)
62 sblive_writeptr(card, ADCCR, 0, 0);
63}
64
65void emu10k1_set_record_src(struct emu10k1_card *card, struct wiinst *wiinst)
66{
67 struct wavein_buffer *buffer = &wiinst->buffer;
68
69 DPF(2, "emu10k1_set_record_src()\n");
70
71 switch (wiinst->recsrc) {
72
73 case WAVERECORD_AC97:
74 DPF(2, "recording source: AC97\n");
75 buffer->sizereg = ADCBS;
76 buffer->addrreg = ADCBA;
77 buffer->idxreg = card->is_audigy ? A_ADCIDX_IDX : ADCIDX_IDX;
78
79 switch (wiinst->format.samplingrate) {
80 case 0xBB80:
81 buffer->adcctl = ADCCR_SAMPLERATE_48;
82 break;
83 case 0xAC44:
84 buffer->adcctl = ADCCR_SAMPLERATE_44;
85 break;
86 case 0x7D00:
87 buffer->adcctl = ADCCR_SAMPLERATE_32;
88 break;
89 case 0x5DC0:
90 buffer->adcctl = ADCCR_SAMPLERATE_24;
91 break;
92 case 0x5622:
93 buffer->adcctl = ADCCR_SAMPLERATE_22;
94 break;
95 case 0x3E80:
96 buffer->adcctl = ADCCR_SAMPLERATE_16;
97 break;
98 // FIXME: audigy supports 12kHz recording
99 /*
100 case ????:
101 buffer->adcctl = A_ADCCR_SAMPLERATE_12;
102 break;
103 */
104 case 0x2B11:
105 buffer->adcctl = card->is_audigy ? A_ADCCR_SAMPLERATE_11 : ADCCR_SAMPLERATE_11;
106 break;
107 case 0x1F40:
108 buffer->adcctl = card->is_audigy ? A_ADCCR_SAMPLERATE_8 : ADCCR_SAMPLERATE_8;
109 break;
110 default:
111 BUG();
112 break;
113 }
114
115 buffer->adcctl |= card->is_audigy ? A_ADCCR_LCHANENABLE : ADCCR_LCHANENABLE;
116
117 if (wiinst->format.channels == 2)
118 buffer->adcctl |= card->is_audigy ? A_ADCCR_RCHANENABLE : ADCCR_RCHANENABLE;
119
120 break;
121
122 case WAVERECORD_MIC:
123 DPF(2, "recording source: MIC\n");
124 buffer->sizereg = MICBS;
125 buffer->addrreg = MICBA;
126 buffer->idxreg = MICIDX_IDX;
127 buffer->adcctl = 0;
128 break;
129
130 case WAVERECORD_FX:
131 DPF(2, "recording source: FX\n");
132 buffer->sizereg = FXBS;
133 buffer->addrreg = FXBA;
134 buffer->idxreg = FXIDX_IDX;
135 buffer->adcctl = 0;
136
137 sblive_writeptr(card, FXWC, 0, wiinst->fxwc);
138 break;
139 default:
140 BUG();
141 break;
142 }
143
144 DPD(2, "bus addx: %#lx\n", (unsigned long) buffer->dma_handle);
145
146 sblive_writeptr(card, buffer->addrreg, 0, (u32)buffer->dma_handle);
147}
diff --git a/sound/oss/emu10k1/recmgr.h b/sound/oss/emu10k1/recmgr.h
new file mode 100644
index 000000000000..a68766ac4fd5
--- /dev/null
+++ b/sound/oss/emu10k1/recmgr.h
@@ -0,0 +1,48 @@
1/*
2 **********************************************************************
3 * recmgr.h
4 * Copyright 1999, 2000 Creative Labs, Inc.
5 *
6 **********************************************************************
7 *
8 * Date Author Summary of changes
9 * ---- ------ ------------------
10 * October 20, 1999 Bertrand Lee base code release
11 *
12 **********************************************************************
13 *
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License as
16 * published by the Free Software Foundation; either version 2 of
17 * the License, or (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public
25 * License along with this program; if not, write to the Free
26 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139,
27 * USA.
28 *
29 **********************************************************************
30 */
31
32#ifndef _RECORDMGR_H
33#define _RECORDMGR_H
34
35#include "hwaccess.h"
36#include "cardwi.h"
37
38/* Recording resources */
39#define WAVERECORD_AC97 0x01
40#define WAVERECORD_MIC 0x02
41#define WAVERECORD_FX 0x03
42
43void emu10k1_reset_record(struct emu10k1_card *card, struct wavein_buffer *buffer);
44void emu10k1_start_record(struct emu10k1_card *, struct wavein_buffer *);
45void emu10k1_stop_record(struct emu10k1_card *, struct wavein_buffer *);
46void emu10k1_set_record_src(struct emu10k1_card *, struct wiinst *wiinst);
47
48#endif /* _RECORDMGR_H */
diff --git a/sound/oss/emu10k1/timer.c b/sound/oss/emu10k1/timer.c
new file mode 100644
index 000000000000..d10d30739f41
--- /dev/null
+++ b/sound/oss/emu10k1/timer.c
@@ -0,0 +1,176 @@
1
2/*
3 **********************************************************************
4 * timer.c
5 * Copyright (C) 1999, 2000 Creative Labs, inc.
6 *
7 **********************************************************************
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License as
11 * published by the Free Software Foundation; either version 2 of
12 * the License, or (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public
20 * License along with this program; if not, write to the Free
21 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139,
22 * USA.
23 *
24 **********************************************************************
25 */
26
27/* 3/6/2000 Improved support for different timer delays Rui Sousa */
28
29/* 4/3/2000 Implemented timer list using list.h Rui Sousa */
30
31#include "hwaccess.h"
32#include "8010.h"
33#include "irqmgr.h"
34#include "timer.h"
35
36/* Try to schedule only once per fragment */
37
38void emu10k1_timer_irqhandler(struct emu10k1_card *card)
39{
40 struct emu_timer *t;
41 struct list_head *entry;
42
43 spin_lock(&card->timer_lock);
44
45 list_for_each(entry, &card->timers) {
46 t = list_entry(entry, struct emu_timer, list);
47
48 if (t->state & TIMER_STATE_ACTIVE) {
49 t->count++;
50 if (t->count == t->count_max) {
51 t->count = 0;
52 tasklet_hi_schedule(&t->tasklet);
53 }
54 }
55 }
56
57 spin_unlock(&card->timer_lock);
58
59 return;
60}
61
62void emu10k1_timer_install(struct emu10k1_card *card, struct emu_timer *timer, u16 delay)
63{
64 struct emu_timer *t;
65 struct list_head *entry;
66 unsigned long flags;
67
68 if (delay < 5)
69 delay = 5;
70
71 timer->delay = delay;
72 timer->state = TIMER_STATE_INSTALLED;
73
74 spin_lock_irqsave(&card->timer_lock, flags);
75
76 timer->count_max = timer->delay / (card->timer_delay < 1024 ? card->timer_delay : 1024);
77 timer->count = timer->count_max - 1;
78
79 list_add(&timer->list, &card->timers);
80
81 if (card->timer_delay > delay) {
82 if (card->timer_delay == TIMER_STOPPED)
83 emu10k1_irq_enable(card, INTE_INTERVALTIMERENB);
84
85 card->timer_delay = delay;
86 delay = (delay < 1024 ? delay : 1024);
87
88 emu10k1_timer_set(card, delay);
89
90 list_for_each(entry, &card->timers) {
91 t = list_entry(entry, struct emu_timer, list);
92
93 t->count_max = t->delay / delay;
94 /* don't want to think much, just force scheduling
95 on the next interrupt */
96 t->count = t->count_max - 1;
97 }
98
99 DPD(2, "timer rate --> %u\n", delay);
100 }
101
102 spin_unlock_irqrestore(&card->timer_lock, flags);
103
104 return;
105}
106
107void emu10k1_timer_uninstall(struct emu10k1_card *card, struct emu_timer *timer)
108{
109 struct emu_timer *t;
110 struct list_head *entry;
111 u16 delay = TIMER_STOPPED;
112 unsigned long flags;
113
114 if (timer->state == TIMER_STATE_UNINSTALLED)
115 return;
116
117 spin_lock_irqsave(&card->timer_lock, flags);
118
119 list_del(&timer->list);
120
121 list_for_each(entry, &card->timers) {
122 t = list_entry(entry, struct emu_timer, list);
123
124 if (t->delay < delay)
125 delay = t->delay;
126 }
127
128 if (card->timer_delay != delay) {
129 card->timer_delay = delay;
130
131 if (delay == TIMER_STOPPED)
132 emu10k1_irq_disable(card, INTE_INTERVALTIMERENB);
133 else {
134 delay = (delay < 1024 ? delay : 1024);
135
136 emu10k1_timer_set(card, delay);
137
138 list_for_each(entry, &card->timers) {
139 t = list_entry(entry, struct emu_timer, list);
140
141 t->count_max = t->delay / delay;
142 t->count = t->count_max - 1;
143 }
144 }
145
146 DPD(2, "timer rate --> %u\n", delay);
147 }
148
149 spin_unlock_irqrestore(&card->timer_lock, flags);
150
151 timer->state = TIMER_STATE_UNINSTALLED;
152
153 return;
154}
155
156void emu10k1_timer_enable(struct emu10k1_card *card, struct emu_timer *timer)
157{
158 unsigned long flags;
159
160 spin_lock_irqsave(&card->timer_lock, flags);
161 timer->state |= TIMER_STATE_ACTIVE;
162 spin_unlock_irqrestore(&card->timer_lock, flags);
163
164 return;
165}
166
167void emu10k1_timer_disable(struct emu10k1_card *card, struct emu_timer *timer)
168{
169 unsigned long flags;
170
171 spin_lock_irqsave(&card->timer_lock, flags);
172 timer->state &= ~TIMER_STATE_ACTIVE;
173 spin_unlock_irqrestore(&card->timer_lock, flags);
174
175 return;
176}
diff --git a/sound/oss/emu10k1/timer.h b/sound/oss/emu10k1/timer.h
new file mode 100644
index 000000000000..b2543b4d53a8
--- /dev/null
+++ b/sound/oss/emu10k1/timer.h
@@ -0,0 +1,54 @@
1/*
2 **********************************************************************
3 * timer.h
4 * Copyright (C) 1999, 2000 Creative Labs, Inc.
5 *
6 **********************************************************************
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License as
10 * published by the Free Software Foundation; either version 2 of
11 * the License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public
19 * License along with this program; if not, write to the Free
20 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139,
21 * USA.
22 *
23 **********************************************************************
24 */
25
26
27#ifndef _TIMER_H
28#define _TIMER_H
29
30#include <linux/sched.h>
31#include <linux/interrupt.h>
32#include "hwaccess.h"
33
34struct emu_timer
35{
36 struct list_head list;
37 struct tasklet_struct tasklet;
38 u8 state;
39 u16 count; /* current number of interrupts */
40 u16 count_max; /* number of interrupts needed to schedule the bh */
41 u16 delay; /* timer delay */
42};
43
44void emu10k1_timer_install(struct emu10k1_card *, struct emu_timer *, u16);
45void emu10k1_timer_uninstall(struct emu10k1_card *, struct emu_timer *);
46void emu10k1_timer_enable(struct emu10k1_card *, struct emu_timer *);
47void emu10k1_timer_disable(struct emu10k1_card *, struct emu_timer *);
48
49#define TIMER_STOPPED 0xffff
50#define TIMER_STATE_INSTALLED 0x01
51#define TIMER_STATE_ACTIVE 0x02
52#define TIMER_STATE_UNINSTALLED 0x04
53
54#endif /* _TIMER_H */
diff --git a/sound/oss/emu10k1/voicemgr.c b/sound/oss/emu10k1/voicemgr.c
new file mode 100644
index 000000000000..d88b602c07c2
--- /dev/null
+++ b/sound/oss/emu10k1/voicemgr.c
@@ -0,0 +1,398 @@
1/*
2 **********************************************************************
3 * voicemgr.c - Voice manager for emu10k1 driver
4 * Copyright 1999, 2000 Creative Labs, Inc.
5 *
6 **********************************************************************
7 *
8 * Date Author Summary of changes
9 * ---- ------ ------------------
10 * October 20, 1999 Bertrand Lee base code release
11 *
12 **********************************************************************
13 *
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License as
16 * published by the Free Software Foundation; either version 2 of
17 * the License, or (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public
25 * License along with this program; if not, write to the Free
26 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139,
27 * USA.
28 *
29 **********************************************************************
30 */
31
32#include "voicemgr.h"
33#include "8010.h"
34
35#define PITCH_48000 0x00004000
36#define PITCH_96000 0x00008000
37#define PITCH_85000 0x00007155
38#define PITCH_80726 0x00006ba2
39#define PITCH_67882 0x00005a82
40#define PITCH_57081 0x00004c1c
41
42static u32 emu10k1_select_interprom(struct emu10k1_card *card,
43 struct emu_voice *voice)
44{
45 if(voice->pitch_target==PITCH_48000)
46 return CCCA_INTERPROM_0;
47 else if(voice->pitch_target<PITCH_48000)
48 return CCCA_INTERPROM_1;
49 else if(voice->pitch_target>=PITCH_96000)
50 return CCCA_INTERPROM_0;
51 else if(voice->pitch_target>=PITCH_85000)
52 return CCCA_INTERPROM_6;
53 else if(voice->pitch_target>=PITCH_80726)
54 return CCCA_INTERPROM_5;
55 else if(voice->pitch_target>=PITCH_67882)
56 return CCCA_INTERPROM_4;
57 else if(voice->pitch_target>=PITCH_57081)
58 return CCCA_INTERPROM_3;
59 else
60 return CCCA_INTERPROM_2;
61}
62
63
64/**
65 * emu10k1_voice_alloc_buffer -
66 *
67 * allocates the memory buffer for a voice. Two page tables are kept for each buffer.
68 * One (dma_handle) keeps track of the host memory pages used and the other (virtualpagetable)
69 * is passed to the device so that it can do DMA to host memory.
70 *
71 */
72int emu10k1_voice_alloc_buffer(struct emu10k1_card *card, struct voice_mem *mem, u32 pages)
73{
74 u32 pageindex, pagecount;
75 u32 busaddx;
76 int i;
77
78 DPD(2, "requested pages is: %d\n", pages);
79
80 if ((mem->emupageindex = emu10k1_addxmgr_alloc(pages * PAGE_SIZE, card)) < 0)
81 {
82 DPF(1, "couldn't allocate emu10k1 address space\n");
83 return -1;
84 }
85
86 /* Fill in virtual memory table */
87 for (pagecount = 0; pagecount < pages; pagecount++) {
88 if ((mem->addr[pagecount] = pci_alloc_consistent(card->pci_dev, PAGE_SIZE, &mem->dma_handle[pagecount]))
89 == NULL) {
90 mem->pages = pagecount;
91 DPF(1, "couldn't allocate dma memory\n");
92 return -1;
93 }
94
95 DPD(2, "Virtual Addx: %p\n", mem->addr[pagecount]);
96
97 for (i = 0; i < PAGE_SIZE / EMUPAGESIZE; i++) {
98 busaddx = (u32) mem->dma_handle[pagecount] + i * EMUPAGESIZE;
99
100 DPD(3, "Bus Addx: %#x\n", busaddx);
101
102 pageindex = mem->emupageindex + pagecount * PAGE_SIZE / EMUPAGESIZE + i;
103
104 ((u32 *) card->virtualpagetable.addr)[pageindex] = cpu_to_le32((busaddx * 2) | pageindex);
105 }
106 }
107
108 mem->pages = pagecount;
109
110 return 0;
111}
112
113/**
114 * emu10k1_voice_free_buffer -
115 *
116 * frees the memory buffer for a voice.
117 */
118void emu10k1_voice_free_buffer(struct emu10k1_card *card, struct voice_mem *mem)
119{
120 u32 pagecount, pageindex;
121 int i;
122
123 if (mem->emupageindex < 0)
124 return;
125
126 for (pagecount = 0; pagecount < mem->pages; pagecount++) {
127 pci_free_consistent(card->pci_dev, PAGE_SIZE,
128 mem->addr[pagecount],
129 mem->dma_handle[pagecount]);
130
131 for (i = 0; i < PAGE_SIZE / EMUPAGESIZE; i++) {
132 pageindex = mem->emupageindex + pagecount * PAGE_SIZE / EMUPAGESIZE + i;
133 ((u32 *) card->virtualpagetable.addr)[pageindex] =
134 cpu_to_le32(((u32) card->silentpage.dma_handle * 2) | pageindex);
135 }
136 }
137
138 emu10k1_addxmgr_free(card, mem->emupageindex);
139 mem->emupageindex = -1;
140}
141
142int emu10k1_voice_alloc(struct emu10k1_card *card, struct emu_voice *voice)
143{
144 u8 *voicetable = card->voicetable;
145 int i;
146 unsigned long flags;
147
148 DPF(2, "emu10k1_voice_alloc()\n");
149
150 spin_lock_irqsave(&card->lock, flags);
151
152 if (voice->flags & VOICE_FLAGS_STEREO) {
153 for (i = 0; i < NUM_G; i += 2)
154 if ((voicetable[i] == VOICE_USAGE_FREE) && (voicetable[i + 1] == VOICE_USAGE_FREE)) {
155 voicetable[i] = voice->usage;
156 voicetable[i + 1] = voice->usage;
157 break;
158 }
159 } else {
160 for (i = 0; i < NUM_G; i++)
161 if (voicetable[i] == VOICE_USAGE_FREE) {
162 voicetable[i] = voice->usage;
163 break;
164 }
165 }
166
167 spin_unlock_irqrestore(&card->lock, flags);
168
169 if (i >= NUM_G)
170 return -1;
171
172 voice->card = card;
173 voice->num = i;
174
175 for (i = 0; i < (voice->flags & VOICE_FLAGS_STEREO ? 2 : 1); i++) {
176 DPD(2, " voice allocated -> %d\n", voice->num + i);
177
178 sblive_writeptr_tag(card, voice->num + i, IFATN, 0xffff,
179 DCYSUSV, 0,
180 VTFT, 0x0000ffff,
181 PTRX, 0,
182 TAGLIST_END);
183 }
184
185 return 0;
186}
187
188void emu10k1_voice_free(struct emu_voice *voice)
189{
190 struct emu10k1_card *card = voice->card;
191 int i;
192 unsigned long flags;
193
194 DPF(2, "emu10k1_voice_free()\n");
195
196 if (voice->usage == VOICE_USAGE_FREE)
197 return;
198
199 for (i = 0; i < (voice->flags & VOICE_FLAGS_STEREO ? 2 : 1); i++) {
200 DPD(2, " voice released -> %d\n", voice->num + i);
201
202 sblive_writeptr_tag(card, voice->num + i, DCYSUSV, 0,
203 VTFT, 0x0000ffff,
204 PTRX_PITCHTARGET, 0,
205 CVCF, 0x0000ffff,
206 //CPF, 0,
207 TAGLIST_END);
208
209 sblive_writeptr(card, CPF, voice->num + i, 0);
210 }
211
212 voice->usage = VOICE_USAGE_FREE;
213
214 spin_lock_irqsave(&card->lock, flags);
215
216 card->voicetable[voice->num] = VOICE_USAGE_FREE;
217
218 if (voice->flags & VOICE_FLAGS_STEREO)
219 card->voicetable[voice->num + 1] = VOICE_USAGE_FREE;
220
221 spin_unlock_irqrestore(&card->lock, flags);
222}
223
224void emu10k1_voice_playback_setup(struct emu_voice *voice)
225{
226 struct emu10k1_card *card = voice->card;
227 u32 start;
228 int i;
229
230 DPF(2, "emu10k1_voice_playback_setup()\n");
231
232 if (voice->flags & VOICE_FLAGS_STEREO) {
233 /* Set stereo bit */
234 start = 28;
235 sblive_writeptr(card, CPF, voice->num, CPF_STEREO_MASK);
236 sblive_writeptr(card, CPF, voice->num + 1, CPF_STEREO_MASK);
237 } else {
238 start = 30;
239 sblive_writeptr(card, CPF, voice->num, 0);
240 }
241
242 if(!(voice->flags & VOICE_FLAGS_16BIT))
243 start *= 2;
244
245 voice->start += start;
246
247 for (i = 0; i < (voice->flags & VOICE_FLAGS_STEREO ? 2 : 1); i++) {
248 if (card->is_audigy) {
249 sblive_writeptr(card, A_FXRT1, voice->num + i, voice->params[i].send_routing);
250 sblive_writeptr(card, A_FXRT2, voice->num + i, voice->params[i].send_routing2);
251 sblive_writeptr(card, A_SENDAMOUNTS, voice->num + i, voice->params[i].send_hgfe);
252 } else {
253 sblive_writeptr(card, FXRT, voice->num + i, voice->params[i].send_routing << 16);
254 }
255
256 /* Stop CA */
257 /* Assumption that PT is already 0 so no harm overwriting */
258 sblive_writeptr(card, PTRX, voice->num + i, ((voice->params[i].send_dcba & 0xff) << 8)
259 | ((voice->params[i].send_dcba & 0xff00) >> 8));
260
261 sblive_writeptr_tag(card, voice->num + i,
262 /* CSL, ST, CA */
263 DSL, voice->endloop | (voice->params[i].send_dcba & 0xff000000),
264 PSST, voice->startloop | ((voice->params[i].send_dcba & 0x00ff0000) << 8),
265 CCCA, (voice->start) | emu10k1_select_interprom(card,voice) |
266 ((voice->flags & VOICE_FLAGS_16BIT) ? 0 : CCCA_8BITSELECT),
267 /* Clear filter delay memory */
268 Z1, 0,
269 Z2, 0,
270 /* Invalidate maps */
271 MAPA, MAP_PTI_MASK | ((u32) card->silentpage.dma_handle * 2),
272 MAPB, MAP_PTI_MASK | ((u32) card->silentpage.dma_handle * 2),
273 /* modulation envelope */
274 CVCF, 0x0000ffff,
275 VTFT, 0x0000ffff,
276 ATKHLDM, 0,
277 DCYSUSM, 0x007f,
278 LFOVAL1, 0x8000,
279 LFOVAL2, 0x8000,
280 FMMOD, 0,
281 TREMFRQ, 0,
282 FM2FRQ2, 0,
283 ENVVAL, 0x8000,
284 /* volume envelope */
285 ATKHLDV, 0x7f7f,
286 ENVVOL, 0x8000,
287 /* filter envelope */
288 PEFE_FILTERAMOUNT, 0x7f,
289 /* pitch envelope */
290 PEFE_PITCHAMOUNT, 0, TAGLIST_END);
291
292 voice->params[i].fc_target = 0xffff;
293 }
294}
295
296void emu10k1_voices_start(struct emu_voice *first_voice, unsigned int num_voices, int set)
297{
298 struct emu10k1_card *card = first_voice->card;
299 struct emu_voice *voice;
300 unsigned int voicenum;
301 int j;
302
303 DPF(2, "emu10k1_voices_start()\n");
304
305 for (voicenum = 0; voicenum < num_voices; voicenum++)
306 {
307 voice = first_voice + voicenum;
308
309 if (!set) {
310 u32 cra, ccis, cs, sample;
311 if (voice->flags & VOICE_FLAGS_STEREO) {
312 cra = 64;
313 ccis = 28;
314 cs = 4;
315 } else {
316 cra = 64;
317 ccis = 30;
318 cs = 2;
319 }
320
321 if(voice->flags & VOICE_FLAGS_16BIT) {
322 sample = 0x00000000;
323 } else {
324 sample = 0x80808080;
325 ccis *= 2;
326 }
327
328 for(j = 0; j < cs; j++)
329 sblive_writeptr(card, CD0 + j, voice->num, sample);
330
331 /* Reset cache */
332 sblive_writeptr(card, CCR_CACHEINVALIDSIZE, voice->num, 0);
333 if (voice->flags & VOICE_FLAGS_STEREO)
334 sblive_writeptr(card, CCR_CACHEINVALIDSIZE, voice->num + 1, 0);
335
336 sblive_writeptr(card, CCR_READADDRESS, voice->num, cra);
337
338 if (voice->flags & VOICE_FLAGS_STEREO)
339 sblive_writeptr(card, CCR_READADDRESS, voice->num + 1, cra);
340
341 /* Fill cache */
342 sblive_writeptr(card, CCR_CACHEINVALIDSIZE, voice->num, ccis);
343 }
344
345 for (j = 0; j < (voice->flags & VOICE_FLAGS_STEREO ? 2 : 1); j++) {
346 sblive_writeptr_tag(card, voice->num + j,
347 IFATN, (voice->params[j].initial_fc << 8) | voice->params[j].initial_attn,
348 VTFT, (voice->params[j].volume_target << 16) | voice->params[j].fc_target,
349 CVCF, (voice->params[j].volume_target << 16) | voice->params[j].fc_target,
350 DCYSUSV, (voice->params[j].byampl_env_sustain << 8) | voice->params[j].byampl_env_decay,
351 TAGLIST_END);
352
353 emu10k1_clear_stop_on_loop(card, voice->num + j);
354 }
355 }
356
357
358 for (voicenum = 0; voicenum < num_voices; voicenum++)
359 {
360 voice = first_voice + voicenum;
361
362 for (j = 0; j < (voice->flags & VOICE_FLAGS_STEREO ? 2 : 1); j++) {
363 sblive_writeptr(card, PTRX_PITCHTARGET, voice->num + j, voice->pitch_target);
364
365 if (j == 0)
366 sblive_writeptr(card, CPF_CURRENTPITCH, voice->num, voice->pitch_target);
367
368 sblive_writeptr(card, IP, voice->num + j, voice->initial_pitch);
369 }
370 }
371}
372
373void emu10k1_voices_stop(struct emu_voice *first_voice, int num_voices)
374{
375 struct emu10k1_card *card = first_voice->card;
376 struct emu_voice *voice;
377 unsigned int voice_num;
378 int j;
379
380 DPF(2, "emu10k1_voice_stop()\n");
381
382 for (voice_num = 0; voice_num < num_voices; voice_num++)
383 {
384 voice = first_voice + voice_num;
385
386 for (j = 0; j < (voice->flags & VOICE_FLAGS_STEREO ? 2 : 1); j++) {
387 sblive_writeptr_tag(card, voice->num + j,
388 PTRX_PITCHTARGET, 0,
389 CPF_CURRENTPITCH, 0,
390 IFATN, 0xffff,
391 VTFT, 0x0000ffff,
392 CVCF, 0x0000ffff,
393 IP, 0,
394 TAGLIST_END);
395 }
396 }
397}
398
diff --git a/sound/oss/emu10k1/voicemgr.h b/sound/oss/emu10k1/voicemgr.h
new file mode 100644
index 000000000000..099a8cb7f2c5
--- /dev/null
+++ b/sound/oss/emu10k1/voicemgr.h
@@ -0,0 +1,103 @@
1/*
2 **********************************************************************
3 * sblive_voice.h -- EMU Voice Resource Manager header file
4 * Copyright 1999, 2000 Creative Labs, Inc.
5 *
6 **********************************************************************
7 *
8 * Date Author Summary of changes
9 * ---- ------ ------------------
10 * October 20, 1999 Bertrand Lee base code release
11 *
12 **********************************************************************
13 *
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License as
16 * published by the Free Software Foundation; either version 2 of
17 * the License, or (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public
25 * License along with this program; if not, write to the Free
26 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139,
27 * USA.
28 *
29 **********************************************************************
30 */
31
32#ifndef _VOICEMGR_H
33#define _VOICEMGR_H
34
35#include "hwaccess.h"
36
37/* struct emu_voice.usage flags */
38#define VOICE_USAGE_FREE 0x01
39#define VOICE_USAGE_MIDI 0x02
40#define VOICE_USAGE_PLAYBACK 0x04
41
42/* struct emu_voice.flags flags */
43#define VOICE_FLAGS_STEREO 0x02
44#define VOICE_FLAGS_16BIT 0x04
45
46struct voice_param
47{
48 /* FX bus amount send */
49
50 u32 send_routing;
51 // audigy only:
52 u32 send_routing2;
53
54 u32 send_dcba;
55 // audigy only:
56 u32 send_hgfe;
57
58
59 u32 initial_fc;
60 u32 fc_target;
61
62 u32 initial_attn;
63 u32 volume_target;
64
65 u32 byampl_env_sustain;
66 u32 byampl_env_decay;
67};
68
69struct voice_mem {
70 int emupageindex;
71 void *addr[BUFMAXPAGES];
72 dma_addr_t dma_handle[BUFMAXPAGES];
73 u32 pages;
74};
75
76struct emu_voice
77{
78 struct emu10k1_card *card;
79 u8 usage; /* Free, MIDI, playback */
80 u8 num; /* Voice ID */
81 u8 flags; /* Stereo/mono, 8/16 bit */
82
83 u32 startloop;
84 u32 endloop;
85 u32 start;
86
87 u32 initial_pitch;
88 u32 pitch_target;
89
90 struct voice_param params[2];
91
92 struct voice_mem mem;
93};
94
95int emu10k1_voice_alloc_buffer(struct emu10k1_card *, struct voice_mem *, u32);
96void emu10k1_voice_free_buffer(struct emu10k1_card *, struct voice_mem *);
97int emu10k1_voice_alloc(struct emu10k1_card *, struct emu_voice *);
98void emu10k1_voice_free(struct emu_voice *);
99void emu10k1_voice_playback_setup(struct emu_voice *);
100void emu10k1_voices_start(struct emu_voice *, unsigned int, int);
101void emu10k1_voices_stop(struct emu_voice *, int);
102
103#endif /* _VOICEMGR_H */