aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/ca0106
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/pci/ca0106
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/pci/ca0106')
-rw-r--r--sound/pci/ca0106/Makefile3
-rw-r--r--sound/pci/ca0106/ca0106.h549
-rw-r--r--sound/pci/ca0106/ca0106_main.c1283
-rw-r--r--sound/pci/ca0106/ca0106_mixer.c634
-rw-r--r--sound/pci/ca0106/ca0106_proc.c436
5 files changed, 2905 insertions, 0 deletions
diff --git a/sound/pci/ca0106/Makefile b/sound/pci/ca0106/Makefile
new file mode 100644
index 000000000000..89c6ceee21f3
--- /dev/null
+++ b/sound/pci/ca0106/Makefile
@@ -0,0 +1,3 @@
1snd-ca0106-objs := ca0106_main.o ca0106_proc.o ca0106_mixer.o
2
3obj-$(CONFIG_SND_CA0106) += snd-ca0106.o
diff --git a/sound/pci/ca0106/ca0106.h b/sound/pci/ca0106/ca0106.h
new file mode 100644
index 000000000000..deb028851056
--- /dev/null
+++ b/sound/pci/ca0106/ca0106.h
@@ -0,0 +1,549 @@
1/*
2 * Copyright (c) 2004 James Courtier-Dutton <James@superbug.demon.co.uk>
3 * Driver CA0106 chips. e.g. Sound Blaster Audigy LS and Live 24bit
4 * Version: 0.0.20
5 *
6 * FEATURES currently supported:
7 * See ca0106_main.c for features.
8 *
9 * Changelog:
10 * Support interrupts per period.
11 * Removed noise from Center/LFE channel when in Analog mode.
12 * Rename and remove mixer controls.
13 * 0.0.6
14 * Use separate card based DMA buffer for periods table list.
15 * 0.0.7
16 * Change remove and rename ctrls into lists.
17 * 0.0.8
18 * Try to fix capture sources.
19 * 0.0.9
20 * Fix AC3 output.
21 * Enable S32_LE format support.
22 * 0.0.10
23 * Enable playback 48000 and 96000 rates. (Rates other that these do not work, even with "plug:front".)
24 * 0.0.11
25 * Add Model name recognition.
26 * 0.0.12
27 * Correct interrupt timing. interrupt at end of period, instead of in the middle of a playback period.
28 * Remove redundent "voice" handling.
29 * 0.0.13
30 * Single trigger call for multi channels.
31 * 0.0.14
32 * Set limits based on what the sound card hardware can do.
33 * playback periods_min=2, periods_max=8
34 * capture hw constraints require period_size = n * 64 bytes.
35 * playback hw constraints require period_size = n * 64 bytes.
36 * 0.0.15
37 * Separated ca0106.c into separate functional .c files.
38 * 0.0.16
39 * Implement 192000 sample rate.
40 * 0.0.17
41 * Add support for SB0410 and SB0413.
42 * 0.0.18
43 * Modified Copyright message.
44 * 0.0.19
45 * Added I2C and SPI registers. Filled in interrupt enable.
46 * 0.0.20
47 * Added GPIO info for SB Live 24bit.
48 *
49 *
50 * This code was initally based on code from ALSA's emu10k1x.c which is:
51 * Copyright (c) by Francisco Moraes <fmoraes@nc.rr.com>
52 *
53 * This program is free software; you can redistribute it and/or modify
54 * it under the terms of the GNU General Public License as published by
55 * the Free Software Foundation; either version 2 of the License, or
56 * (at your option) any later version.
57 *
58 * This program is distributed in the hope that it will be useful,
59 * but WITHOUT ANY WARRANTY; without even the implied warranty of
60 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
61 * GNU General Public License for more details.
62 *
63 * You should have received a copy of the GNU General Public License
64 * along with this program; if not, write to the Free Software
65 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
66 *
67 */
68
69/************************************************************************************************/
70/* PCI function 0 registers, address = <val> + PCIBASE0 */
71/************************************************************************************************/
72
73#define PTR 0x00 /* Indexed register set pointer register */
74 /* NOTE: The CHANNELNUM and ADDRESS words can */
75 /* be modified independently of each other. */
76 /* CNL[1:0], ADDR[27:16] */
77
78#define DATA 0x04 /* Indexed register set data register */
79 /* DATA[31:0] */
80
81#define IPR 0x08 /* Global interrupt pending register */
82 /* Clear pending interrupts by writing a 1 to */
83 /* the relevant bits and zero to the other bits */
84#define IPR_MIDI_RX_B 0x00020000 /* MIDI UART-B Receive buffer non-empty */
85#define IPR_MIDI_TX_B 0x00010000 /* MIDI UART-B Transmit buffer empty */
86#define IPR_SPDIF_IN_USER 0x00004000 /* SPDIF input user data has 16 more bits */
87#define IPR_SPDIF_OUT_USER 0x00002000 /* SPDIF output user data needs 16 more bits */
88#define IPR_SPDIF_OUT_FRAME 0x00001000 /* SPDIF frame about to start */
89#define IPR_SPI 0x00000800 /* SPI transaction completed */
90#define IPR_I2C_EEPROM 0x00000400 /* I2C EEPROM transaction completed */
91#define IPR_I2C_DAC 0x00000200 /* I2C DAC transaction completed */
92#define IPR_AI 0x00000100 /* Audio pending register changed. See PTR reg 0x76 */
93#define IPR_GPI 0x00000080 /* General Purpose input changed */
94#define IPR_SRC_LOCKED 0x00000040 /* SRC lock status changed */
95#define IPR_SPDIF_STATUS 0x00000020 /* SPDIF status changed */
96#define IPR_TIMER2 0x00000010 /* 192000Hz Timer */
97#define IPR_TIMER1 0x00000008 /* 44100Hz Timer */
98#define IPR_MIDI_RX_A 0x00000004 /* MIDI UART-A Receive buffer non-empty */
99#define IPR_MIDI_TX_A 0x00000002 /* MIDI UART-A Transmit buffer empty */
100#define IPR_PCI 0x00000001 /* PCI Bus error */
101
102#define INTE 0x0c /* Interrupt enable register */
103
104#define INTE_MIDI_RX_B 0x00020000 /* MIDI UART-B Receive buffer non-empty */
105#define INTE_MIDI_TX_B 0x00010000 /* MIDI UART-B Transmit buffer empty */
106#define INTE_SPDIF_IN_USER 0x00004000 /* SPDIF input user data has 16 more bits */
107#define INTE_SPDIF_OUT_USER 0x00002000 /* SPDIF output user data needs 16 more bits */
108#define INTE_SPDIF_OUT_FRAME 0x00001000 /* SPDIF frame about to start */
109#define INTE_SPI 0x00000800 /* SPI transaction completed */
110#define INTE_I2C_EEPROM 0x00000400 /* I2C EEPROM transaction completed */
111#define INTE_I2C_DAC 0x00000200 /* I2C DAC transaction completed */
112#define INTE_AI 0x00000100 /* Audio pending register changed. See PTR reg 0x75 */
113#define INTE_GPI 0x00000080 /* General Purpose input changed */
114#define INTE_SRC_LOCKED 0x00000040 /* SRC lock status changed */
115#define INTE_SPDIF_STATUS 0x00000020 /* SPDIF status changed */
116#define INTE_TIMER2 0x00000010 /* 192000Hz Timer */
117#define INTE_TIMER1 0x00000008 /* 44100Hz Timer */
118#define INTE_MIDI_RX_A 0x00000004 /* MIDI UART-A Receive buffer non-empty */
119#define INTE_MIDI_TX_A 0x00000002 /* MIDI UART-A Transmit buffer empty */
120#define INTE_PCI 0x00000001 /* PCI Bus error */
121
122#define UNKNOWN10 0x10 /* Unknown ??. Defaults to 0 */
123#define HCFG 0x14 /* Hardware config register */
124 /* 0x1000 causes AC3 to fails. It adds a dither bit. */
125
126#define HCFG_STAC 0x10000000 /* Special mode for STAC9460 Codec. */
127#define HCFG_CAPTURE_I2S_BYPASS 0x08000000 /* 1 = bypass I2S input async SRC. */
128#define HCFG_CAPTURE_SPDIF_BYPASS 0x04000000 /* 1 = bypass SPDIF input async SRC. */
129#define HCFG_PLAYBACK_I2S_BYPASS 0x02000000 /* 0 = I2S IN mixer output, 1 = I2S IN1. */
130#define HCFG_FORCE_LOCK 0x01000000 /* For test only. Force input SRC tracker to lock. */
131#define HCFG_PLAYBACK_ATTENUATION 0x00006000 /* Playback attenuation mask. 0 = 0dB, 1 = 6dB, 2 = 12dB, 3 = Mute. */
132#define HCFG_PLAYBACK_DITHER 0x00001000 /* 1 = Add dither bit to all playback channels. */
133#define HCFG_PLAYBACK_S32_LE 0x00000800 /* 1 = S32_LE, 0 = S16_LE */
134#define HCFG_CAPTURE_S32_LE 0x00000400 /* 1 = S32_LE, 0 = S16_LE (S32_LE current not working) */
135#define HCFG_8_CHANNEL_PLAY 0x00000200 /* 1 = 8 channels, 0 = 2 channels per substream.*/
136#define HCFG_8_CHANNEL_CAPTURE 0x00000100 /* 1 = 8 channels, 0 = 2 channels per substream.*/
137#define HCFG_MONO 0x00000080 /* 1 = I2S Input mono */
138#define HCFG_I2S_OUTPUT 0x00000010 /* 1 = I2S Output disabled */
139#define HCFG_AC97 0x00000008 /* 0 = AC97 1.0, 1 = AC97 2.0 */
140#define HCFG_LOCK_PLAYBACK_CACHE 0x00000004 /* 1 = Cancel bustmaster accesses to soundcache */
141 /* NOTE: This should generally never be used. */
142#define HCFG_LOCK_CAPTURE_CACHE 0x00000002 /* 1 = Cancel bustmaster accesses to soundcache */
143 /* NOTE: This should generally never be used. */
144#define HCFG_AUDIOENABLE 0x00000001 /* 0 = CODECs transmit zero-valued samples */
145 /* Should be set to 1 when the EMU10K1 is */
146 /* completely initialized. */
147#define GPIO 0x18 /* Defaults: 005f03a3-Analog, 005f02a2-SPDIF. */
148 /* Here pins 0,1,2,3,4,,6 are output. 5,7 are input */
149 /* For the Audigy LS, pin 0 (or bit 8) controls the SPDIF/Analog jack. */
150 /* SB Live 24bit:
151 * bit 8 0 = SPDIF in and out / 1 = Analog (Mic or Line)-in.
152 * bit 9 0 = Mute / 1 = Analog out.
153 * bit 10 0 = Line-in / 1 = Mic-in.
154 * bit 11 0 = ? / 1 = ?
155 * bit 12 0 = ? / 1 = ?
156 * bit 13 0 = ? / 1 = ?
157 * bit 14 0 = Mute / 1 = Analog out
158 * bit 15 0 = ? / 1 = ?
159 * Both bit 9 and bit 14 have to be set for analog sound to work on the SB Live 24bit.
160 */
161 /* 8 general purpose programmable In/Out pins.
162 * GPI [8:0] Read only. Default 0.
163 * GPO [15:8] Default 0x9. (Default to SPDIF jack enabled for SPDIF)
164 * GPO Enable [23:16] Default 0x0f. Setting a bit to 1, causes the pin to be an output pin.
165 */
166#define AC97DATA 0x1c /* AC97 register set data register (16 bit) */
167
168#define AC97ADDRESS 0x1e /* AC97 register set address register (8 bit) */
169
170/********************************************************************************************************/
171/* CA0106 pointer-offset register set, accessed through the PTR and DATA registers */
172/********************************************************************************************************/
173
174/* Initally all registers from 0x00 to 0x3f have zero contents. */
175#define PLAYBACK_LIST_ADDR 0x00 /* Base DMA address of a list of pointers to each period/size */
176 /* One list entry: 4 bytes for DMA address,
177 * 4 bytes for period_size << 16.
178 * One list entry is 8 bytes long.
179 * One list entry for each period in the buffer.
180 */
181 /* ADDR[31:0], Default: 0x0 */
182#define PLAYBACK_LIST_SIZE 0x01 /* Size of list in bytes << 16. E.g. 8 periods -> 0x00380000 */
183 /* SIZE[21:16], Default: 0x8 */
184#define PLAYBACK_LIST_PTR 0x02 /* Pointer to the current period being played */
185 /* PTR[5:0], Default: 0x0 */
186#define PLAYBACK_UNKNOWN3 0x03 /* Not used ?? */
187#define PLAYBACK_DMA_ADDR 0x04 /* Playback DMA addresss */
188 /* DMA[31:0], Default: 0x0 */
189#define PLAYBACK_PERIOD_SIZE 0x05 /* Playback period size. win2000 uses 0x04000000 */
190 /* SIZE[31:16], Default: 0x0 */
191#define PLAYBACK_POINTER 0x06 /* Playback period pointer. Used with PLAYBACK_LIST_PTR to determine buffer position currently in DAC */
192 /* POINTER[15:0], Default: 0x0 */
193#define PLAYBACK_PERIOD_END_ADDR 0x07 /* Playback fifo end address */
194 /* END_ADDR[15:0], FLAG[16] 0 = don't stop, 1 = stop */
195#define PLAYBACK_FIFO_OFFSET_ADDRESS 0x08 /* Current fifo offset address [21:16] */
196 /* Cache size valid [5:0] */
197#define PLAYBACK_UNKNOWN9 0x09 /* 0x9 to 0xf Unused */
198#define CAPTURE_DMA_ADDR 0x10 /* Capture DMA address */
199 /* DMA[31:0], Default: 0x0 */
200#define CAPTURE_BUFFER_SIZE 0x11 /* Capture buffer size */
201 /* SIZE[31:16], Default: 0x0 */
202#define CAPTURE_POINTER 0x12 /* Capture buffer pointer. Sample currently in ADC */
203 /* POINTER[15:0], Default: 0x0 */
204#define CAPTURE_FIFO_OFFSET_ADDRESS 0x13 /* Current fifo offset address [21:16] */
205 /* Cache size valid [5:0] */
206#define PLAYBACK_LAST_SAMPLE 0x20 /* The sample currently being played */
207/* 0x21 - 0x3f unused */
208#define BASIC_INTERRUPT 0x40 /* Used by both playback and capture interrupt handler */
209 /* Playback (0x1<<channel_id) */
210 /* Capture (0x100<<channel_id) */
211 /* Playback sample rate 96000 = 0x20000 */
212 /* Start Playback [3:0] (one bit per channel)
213 * Start Capture [11:8] (one bit per channel)
214 * Playback rate [23:16] (2 bits per channel) (0=48kHz, 1=44.1kHz, 2=96kHz, 3=192Khz)
215 * Playback mixer in enable [27:24] (one bit per channel)
216 * Playback mixer out enable [31:28] (one bit per channel)
217 */
218/* The Digital out jack is shared with the Center/LFE Analogue output.
219 * The jack has 4 poles. I will call 1 - Tip, 2 - Next to 1, 3 - Next to 2, 4 - Next to 3
220 * For Analogue: 1 -> Center Speaker, 2 -> Sub Woofer, 3 -> Ground, 4 -> Ground
221 * For Digital: 1 -> Front SPDIF, 2 -> Rear SPDIF, 3 -> Center/Subwoofer SPDIF, 4 -> Ground.
222 * Standard 4 pole Video A/V cable with RCA outputs: 1 -> White, 2 -> Yellow, 3 -> Sheild on all three, 4 -> Red.
223 * So, from this you can see that you cannot use a Standard 4 pole Video A/V cable with the SB Audigy LS card.
224 */
225/* The Front SPDIF PCM gets mixed with samples from the AC97 codec, so can only work for Stereo PCM and not AC3/DTS
226 * The Rear SPDIF can be used for Stereo PCM and also AC3/DTS
227 * The Center/LFE SPDIF cannot be used for AC3/DTS, but can be used for Stereo PCM.
228 * Summary: For ALSA we use the Rear channel for SPDIF Digital AC3/DTS output
229 */
230/* A standard 2 pole mono mini-jack to RCA plug can be used for SPDIF Stereo PCM output from the Front channel.
231 * A standard 3 pole stereo mini-jack to 2 RCA plugs can be used for SPDIF AC3/DTS and Stereo PCM output utilising the Rear channel and just one of the RCA plugs.
232 */
233#define SPCS0 0x41 /* SPDIF output Channel Status 0 register. For Rear. default=0x02108004, non-audio=0x02108006 */
234#define SPCS1 0x42 /* SPDIF output Channel Status 1 register. For Front */
235#define SPCS2 0x43 /* SPDIF output Channel Status 2 register. For Center/LFE */
236#define SPCS3 0x44 /* SPDIF output Channel Status 3 register. Unknown */
237 /* When Channel set to 0: */
238#define SPCS_CLKACCYMASK 0x30000000 /* Clock accuracy */
239#define SPCS_CLKACCY_1000PPM 0x00000000 /* 1000 parts per million */
240#define SPCS_CLKACCY_50PPM 0x10000000 /* 50 parts per million */
241#define SPCS_CLKACCY_VARIABLE 0x20000000 /* Variable accuracy */
242#define SPCS_SAMPLERATEMASK 0x0f000000 /* Sample rate */
243#define SPCS_SAMPLERATE_44 0x00000000 /* 44.1kHz sample rate */
244#define SPCS_SAMPLERATE_48 0x02000000 /* 48kHz sample rate */
245#define SPCS_SAMPLERATE_32 0x03000000 /* 32kHz sample rate */
246#define SPCS_CHANNELNUMMASK 0x00f00000 /* Channel number */
247#define SPCS_CHANNELNUM_UNSPEC 0x00000000 /* Unspecified channel number */
248#define SPCS_CHANNELNUM_LEFT 0x00100000 /* Left channel */
249#define SPCS_CHANNELNUM_RIGHT 0x00200000 /* Right channel */
250#define SPCS_SOURCENUMMASK 0x000f0000 /* Source number */
251#define SPCS_SOURCENUM_UNSPEC 0x00000000 /* Unspecified source number */
252#define SPCS_GENERATIONSTATUS 0x00008000 /* Originality flag (see IEC-958 spec) */
253#define SPCS_CATEGORYCODEMASK 0x00007f00 /* Category code (see IEC-958 spec) */
254#define SPCS_MODEMASK 0x000000c0 /* Mode (see IEC-958 spec) */
255#define SPCS_EMPHASISMASK 0x00000038 /* Emphasis */
256#define SPCS_EMPHASIS_NONE 0x00000000 /* No emphasis */
257#define SPCS_EMPHASIS_50_15 0x00000008 /* 50/15 usec 2 channel */
258#define SPCS_COPYRIGHT 0x00000004 /* Copyright asserted flag -- do not modify */
259#define SPCS_NOTAUDIODATA 0x00000002 /* 0 = Digital audio, 1 = not audio */
260#define SPCS_PROFESSIONAL 0x00000001 /* 0 = Consumer (IEC-958), 1 = pro (AES3-1992) */
261
262 /* When Channel set to 1: */
263#define SPCS_WORD_LENGTH_MASK 0x0000000f /* Word Length Mask */
264#define SPCS_WORD_LENGTH_16 0x00000008 /* Word Length 16 bit */
265#define SPCS_WORD_LENGTH_17 0x00000006 /* Word Length 17 bit */
266#define SPCS_WORD_LENGTH_18 0x00000004 /* Word Length 18 bit */
267#define SPCS_WORD_LENGTH_19 0x00000002 /* Word Length 19 bit */
268#define SPCS_WORD_LENGTH_20A 0x0000000a /* Word Length 20 bit */
269#define SPCS_WORD_LENGTH_20 0x00000009 /* Word Length 20 bit (both 0xa and 0x9 are 20 bit) */
270#define SPCS_WORD_LENGTH_21 0x00000007 /* Word Length 21 bit */
271#define SPCS_WORD_LENGTH_21 0x00000007 /* Word Length 21 bit */
272#define SPCS_WORD_LENGTH_22 0x00000005 /* Word Length 22 bit */
273#define SPCS_WORD_LENGTH_23 0x00000003 /* Word Length 23 bit */
274#define SPCS_WORD_LENGTH_24 0x0000000b /* Word Length 24 bit */
275#define SPCS_ORIGINAL_SAMPLE_RATE_MASK 0x000000f0 /* Original Sample rate */
276#define SPCS_ORIGINAL_SAMPLE_RATE_NONE 0x00000000 /* Original Sample rate not indicated */
277#define SPCS_ORIGINAL_SAMPLE_RATE_16000 0x00000010 /* Original Sample rate */
278#define SPCS_ORIGINAL_SAMPLE_RATE_RES1 0x00000020 /* Original Sample rate */
279#define SPCS_ORIGINAL_SAMPLE_RATE_32000 0x00000030 /* Original Sample rate */
280#define SPCS_ORIGINAL_SAMPLE_RATE_12000 0x00000040 /* Original Sample rate */
281#define SPCS_ORIGINAL_SAMPLE_RATE_11025 0x00000050 /* Original Sample rate */
282#define SPCS_ORIGINAL_SAMPLE_RATE_8000 0x00000060 /* Original Sample rate */
283#define SPCS_ORIGINAL_SAMPLE_RATE_RES2 0x00000070 /* Original Sample rate */
284#define SPCS_ORIGINAL_SAMPLE_RATE_192000 0x00000080 /* Original Sample rate */
285#define SPCS_ORIGINAL_SAMPLE_RATE_24000 0x00000090 /* Original Sample rate */
286#define SPCS_ORIGINAL_SAMPLE_RATE_96000 0x000000a0 /* Original Sample rate */
287#define SPCS_ORIGINAL_SAMPLE_RATE_48000 0x000000b0 /* Original Sample rate */
288#define SPCS_ORIGINAL_SAMPLE_RATE_176400 0x000000c0 /* Original Sample rate */
289#define SPCS_ORIGINAL_SAMPLE_RATE_22050 0x000000d0 /* Original Sample rate */
290#define SPCS_ORIGINAL_SAMPLE_RATE_88200 0x000000e0 /* Original Sample rate */
291#define SPCS_ORIGINAL_SAMPLE_RATE_44100 0x000000f0 /* Original Sample rate */
292
293#define SPDIF_SELECT1 0x45 /* Enables SPDIF or Analogue outputs 0-SPDIF, 0xf00-Analogue */
294 /* 0x100 - Front, 0x800 - Rear, 0x200 - Center/LFE.
295 * But as the jack is shared, use 0xf00.
296 * The Windows2000 driver uses 0x0000000f for both digital and analog.
297 * 0xf00 introduces interesting noises onto the Center/LFE.
298 * If you turn the volume up, you hear computer noise,
299 * e.g. mouse moving, changing between app windows etc.
300 * So, I am going to set this to 0x0000000f all the time now,
301 * same as the windows driver does.
302 * Use register SPDIF_SELECT2(0x72) to switch between SPDIF and Analog.
303 */
304 /* When Channel = 0:
305 * Wide SPDIF format [3:0] (one bit for each channel) (0=20bit, 1=24bit)
306 * Tristate SPDIF Output [11:8] (one bit for each channel) (0=Not tristate, 1=Tristate)
307 * SPDIF Bypass enable [19:16] (one bit for each channel) (0=Not bypass, 1=Bypass)
308 */
309 /* When Channel = 1:
310 * SPDIF 0 User data [7:0]
311 * SPDIF 1 User data [15:8]
312 * SPDIF 0 User data [23:16]
313 * SPDIF 0 User data [31:24]
314 * User data can be sent by using the SPDIF output frame pending and SPDIF output user bit interrupts.
315 */
316#define WATERMARK 0x46 /* Test bit to indicate cache usage level */
317#define SPDIF_INPUT_STATUS 0x49 /* SPDIF Input status register. Bits the same as SPCS.
318 * When Channel = 0: Bits the same as SPCS channel 0.
319 * When Channel = 1: Bits the same as SPCS channel 1.
320 * When Channel = 2:
321 * SPDIF Input User data [16:0]
322 * SPDIF Input Frame count [21:16]
323 */
324#define CAPTURE_CACHE_DATA 0x50 /* 0x50-0x5f Recorded samples. */
325#define CAPTURE_SOURCE 0x60 /* Capture Source 0 = MIC */
326#define CAPTURE_SOURCE_CHANNEL0 0xf0000000 /* Mask for selecting the Capture sources */
327#define CAPTURE_SOURCE_CHANNEL1 0x0f000000 /* 0 - SPDIF mixer output. */
328#define CAPTURE_SOURCE_CHANNEL2 0x00f00000 /* 1 - What you hear or . 2 - ?? */
329#define CAPTURE_SOURCE_CHANNEL3 0x000f0000 /* 3 - Mic in, Line in, TAD in, Aux in. */
330#define CAPTURE_SOURCE_RECORD_MAP 0x0000ffff /* Default 0x00e4 */
331 /* Record Map [7:0] (2 bits per channel) 0=mapped to channel 0, 1=mapped to channel 1, 2=mapped to channel2, 3=mapped to channel3
332 * Record source select for channel 0 [18:16]
333 * Record source select for channel 1 [22:20]
334 * Record source select for channel 2 [26:24]
335 * Record source select for channel 3 [30:28]
336 * 0 - SPDIF mixer output.
337 * 1 - i2s mixer output.
338 * 2 - SPDIF input.
339 * 3 - i2s input.
340 * 4 - AC97 capture.
341 * 5 - SRC output.
342 */
343#define CAPTURE_VOLUME1 0x61 /* Capture volume per channel 0-3 */
344#define CAPTURE_VOLUME2 0x62 /* Capture volume per channel 4-7 */
345
346#define PLAYBACK_ROUTING1 0x63 /* Playback routing of channels 0-7. Effects AC3 output. Default 0x32765410 */
347#define ROUTING1_REAR 0x77000000 /* Channel_id 0 sends to 10, Channel_id 1 sends to 32 */
348#define ROUTING1_NULL 0x00770000 /* Channel_id 2 sends to 54, Channel_id 3 sends to 76 */
349#define ROUTING1_CENTER_LFE 0x00007700 /* 0x32765410 means, send Channel_id 0 to FRONT, Channel_id 1 to REAR */
350#define ROUTING1_FRONT 0x00000077 /* Channel_id 2 to CENTER_LFE, Channel_id 3 to NULL. */
351 /* Channel_id's handle stereo channels. Channel X is a single mono channel */
352 /* Host is input from the PCI bus. */
353 /* Host channel 0 [2:0] -> SPDIF Mixer/Router channel 0-7.
354 * Host channel 1 [6:4] -> SPDIF Mixer/Router channel 0-7.
355 * Host channel 2 [10:8] -> SPDIF Mixer/Router channel 0-7.
356 * Host channel 3 [14:12] -> SPDIF Mixer/Router channel 0-7.
357 * Host channel 4 [18:16] -> SPDIF Mixer/Router channel 0-7.
358 * Host channel 5 [22:20] -> SPDIF Mixer/Router channel 0-7.
359 * Host channel 6 [26:24] -> SPDIF Mixer/Router channel 0-7.
360 * Host channel 7 [30:28] -> SPDIF Mixer/Router channel 0-7.
361 */
362
363#define PLAYBACK_ROUTING2 0x64 /* Playback Routing . Feeding Capture channels back into Playback. Effects AC3 output. Default 0x76767676 */
364 /* SRC is input from the capture inputs. */
365 /* SRC channel 0 [2:0] -> SPDIF Mixer/Router channel 0-7.
366 * SRC channel 1 [6:4] -> SPDIF Mixer/Router channel 0-7.
367 * SRC channel 2 [10:8] -> SPDIF Mixer/Router channel 0-7.
368 * SRC channel 3 [14:12] -> SPDIF Mixer/Router channel 0-7.
369 * SRC channel 4 [18:16] -> SPDIF Mixer/Router channel 0-7.
370 * SRC channel 5 [22:20] -> SPDIF Mixer/Router channel 0-7.
371 * SRC channel 6 [26:24] -> SPDIF Mixer/Router channel 0-7.
372 * SRC channel 7 [30:28] -> SPDIF Mixer/Router channel 0-7.
373 */
374
375#define PLAYBACK_MUTE 0x65 /* Unknown. While playing 0x0, while silent 0x00fc0000 */
376 /* SPDIF Mixer input control:
377 * Invert SRC to SPDIF Mixer [7-0] (One bit per channel)
378 * Invert Host to SPDIF Mixer [15:8] (One bit per channel)
379 * SRC to SPDIF Mixer disable [23:16] (One bit per channel)
380 * Host to SPDIF Mixer disable [31:24] (One bit per channel)
381 */
382#define PLAYBACK_VOLUME1 0x66 /* Playback SPDIF volume per channel. Set to the same PLAYBACK_VOLUME(0x6a) */
383 /* PLAYBACK_VOLUME1 must be set to 30303030 for SPDIF AC3 Playback */
384 /* SPDIF mixer input volume. 0=12dB, 0x30=0dB, 0xFE=-51.5dB, 0xff=Mute */
385 /* One register for each of the 4 stereo streams. */
386 /* SRC Right volume [7:0]
387 * SRC Left volume [15:8]
388 * Host Right volume [23:16]
389 * Host Left volume [31:24]
390 */
391#define CAPTURE_ROUTING1 0x67 /* Capture Routing. Default 0x32765410 */
392 /* Similar to register 0x63, except that the destination is the I2S mixer instead of the SPDIF mixer. I.E. Outputs to the Analog outputs instead of SPDIF. */
393#define CAPTURE_ROUTING2 0x68 /* Unknown Routing. Default 0x76767676 */
394 /* Similar to register 0x64, except that the destination is the I2S mixer instead of the SPDIF mixer. I.E. Outputs to the Analog outputs instead of SPDIF. */
395#define CAPTURE_MUTE 0x69 /* Unknown. While capturing 0x0, while silent 0x00fc0000 */
396 /* Similar to register 0x65, except that the destination is the I2S mixer instead of the SPDIF mixer. I.E. Outputs to the Analog outputs instead of SPDIF. */
397#define PLAYBACK_VOLUME2 0x6a /* Playback Analog volume per channel. Does not effect AC3 output */
398 /* Similar to register 0x66, except that the destination is the I2S mixer instead of the SPDIF mixer. I.E. Outputs to the Analog outputs instead of SPDIF. */
399#define UNKNOWN6b 0x6b /* Unknown. Readonly. Default 00400000 00400000 00400000 00400000 */
400#define UART_A_DATA 0x6c /* Uart, used in setting sample rates, bits per sample etc. */
401#define UART_A_CMD 0x6d /* Uart, used in setting sample rates, bits per sample etc. */
402#define UART_B_DATA 0x6e /* Uart, Unknown. */
403#define UART_B_CMD 0x6f /* Uart, Unknown. */
404#define SAMPLE_RATE_TRACKER_STATUS 0x70 /* Readonly. Default 00108000 00108000 00500000 00500000 */
405 /* Estimated sample rate [19:0] Relative to 48kHz. 0x8000 = 1.0
406 * Rate Locked [20]
407 * SPDIF Locked [21] For SPDIF channel only.
408 * Valid Audio [22] For SPDIF channel only.
409 */
410#define CAPTURE_CONTROL 0x71 /* Some sort of routing. default = 40c81000 30303030 30300000 00700000 */
411 /* Channel_id 0: 0x40c81000 must be changed to 0x40c80000 for SPDIF AC3 input or output. */
412 /* Channel_id 1: 0xffffffff(mute) 0x30303030(max) controls CAPTURE feedback into PLAYBACK. */
413 /* Sample rate output control register Channel=0
414 * Sample output rate [1:0] (0=48kHz, 1=44.1kHz, 2=96kHz, 3=192Khz)
415 * Sample input rate [3:2] (0=48kHz, 1=Not available, 2=96kHz, 3=192Khz)
416 * SRC input source select [4] 0=Audio from digital mixer, 1=Audio from analog source.
417 * Record rate [9:8] (0=48kHz, 1=Not available, 2=96kHz, 3=192Khz)
418 * Record mixer output enable [12:10]
419 * I2S input rate master mode [15:14] (0=48kHz, 1=44.1kHz, 2=96kHz, 3=192Khz)
420 * I2S output rate [17:16] (0=48kHz, 1=44.1kHz, 2=96kHz, 3=192Khz)
421 * I2S output source select [18] (0=Audio from host, 1=Audio from SRC)
422 * Record mixer I2S enable [20:19] (enable/disable i2sin1 and i2sin0)
423 * I2S output master clock select [21] (0=256*I2S output rate, 1=512*I2S output rate.)
424 * I2S input master clock select [22] (0=256*I2S input rate, 1=512*I2S input rate.)
425 * I2S input mode [23] (0=Slave, 1=Master)
426 * SPDIF output rate [25:24] (0=48kHz, 1=44.1kHz, 2=96kHz, 3=192Khz)
427 * SPDIF output source select [26] (0=host, 1=SRC)
428 * Not used [27]
429 * Record Source 0 input [29:28] (0=SPDIF in, 1=I2S in, 2=AC97 Mic, 3=AC97 PCM)
430 * Record Source 1 input [31:30] (0=SPDIF in, 1=I2S in, 2=AC97 Mic, 3=AC97 PCM)
431 */
432 /* Sample rate output control register Channel=1
433 * I2S Input 0 volume Right [7:0]
434 * I2S Input 0 volume Left [15:8]
435 * I2S Input 1 volume Right [23:16]
436 * I2S Input 1 volume Left [31:24]
437 */
438 /* Sample rate output control register Channel=2
439 * SPDIF Input volume Right [23:16]
440 * SPDIF Input volume Left [31:24]
441 */
442 /* Sample rate output control register Channel=3
443 * No used
444 */
445#define SPDIF_SELECT2 0x72 /* Some sort of routing. Channel_id 0 only. default = 0x0f0f003f. Analog 0x000b0000, Digital 0x0b000000 */
446#define ROUTING2_FRONT_MASK 0x00010000 /* Enable for Front speakers. */
447#define ROUTING2_CENTER_LFE_MASK 0x00020000 /* Enable for Center/LFE speakers. */
448#define ROUTING2_REAR_MASK 0x00080000 /* Enable for Rear speakers. */
449 /* Audio output control
450 * AC97 output enable [5:0]
451 * I2S output enable [19:16]
452 * SPDIF output enable [27:24]
453 */
454#define UNKNOWN73 0x73 /* Unknown. Readonly. Default 0x0 */
455#define CHIP_VERSION 0x74 /* P17 Chip version. Channel_id 0 only. Default 00000071 */
456#define EXTENDED_INT_MASK 0x75 /* Used by both playback and capture interrupt handler */
457 /* Sets which Interrupts are enabled. */
458 /* 0x00000001 = Half period. Playback.
459 * 0x00000010 = Full period. Playback.
460 * 0x00000100 = Half buffer. Playback.
461 * 0x00001000 = Full buffer. Playback.
462 * 0x00010000 = Half buffer. Capture.
463 * 0x00100000 = Full buffer. Capture.
464 * Capture can only do 2 periods.
465 * 0x01000000 = End audio. Playback.
466 * 0x40000000 = Half buffer Playback,Caputre xrun.
467 * 0x80000000 = Full buffer Playback,Caputre xrun.
468 */
469#define EXTENDED_INT 0x76 /* Used by both playback and capture interrupt handler */
470 /* Shows which interrupts are active at the moment. */
471 /* Same bit layout as EXTENDED_INT_MASK */
472#define COUNTER77 0x77 /* Counter range 0 to 0x3fffff, 192000 counts per second. */
473#define COUNTER78 0x78 /* Counter range 0 to 0x3fffff, 44100 counts per second. */
474#define EXTENDED_INT_TIMER 0x79 /* Channel_id 0 only. Used by both playback and capture interrupt handler */
475 /* Causes interrupts based on timer intervals. */
476#define SPI 0x7a /* SPI: Serial Interface Register */
477#define I2C_A 0x7b /* I2C Address. 32 bit */
478#define I2C_0 0x7c /* I2C Data Port 0. 32 bit */
479#define I2C_1 0x7d /* I2C Data Port 1. 32 bit */
480
481
482#define SET_CHANNEL 0 /* Testing channel outputs 0=Front, 1=Center/LFE, 2=Unknown, 3=Rear */
483#define PCM_FRONT_CHANNEL 0
484#define PCM_REAR_CHANNEL 1
485#define PCM_CENTER_LFE_CHANNEL 2
486#define PCM_UNKNOWN_CHANNEL 3
487#define CONTROL_FRONT_CHANNEL 0
488#define CONTROL_REAR_CHANNEL 3
489#define CONTROL_CENTER_LFE_CHANNEL 1
490#define CONTROL_UNKNOWN_CHANNEL 2
491
492typedef struct snd_ca0106_channel ca0106_channel_t;
493typedef struct snd_ca0106 ca0106_t;
494typedef struct snd_ca0106_pcm ca0106_pcm_t;
495
496struct snd_ca0106_channel {
497 ca0106_t *emu;
498 int number;
499 int use;
500 void (*interrupt)(ca0106_t *emu, ca0106_channel_t *channel);
501 ca0106_pcm_t *epcm;
502};
503
504struct snd_ca0106_pcm {
505 ca0106_t *emu;
506 snd_pcm_substream_t *substream;
507 int channel_id;
508 unsigned short running;
509};
510
511// definition of the chip-specific record
512struct snd_ca0106 {
513 snd_card_t *card;
514 struct pci_dev *pci;
515
516 unsigned long port;
517 struct resource *res_port;
518 int irq;
519
520 unsigned int revision; /* chip revision */
521 unsigned int serial; /* serial number */
522 unsigned short model; /* subsystem id */
523
524 spinlock_t emu_lock;
525
526 ac97_t *ac97;
527 snd_pcm_t *pcm;
528
529 ca0106_channel_t playback_channels[4];
530 ca0106_channel_t capture_channels[4];
531 u32 spdif_bits[4]; /* s/pdif out setup */
532 int spdif_enable;
533 int capture_source;
534
535 struct snd_dma_buffer buffer;
536};
537
538int __devinit snd_ca0106_mixer(ca0106_t *emu);
539int __devinit snd_ca0106_proc_init(ca0106_t * emu);
540
541unsigned int snd_ca0106_ptr_read(ca0106_t * emu,
542 unsigned int reg,
543 unsigned int chn);
544
545void snd_ca0106_ptr_write(ca0106_t *emu,
546 unsigned int reg,
547 unsigned int chn,
548 unsigned int data);
549
diff --git a/sound/pci/ca0106/ca0106_main.c b/sound/pci/ca0106/ca0106_main.c
new file mode 100644
index 000000000000..82533b45bc8c
--- /dev/null
+++ b/sound/pci/ca0106/ca0106_main.c
@@ -0,0 +1,1283 @@
1/*
2 * Copyright (c) 2004 James Courtier-Dutton <James@superbug.demon.co.uk>
3 * Driver CA0106 chips. e.g. Sound Blaster Audigy LS and Live 24bit
4 * Version: 0.0.22
5 *
6 * FEATURES currently supported:
7 * Front, Rear and Center/LFE.
8 * Surround40 and Surround51.
9 * Capture from MIC an LINE IN input.
10 * SPDIF digital playback of PCM stereo and AC3/DTS works.
11 * (One can use a standard mono mini-jack to one RCA plugs cable.
12 * or one can use a standard stereo mini-jack to two RCA plugs cable.
13 * Plug one of the RCA plugs into the Coax input of the external decoder/receiver.)
14 * ( In theory one could output 3 different AC3 streams at once, to 3 different SPDIF outputs. )
15 * Notes on how to capture sound:
16 * The AC97 is used in the PLAYBACK direction.
17 * The output from the AC97 chip, instead of reaching the speakers, is fed into the Philips 1361T ADC.
18 * So, to record from the MIC, set the MIC Playback volume to max,
19 * unmute the MIC and turn up the MASTER Playback volume.
20 * So, to prevent feedback when capturing, minimise the "Capture feedback into Playback" volume.
21 *
22 * The only playback controls that currently do anything are: -
23 * Analog Front
24 * Analog Rear
25 * Analog Center/LFE
26 * SPDIF Front
27 * SPDIF Rear
28 * SPDIF Center/LFE
29 *
30 * For capture from Mic in or Line in.
31 * Digital/Analog ( switch must be in Analog mode for CAPTURE. )
32 *
33 * CAPTURE feedback into PLAYBACK
34 *
35 * Changelog:
36 * Support interrupts per period.
37 * Removed noise from Center/LFE channel when in Analog mode.
38 * Rename and remove mixer controls.
39 * 0.0.6
40 * Use separate card based DMA buffer for periods table list.
41 * 0.0.7
42 * Change remove and rename ctrls into lists.
43 * 0.0.8
44 * Try to fix capture sources.
45 * 0.0.9
46 * Fix AC3 output.
47 * Enable S32_LE format support.
48 * 0.0.10
49 * Enable playback 48000 and 96000 rates. (Rates other that these do not work, even with "plug:front".)
50 * 0.0.11
51 * Add Model name recognition.
52 * 0.0.12
53 * Correct interrupt timing. interrupt at end of period, instead of in the middle of a playback period.
54 * Remove redundent "voice" handling.
55 * 0.0.13
56 * Single trigger call for multi channels.
57 * 0.0.14
58 * Set limits based on what the sound card hardware can do.
59 * playback periods_min=2, periods_max=8
60 * capture hw constraints require period_size = n * 64 bytes.
61 * playback hw constraints require period_size = n * 64 bytes.
62 * 0.0.15
63 * Minor updates.
64 * 0.0.16
65 * Implement 192000 sample rate.
66 * 0.0.17
67 * Add support for SB0410 and SB0413.
68 * 0.0.18
69 * Modified Copyright message.
70 * 0.0.19
71 * Finally fix support for SB Live 24 bit. SB0410 and SB0413.
72 * The output codec needs resetting, otherwise all output is muted.
73 * 0.0.20
74 * Merge "pci_disable_device(pci);" fixes.
75 * 0.0.21
76 * Add 4 capture channels. (SPDIF only comes in on channel 0. )
77 * Add SPDIF capture using optional digital I/O module for SB Live 24bit. (Analog capture does not yet work.)
78 * 0.0.22
79 * Add support for MSI K8N Diamond Motherboard with onboard SB Live 24bit without AC97. From kiksen, bug #901
80 *
81 * BUGS:
82 * Some stability problems when unloading the snd-ca0106 kernel module.
83 * --
84 *
85 * TODO:
86 * 4 Capture channels, only one implemented so far.
87 * Other capture rates apart from 48khz not implemented.
88 * MIDI
89 * --
90 * GENERAL INFO:
91 * Model: SB0310
92 * P17 Chip: CA0106-DAT
93 * AC97 Codec: STAC 9721
94 * ADC: Philips 1361T (Stereo 24bit)
95 * DAC: WM8746EDS (6-channel, 24bit, 192Khz)
96 *
97 * GENERAL INFO:
98 * Model: SB0410
99 * P17 Chip: CA0106-DAT
100 * AC97 Codec: None
101 * ADC: WM8775EDS (4 Channel)
102 * DAC: CS4382 (114 dB, 24-Bit, 192 kHz, 8-Channel D/A Converter with DSD Support)
103 * SPDIF Out control switches between Mic in and SPDIF out.
104 * No sound out or mic input working yet.
105 *
106 * GENERAL INFO:
107 * Model: SB0413
108 * P17 Chip: CA0106-DAT
109 * AC97 Codec: None.
110 * ADC: Unknown
111 * DAC: Unknown
112 * Trying to handle it like the SB0410.
113 *
114 * This code was initally based on code from ALSA's emu10k1x.c which is:
115 * Copyright (c) by Francisco Moraes <fmoraes@nc.rr.com>
116 *
117 * This program is free software; you can redistribute it and/or modify
118 * it under the terms of the GNU General Public License as published by
119 * the Free Software Foundation; either version 2 of the License, or
120 * (at your option) any later version.
121 *
122 * This program is distributed in the hope that it will be useful,
123 * but WITHOUT ANY WARRANTY; without even the implied warranty of
124 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
125 * GNU General Public License for more details.
126 *
127 * You should have received a copy of the GNU General Public License
128 * along with this program; if not, write to the Free Software
129 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
130 *
131 */
132#include <sound/driver.h>
133#include <linux/delay.h>
134#include <linux/init.h>
135#include <linux/interrupt.h>
136#include <linux/pci.h>
137#include <linux/slab.h>
138#include <linux/moduleparam.h>
139#include <sound/core.h>
140#include <sound/initval.h>
141#include <sound/pcm.h>
142#include <sound/ac97_codec.h>
143#include <sound/info.h>
144
145MODULE_AUTHOR("James Courtier-Dutton <James@superbug.demon.co.uk>");
146MODULE_DESCRIPTION("CA0106");
147MODULE_LICENSE("GPL");
148MODULE_SUPPORTED_DEVICE("{{Creative,SB CA0106 chip}}");
149
150// module parameters (see "Module Parameters")
151static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
152static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
153static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
154
155module_param_array(index, int, NULL, 0444);
156MODULE_PARM_DESC(index, "Index value for the CA0106 soundcard.");
157module_param_array(id, charp, NULL, 0444);
158MODULE_PARM_DESC(id, "ID string for the CA0106 soundcard.");
159module_param_array(enable, bool, NULL, 0444);
160MODULE_PARM_DESC(enable, "Enable the CA0106 soundcard.");
161
162#include "ca0106.h"
163
164typedef struct {
165 u32 serial;
166 char * name;
167} ca0106_names_t;
168
169static ca0106_names_t ca0106_chip_names[] = {
170 { 0x10021102, "AudigyLS [SB0310]"} ,
171 { 0x10051102, "AudigyLS [SB0310b]"} , /* Unknown AudigyLS that also says SB0310 on it */
172 { 0x10061102, "Live! 7.1 24bit [SB0410]"} , /* New Sound Blaster Live! 7.1 24bit. This does not have an AC97. 53SB041000001 */
173 { 0x10071102, "Live! 7.1 24bit [SB0413]"} , /* New Dell Sound Blaster Live! 7.1 24bit. This does not have an AC97. */
174 { 0x10091462, "MSI K8N Diamond MB [SB0438]"}, /* MSI K8N Diamond Motherboard with onboard SB Live 24bit without AC97 */
175 { 0, "AudigyLS [Unknown]" }
176};
177
178/* hardware definition */
179static snd_pcm_hardware_t snd_ca0106_playback_hw = {
180 .info = (SNDRV_PCM_INFO_MMAP |
181 SNDRV_PCM_INFO_INTERLEAVED |
182 SNDRV_PCM_INFO_BLOCK_TRANSFER |
183 SNDRV_PCM_INFO_MMAP_VALID),
184 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE,
185 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_192000,
186 .rate_min = 48000,
187 .rate_max = 192000,
188 .channels_min = 2, //1,
189 .channels_max = 2, //6,
190 .buffer_bytes_max = ((65536 - 64) * 8),
191 .period_bytes_min = 64,
192 .period_bytes_max = (65536 - 64),
193 .periods_min = 2,
194 .periods_max = 8,
195 .fifo_size = 0,
196};
197
198static snd_pcm_hardware_t snd_ca0106_capture_hw = {
199 .info = (SNDRV_PCM_INFO_MMAP |
200 SNDRV_PCM_INFO_INTERLEAVED |
201 SNDRV_PCM_INFO_BLOCK_TRANSFER |
202 SNDRV_PCM_INFO_MMAP_VALID),
203 .formats = SNDRV_PCM_FMTBIT_S16_LE,
204 .rates = SNDRV_PCM_RATE_48000,
205 .rate_min = 48000,
206 .rate_max = 48000,
207 .channels_min = 2,
208 .channels_max = 2,
209 .buffer_bytes_max = ((65536 - 64) * 8),
210 .period_bytes_min = 64,
211 .period_bytes_max = (65536 - 64),
212 .periods_min = 2,
213 .periods_max = 2,
214 .fifo_size = 0,
215};
216
217unsigned int snd_ca0106_ptr_read(ca0106_t * emu,
218 unsigned int reg,
219 unsigned int chn)
220{
221 unsigned long flags;
222 unsigned int regptr, val;
223
224 regptr = (reg << 16) | chn;
225
226 spin_lock_irqsave(&emu->emu_lock, flags);
227 outl(regptr, emu->port + PTR);
228 val = inl(emu->port + DATA);
229 spin_unlock_irqrestore(&emu->emu_lock, flags);
230 return val;
231}
232
233void snd_ca0106_ptr_write(ca0106_t *emu,
234 unsigned int reg,
235 unsigned int chn,
236 unsigned int data)
237{
238 unsigned int regptr;
239 unsigned long flags;
240
241 regptr = (reg << 16) | chn;
242
243 spin_lock_irqsave(&emu->emu_lock, flags);
244 outl(regptr, emu->port + PTR);
245 outl(data, emu->port + DATA);
246 spin_unlock_irqrestore(&emu->emu_lock, flags);
247}
248
249static void snd_ca0106_intr_enable(ca0106_t *emu, unsigned int intrenb)
250{
251 unsigned long flags;
252 unsigned int enable;
253
254 spin_lock_irqsave(&emu->emu_lock, flags);
255 enable = inl(emu->port + INTE) | intrenb;
256 outl(enable, emu->port + INTE);
257 spin_unlock_irqrestore(&emu->emu_lock, flags);
258}
259
260static void snd_ca0106_pcm_free_substream(snd_pcm_runtime_t *runtime)
261{
262 ca0106_pcm_t *epcm = runtime->private_data;
263
264 if (epcm) {
265 kfree(epcm);
266 }
267}
268
269/* open_playback callback */
270static int snd_ca0106_pcm_open_playback_channel(snd_pcm_substream_t *substream, int channel_id)
271{
272 ca0106_t *chip = snd_pcm_substream_chip(substream);
273 ca0106_channel_t *channel = &(chip->playback_channels[channel_id]);
274 ca0106_pcm_t *epcm;
275 snd_pcm_runtime_t *runtime = substream->runtime;
276 int err;
277
278 epcm = kcalloc(1, sizeof(*epcm), GFP_KERNEL);
279
280 if (epcm == NULL)
281 return -ENOMEM;
282 epcm->emu = chip;
283 epcm->substream = substream;
284 epcm->channel_id=channel_id;
285
286 runtime->private_data = epcm;
287 runtime->private_free = snd_ca0106_pcm_free_substream;
288
289 runtime->hw = snd_ca0106_playback_hw;
290
291 channel->emu = chip;
292 channel->number = channel_id;
293
294 channel->use=1;
295 //printk("open:channel_id=%d, chip=%p, channel=%p\n",channel_id, chip, channel);
296 //channel->interrupt = snd_ca0106_pcm_channel_interrupt;
297 channel->epcm=epcm;
298 if ((err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS)) < 0)
299 return err;
300 if ((err = snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 64)) < 0)
301 return err;
302 return 0;
303}
304
305/* close callback */
306static int snd_ca0106_pcm_close_playback(snd_pcm_substream_t *substream)
307{
308 ca0106_t *chip = snd_pcm_substream_chip(substream);
309 snd_pcm_runtime_t *runtime = substream->runtime;
310 ca0106_pcm_t *epcm = runtime->private_data;
311 chip->playback_channels[epcm->channel_id].use=0;
312/* FIXME: maybe zero others */
313 return 0;
314}
315
316static int snd_ca0106_pcm_open_playback_front(snd_pcm_substream_t *substream)
317{
318 return snd_ca0106_pcm_open_playback_channel(substream, PCM_FRONT_CHANNEL);
319}
320
321static int snd_ca0106_pcm_open_playback_center_lfe(snd_pcm_substream_t *substream)
322{
323 return snd_ca0106_pcm_open_playback_channel(substream, PCM_CENTER_LFE_CHANNEL);
324}
325
326static int snd_ca0106_pcm_open_playback_unknown(snd_pcm_substream_t *substream)
327{
328 return snd_ca0106_pcm_open_playback_channel(substream, PCM_UNKNOWN_CHANNEL);
329}
330
331static int snd_ca0106_pcm_open_playback_rear(snd_pcm_substream_t *substream)
332{
333 return snd_ca0106_pcm_open_playback_channel(substream, PCM_REAR_CHANNEL);
334}
335
336/* open_capture callback */
337static int snd_ca0106_pcm_open_capture_channel(snd_pcm_substream_t *substream, int channel_id)
338{
339 ca0106_t *chip = snd_pcm_substream_chip(substream);
340 ca0106_channel_t *channel = &(chip->capture_channels[channel_id]);
341 ca0106_pcm_t *epcm;
342 snd_pcm_runtime_t *runtime = substream->runtime;
343 int err;
344
345 epcm = kcalloc(1, sizeof(*epcm), GFP_KERNEL);
346 if (epcm == NULL) {
347 snd_printk("open_capture_channel: failed epcm alloc\n");
348 return -ENOMEM;
349 }
350 epcm->emu = chip;
351 epcm->substream = substream;
352 epcm->channel_id=channel_id;
353
354 runtime->private_data = epcm;
355 runtime->private_free = snd_ca0106_pcm_free_substream;
356
357 runtime->hw = snd_ca0106_capture_hw;
358
359 channel->emu = chip;
360 channel->number = channel_id;
361
362 channel->use=1;
363 //printk("open:channel_id=%d, chip=%p, channel=%p\n",channel_id, chip, channel);
364 //channel->interrupt = snd_ca0106_pcm_channel_interrupt;
365 channel->epcm=epcm;
366 if ((err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS)) < 0)
367 return err;
368 //snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_SIZE, &hw_constraints_capture_period_sizes);
369 if ((err = snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 64)) < 0)
370 return err;
371 return 0;
372}
373
374/* close callback */
375static int snd_ca0106_pcm_close_capture(snd_pcm_substream_t *substream)
376{
377 ca0106_t *chip = snd_pcm_substream_chip(substream);
378 snd_pcm_runtime_t *runtime = substream->runtime;
379 ca0106_pcm_t *epcm = runtime->private_data;
380 chip->capture_channels[epcm->channel_id].use=0;
381/* FIXME: maybe zero others */
382 return 0;
383}
384
385static int snd_ca0106_pcm_open_0_capture(snd_pcm_substream_t *substream)
386{
387 return snd_ca0106_pcm_open_capture_channel(substream, 0);
388}
389
390static int snd_ca0106_pcm_open_1_capture(snd_pcm_substream_t *substream)
391{
392 return snd_ca0106_pcm_open_capture_channel(substream, 1);
393}
394
395static int snd_ca0106_pcm_open_2_capture(snd_pcm_substream_t *substream)
396{
397 return snd_ca0106_pcm_open_capture_channel(substream, 2);
398}
399
400static int snd_ca0106_pcm_open_3_capture(snd_pcm_substream_t *substream)
401{
402 return snd_ca0106_pcm_open_capture_channel(substream, 3);
403}
404
405/* hw_params callback */
406static int snd_ca0106_pcm_hw_params_playback(snd_pcm_substream_t *substream,
407 snd_pcm_hw_params_t * hw_params)
408{
409 return snd_pcm_lib_malloc_pages(substream,
410 params_buffer_bytes(hw_params));
411}
412
413/* hw_free callback */
414static int snd_ca0106_pcm_hw_free_playback(snd_pcm_substream_t *substream)
415{
416 return snd_pcm_lib_free_pages(substream);
417}
418
419/* hw_params callback */
420static int snd_ca0106_pcm_hw_params_capture(snd_pcm_substream_t *substream,
421 snd_pcm_hw_params_t * hw_params)
422{
423 return snd_pcm_lib_malloc_pages(substream,
424 params_buffer_bytes(hw_params));
425}
426
427/* hw_free callback */
428static int snd_ca0106_pcm_hw_free_capture(snd_pcm_substream_t *substream)
429{
430 return snd_pcm_lib_free_pages(substream);
431}
432
433/* prepare playback callback */
434static int snd_ca0106_pcm_prepare_playback(snd_pcm_substream_t *substream)
435{
436 ca0106_t *emu = snd_pcm_substream_chip(substream);
437 snd_pcm_runtime_t *runtime = substream->runtime;
438 ca0106_pcm_t *epcm = runtime->private_data;
439 int channel = epcm->channel_id;
440 u32 *table_base = (u32 *)(emu->buffer.area+(8*16*channel));
441 u32 period_size_bytes = frames_to_bytes(runtime, runtime->period_size);
442 u32 hcfg_mask = HCFG_PLAYBACK_S32_LE;
443 u32 hcfg_set = 0x00000000;
444 u32 hcfg;
445 u32 reg40_mask = 0x30000 << (channel<<1);
446 u32 reg40_set = 0;
447 u32 reg40;
448 /* FIXME: Depending on mixer selection of SPDIF out or not, select the spdif rate or the DAC rate. */
449 u32 reg71_mask = 0x03030000 ; /* Global. Set SPDIF rate. We only support 44100 to spdif, not to DAC. */
450 u32 reg71_set = 0;
451 u32 reg71;
452 int i;
453
454 //snd_printk("prepare:channel_number=%d, rate=%d, format=0x%x, channels=%d, buffer_size=%ld, period_size=%ld, periods=%u, frames_to_bytes=%d\n",channel, runtime->rate, runtime->format, runtime->channels, runtime->buffer_size, runtime->period_size, runtime->periods, frames_to_bytes(runtime, 1));
455 //snd_printk("dma_addr=%x, dma_area=%p, table_base=%p\n",runtime->dma_addr, runtime->dma_area, table_base);
456 //snd_printk("dma_addr=%x, dma_area=%p, dma_bytes(size)=%x\n",emu->buffer.addr, emu->buffer.area, emu->buffer.bytes);
457 /* Rate can be set per channel. */
458 /* reg40 control host to fifo */
459 /* reg71 controls DAC rate. */
460 switch (runtime->rate) {
461 case 44100:
462 reg40_set = 0x10000 << (channel<<1);
463 reg71_set = 0x01010000;
464 break;
465 case 48000:
466 reg40_set = 0;
467 reg71_set = 0;
468 break;
469 case 96000:
470 reg40_set = 0x20000 << (channel<<1);
471 reg71_set = 0x02020000;
472 break;
473 case 192000:
474 reg40_set = 0x30000 << (channel<<1);
475 reg71_set = 0x03030000;
476 break;
477 default:
478 reg40_set = 0;
479 reg71_set = 0;
480 break;
481 }
482 /* Format is a global setting */
483 /* FIXME: Only let the first channel accessed set this. */
484 switch (runtime->format) {
485 case SNDRV_PCM_FORMAT_S16_LE:
486 hcfg_set = 0;
487 break;
488 case SNDRV_PCM_FORMAT_S32_LE:
489 hcfg_set = HCFG_PLAYBACK_S32_LE;
490 break;
491 default:
492 hcfg_set = 0;
493 break;
494 }
495 hcfg = inl(emu->port + HCFG) ;
496 hcfg = (hcfg & ~hcfg_mask) | hcfg_set;
497 outl(hcfg, emu->port + HCFG);
498 reg40 = snd_ca0106_ptr_read(emu, 0x40, 0);
499 reg40 = (reg40 & ~reg40_mask) | reg40_set;
500 snd_ca0106_ptr_write(emu, 0x40, 0, reg40);
501 reg71 = snd_ca0106_ptr_read(emu, 0x71, 0);
502 reg71 = (reg71 & ~reg71_mask) | reg71_set;
503 snd_ca0106_ptr_write(emu, 0x71, 0, reg71);
504
505 /* FIXME: Check emu->buffer.size before actually writing to it. */
506 for(i=0; i < runtime->periods; i++) {
507 table_base[i*2]=runtime->dma_addr+(i*period_size_bytes);
508 table_base[(i*2)+1]=period_size_bytes<<16;
509 }
510
511 snd_ca0106_ptr_write(emu, PLAYBACK_LIST_ADDR, channel, emu->buffer.addr+(8*16*channel));
512 snd_ca0106_ptr_write(emu, PLAYBACK_LIST_SIZE, channel, (runtime->periods - 1) << 19);
513 snd_ca0106_ptr_write(emu, PLAYBACK_LIST_PTR, channel, 0);
514 snd_ca0106_ptr_write(emu, PLAYBACK_DMA_ADDR, channel, runtime->dma_addr);
515 snd_ca0106_ptr_write(emu, PLAYBACK_PERIOD_SIZE, channel, frames_to_bytes(runtime, runtime->period_size)<<16); // buffer size in bytes
516 /* FIXME test what 0 bytes does. */
517 snd_ca0106_ptr_write(emu, PLAYBACK_PERIOD_SIZE, channel, 0); // buffer size in bytes
518 snd_ca0106_ptr_write(emu, PLAYBACK_POINTER, channel, 0);
519 snd_ca0106_ptr_write(emu, 0x07, channel, 0x0);
520 snd_ca0106_ptr_write(emu, 0x08, channel, 0);
521 snd_ca0106_ptr_write(emu, PLAYBACK_MUTE, 0x0, 0x0); /* Unmute output */
522#if 0
523 snd_ca0106_ptr_write(emu, SPCS0, 0,
524 SPCS_CLKACCY_1000PPM | SPCS_SAMPLERATE_48 |
525 SPCS_CHANNELNUM_LEFT | SPCS_SOURCENUM_UNSPEC |
526 SPCS_GENERATIONSTATUS | 0x00001200 |
527 0x00000000 | SPCS_EMPHASIS_NONE | SPCS_COPYRIGHT );
528 }
529#endif
530
531 return 0;
532}
533
534/* prepare capture callback */
535static int snd_ca0106_pcm_prepare_capture(snd_pcm_substream_t *substream)
536{
537 ca0106_t *emu = snd_pcm_substream_chip(substream);
538 snd_pcm_runtime_t *runtime = substream->runtime;
539 ca0106_pcm_t *epcm = runtime->private_data;
540 int channel = epcm->channel_id;
541 //printk("prepare:channel_number=%d, rate=%d, format=0x%x, channels=%d, buffer_size=%ld, period_size=%ld, frames_to_bytes=%d\n",channel, runtime->rate, runtime->format, runtime->channels, runtime->buffer_size, runtime->period_size, frames_to_bytes(runtime, 1));
542 snd_ca0106_ptr_write(emu, 0x13, channel, 0);
543 snd_ca0106_ptr_write(emu, CAPTURE_DMA_ADDR, channel, runtime->dma_addr);
544 snd_ca0106_ptr_write(emu, CAPTURE_BUFFER_SIZE, channel, frames_to_bytes(runtime, runtime->buffer_size)<<16); // buffer size in bytes
545 snd_ca0106_ptr_write(emu, CAPTURE_POINTER, channel, 0);
546
547 return 0;
548}
549
550/* trigger_playback callback */
551static int snd_ca0106_pcm_trigger_playback(snd_pcm_substream_t *substream,
552 int cmd)
553{
554 ca0106_t *emu = snd_pcm_substream_chip(substream);
555 snd_pcm_runtime_t *runtime;
556 ca0106_pcm_t *epcm;
557 int channel;
558 int result = 0;
559 struct list_head *pos;
560 snd_pcm_substream_t *s;
561 u32 basic = 0;
562 u32 extended = 0;
563 int running=0;
564
565 switch (cmd) {
566 case SNDRV_PCM_TRIGGER_START:
567 running=1;
568 break;
569 case SNDRV_PCM_TRIGGER_STOP:
570 default:
571 running=0;
572 break;
573 }
574 snd_pcm_group_for_each(pos, substream) {
575 s = snd_pcm_group_substream_entry(pos);
576 runtime = s->runtime;
577 epcm = runtime->private_data;
578 channel = epcm->channel_id;
579 //snd_printk("channel=%d\n",channel);
580 epcm->running = running;
581 basic |= (0x1<<channel);
582 extended |= (0x10<<channel);
583 snd_pcm_trigger_done(s, substream);
584 }
585 //snd_printk("basic=0x%x, extended=0x%x\n",basic, extended);
586
587 switch (cmd) {
588 case SNDRV_PCM_TRIGGER_START:
589 snd_ca0106_ptr_write(emu, EXTENDED_INT_MASK, 0, snd_ca0106_ptr_read(emu, EXTENDED_INT_MASK, 0) | (extended));
590 snd_ca0106_ptr_write(emu, BASIC_INTERRUPT, 0, snd_ca0106_ptr_read(emu, BASIC_INTERRUPT, 0)|(basic));
591 break;
592 case SNDRV_PCM_TRIGGER_STOP:
593 snd_ca0106_ptr_write(emu, BASIC_INTERRUPT, 0, snd_ca0106_ptr_read(emu, BASIC_INTERRUPT, 0) & ~(basic));
594 snd_ca0106_ptr_write(emu, EXTENDED_INT_MASK, 0, snd_ca0106_ptr_read(emu, EXTENDED_INT_MASK, 0) & ~(extended));
595 break;
596 default:
597 result = -EINVAL;
598 break;
599 }
600 return result;
601}
602
603/* trigger_capture callback */
604static int snd_ca0106_pcm_trigger_capture(snd_pcm_substream_t *substream,
605 int cmd)
606{
607 ca0106_t *emu = snd_pcm_substream_chip(substream);
608 snd_pcm_runtime_t *runtime = substream->runtime;
609 ca0106_pcm_t *epcm = runtime->private_data;
610 int channel = epcm->channel_id;
611 int result = 0;
612
613 switch (cmd) {
614 case SNDRV_PCM_TRIGGER_START:
615 snd_ca0106_ptr_write(emu, EXTENDED_INT_MASK, 0, snd_ca0106_ptr_read(emu, EXTENDED_INT_MASK, 0) | (0x110000<<channel));
616 snd_ca0106_ptr_write(emu, BASIC_INTERRUPT, 0, snd_ca0106_ptr_read(emu, BASIC_INTERRUPT, 0)|(0x100<<channel));
617 epcm->running = 1;
618 break;
619 case SNDRV_PCM_TRIGGER_STOP:
620 snd_ca0106_ptr_write(emu, BASIC_INTERRUPT, 0, snd_ca0106_ptr_read(emu, BASIC_INTERRUPT, 0) & ~(0x100<<channel));
621 snd_ca0106_ptr_write(emu, EXTENDED_INT_MASK, 0, snd_ca0106_ptr_read(emu, EXTENDED_INT_MASK, 0) & ~(0x110000<<channel));
622 epcm->running = 0;
623 break;
624 default:
625 result = -EINVAL;
626 break;
627 }
628 return result;
629}
630
631/* pointer_playback callback */
632static snd_pcm_uframes_t
633snd_ca0106_pcm_pointer_playback(snd_pcm_substream_t *substream)
634{
635 ca0106_t *emu = snd_pcm_substream_chip(substream);
636 snd_pcm_runtime_t *runtime = substream->runtime;
637 ca0106_pcm_t *epcm = runtime->private_data;
638 snd_pcm_uframes_t ptr, ptr1, ptr2,ptr3,ptr4 = 0;
639 int channel = epcm->channel_id;
640
641 if (!epcm->running)
642 return 0;
643
644 ptr3 = snd_ca0106_ptr_read(emu, PLAYBACK_LIST_PTR, channel);
645 ptr1 = snd_ca0106_ptr_read(emu, PLAYBACK_POINTER, channel);
646 ptr4 = snd_ca0106_ptr_read(emu, PLAYBACK_LIST_PTR, channel);
647 if (ptr3 != ptr4) ptr1 = snd_ca0106_ptr_read(emu, PLAYBACK_POINTER, channel);
648 ptr2 = bytes_to_frames(runtime, ptr1);
649 ptr2+= (ptr4 >> 3) * runtime->period_size;
650 ptr=ptr2;
651 if (ptr >= runtime->buffer_size)
652 ptr -= runtime->buffer_size;
653 //printk("ptr1 = 0x%lx, ptr2=0x%lx, ptr=0x%lx, buffer_size = 0x%x, period_size = 0x%x, bits=%d, rate=%d\n", ptr1, ptr2, ptr, (int)runtime->buffer_size, (int)runtime->period_size, (int)runtime->frame_bits, (int)runtime->rate);
654
655 return ptr;
656}
657
658/* pointer_capture callback */
659static snd_pcm_uframes_t
660snd_ca0106_pcm_pointer_capture(snd_pcm_substream_t *substream)
661{
662 ca0106_t *emu = snd_pcm_substream_chip(substream);
663 snd_pcm_runtime_t *runtime = substream->runtime;
664 ca0106_pcm_t *epcm = runtime->private_data;
665 snd_pcm_uframes_t ptr, ptr1, ptr2 = 0;
666 int channel = channel=epcm->channel_id;
667
668 if (!epcm->running)
669 return 0;
670
671 ptr1 = snd_ca0106_ptr_read(emu, CAPTURE_POINTER, channel);
672 ptr2 = bytes_to_frames(runtime, ptr1);
673 ptr=ptr2;
674 if (ptr >= runtime->buffer_size)
675 ptr -= runtime->buffer_size;
676 //printk("ptr1 = 0x%lx, ptr2=0x%lx, ptr=0x%lx, buffer_size = 0x%x, period_size = 0x%x, bits=%d, rate=%d\n", ptr1, ptr2, ptr, (int)runtime->buffer_size, (int)runtime->period_size, (int)runtime->frame_bits, (int)runtime->rate);
677
678 return ptr;
679}
680
681/* operators */
682static snd_pcm_ops_t snd_ca0106_playback_front_ops = {
683 .open = snd_ca0106_pcm_open_playback_front,
684 .close = snd_ca0106_pcm_close_playback,
685 .ioctl = snd_pcm_lib_ioctl,
686 .hw_params = snd_ca0106_pcm_hw_params_playback,
687 .hw_free = snd_ca0106_pcm_hw_free_playback,
688 .prepare = snd_ca0106_pcm_prepare_playback,
689 .trigger = snd_ca0106_pcm_trigger_playback,
690 .pointer = snd_ca0106_pcm_pointer_playback,
691};
692
693static snd_pcm_ops_t snd_ca0106_capture_0_ops = {
694 .open = snd_ca0106_pcm_open_0_capture,
695 .close = snd_ca0106_pcm_close_capture,
696 .ioctl = snd_pcm_lib_ioctl,
697 .hw_params = snd_ca0106_pcm_hw_params_capture,
698 .hw_free = snd_ca0106_pcm_hw_free_capture,
699 .prepare = snd_ca0106_pcm_prepare_capture,
700 .trigger = snd_ca0106_pcm_trigger_capture,
701 .pointer = snd_ca0106_pcm_pointer_capture,
702};
703
704static snd_pcm_ops_t snd_ca0106_capture_1_ops = {
705 .open = snd_ca0106_pcm_open_1_capture,
706 .close = snd_ca0106_pcm_close_capture,
707 .ioctl = snd_pcm_lib_ioctl,
708 .hw_params = snd_ca0106_pcm_hw_params_capture,
709 .hw_free = snd_ca0106_pcm_hw_free_capture,
710 .prepare = snd_ca0106_pcm_prepare_capture,
711 .trigger = snd_ca0106_pcm_trigger_capture,
712 .pointer = snd_ca0106_pcm_pointer_capture,
713};
714
715static snd_pcm_ops_t snd_ca0106_capture_2_ops = {
716 .open = snd_ca0106_pcm_open_2_capture,
717 .close = snd_ca0106_pcm_close_capture,
718 .ioctl = snd_pcm_lib_ioctl,
719 .hw_params = snd_ca0106_pcm_hw_params_capture,
720 .hw_free = snd_ca0106_pcm_hw_free_capture,
721 .prepare = snd_ca0106_pcm_prepare_capture,
722 .trigger = snd_ca0106_pcm_trigger_capture,
723 .pointer = snd_ca0106_pcm_pointer_capture,
724};
725
726static snd_pcm_ops_t snd_ca0106_capture_3_ops = {
727 .open = snd_ca0106_pcm_open_3_capture,
728 .close = snd_ca0106_pcm_close_capture,
729 .ioctl = snd_pcm_lib_ioctl,
730 .hw_params = snd_ca0106_pcm_hw_params_capture,
731 .hw_free = snd_ca0106_pcm_hw_free_capture,
732 .prepare = snd_ca0106_pcm_prepare_capture,
733 .trigger = snd_ca0106_pcm_trigger_capture,
734 .pointer = snd_ca0106_pcm_pointer_capture,
735};
736
737static snd_pcm_ops_t snd_ca0106_playback_center_lfe_ops = {
738 .open = snd_ca0106_pcm_open_playback_center_lfe,
739 .close = snd_ca0106_pcm_close_playback,
740 .ioctl = snd_pcm_lib_ioctl,
741 .hw_params = snd_ca0106_pcm_hw_params_playback,
742 .hw_free = snd_ca0106_pcm_hw_free_playback,
743 .prepare = snd_ca0106_pcm_prepare_playback,
744 .trigger = snd_ca0106_pcm_trigger_playback,
745 .pointer = snd_ca0106_pcm_pointer_playback,
746};
747
748static snd_pcm_ops_t snd_ca0106_playback_unknown_ops = {
749 .open = snd_ca0106_pcm_open_playback_unknown,
750 .close = snd_ca0106_pcm_close_playback,
751 .ioctl = snd_pcm_lib_ioctl,
752 .hw_params = snd_ca0106_pcm_hw_params_playback,
753 .hw_free = snd_ca0106_pcm_hw_free_playback,
754 .prepare = snd_ca0106_pcm_prepare_playback,
755 .trigger = snd_ca0106_pcm_trigger_playback,
756 .pointer = snd_ca0106_pcm_pointer_playback,
757};
758
759static snd_pcm_ops_t snd_ca0106_playback_rear_ops = {
760 .open = snd_ca0106_pcm_open_playback_rear,
761 .close = snd_ca0106_pcm_close_playback,
762 .ioctl = snd_pcm_lib_ioctl,
763 .hw_params = snd_ca0106_pcm_hw_params_playback,
764 .hw_free = snd_ca0106_pcm_hw_free_playback,
765 .prepare = snd_ca0106_pcm_prepare_playback,
766 .trigger = snd_ca0106_pcm_trigger_playback,
767 .pointer = snd_ca0106_pcm_pointer_playback,
768};
769
770
771static unsigned short snd_ca0106_ac97_read(ac97_t *ac97,
772 unsigned short reg)
773{
774 ca0106_t *emu = ac97->private_data;
775 unsigned long flags;
776 unsigned short val;
777
778 spin_lock_irqsave(&emu->emu_lock, flags);
779 outb(reg, emu->port + AC97ADDRESS);
780 val = inw(emu->port + AC97DATA);
781 spin_unlock_irqrestore(&emu->emu_lock, flags);
782 return val;
783}
784
785static void snd_ca0106_ac97_write(ac97_t *ac97,
786 unsigned short reg, unsigned short val)
787{
788 ca0106_t *emu = ac97->private_data;
789 unsigned long flags;
790
791 spin_lock_irqsave(&emu->emu_lock, flags);
792 outb(reg, emu->port + AC97ADDRESS);
793 outw(val, emu->port + AC97DATA);
794 spin_unlock_irqrestore(&emu->emu_lock, flags);
795}
796
797static int snd_ca0106_ac97(ca0106_t *chip)
798{
799 ac97_bus_t *pbus;
800 ac97_template_t ac97;
801 int err;
802 static ac97_bus_ops_t ops = {
803 .write = snd_ca0106_ac97_write,
804 .read = snd_ca0106_ac97_read,
805 };
806
807 if ((err = snd_ac97_bus(chip->card, 0, &ops, NULL, &pbus)) < 0)
808 return err;
809 pbus->no_vra = 1; /* we don't need VRA */
810
811 memset(&ac97, 0, sizeof(ac97));
812 ac97.private_data = chip;
813 return snd_ac97_mixer(pbus, &ac97, &chip->ac97);
814}
815
816static int snd_ca0106_free(ca0106_t *chip)
817{
818 if (chip->res_port != NULL) { /* avoid access to already used hardware */
819 // disable interrupts
820 snd_ca0106_ptr_write(chip, BASIC_INTERRUPT, 0, 0);
821 outl(0, chip->port + INTE);
822 snd_ca0106_ptr_write(chip, EXTENDED_INT_MASK, 0, 0);
823 udelay(1000);
824 // disable audio
825 //outl(HCFG_LOCKSOUNDCACHE, chip->port + HCFG);
826 outl(0, chip->port + HCFG);
827 /* FIXME: We need to stop and DMA transfers here.
828 * But as I am not sure how yet, we cannot from the dma pages.
829 * So we can fix: snd-malloc: Memory leak? pages not freed = 8
830 */
831 }
832 // release the data
833#if 1
834 if (chip->buffer.area)
835 snd_dma_free_pages(&chip->buffer);
836#endif
837
838 // release the i/o port
839 if (chip->res_port) {
840 release_resource(chip->res_port);
841 kfree_nocheck(chip->res_port);
842 }
843 // release the irq
844 if (chip->irq >= 0)
845 free_irq(chip->irq, (void *)chip);
846 pci_disable_device(chip->pci);
847 kfree(chip);
848 return 0;
849}
850
851static int snd_ca0106_dev_free(snd_device_t *device)
852{
853 ca0106_t *chip = device->device_data;
854 return snd_ca0106_free(chip);
855}
856
857static irqreturn_t snd_ca0106_interrupt(int irq, void *dev_id,
858 struct pt_regs *regs)
859{
860 unsigned int status;
861
862 ca0106_t *chip = dev_id;
863 int i;
864 int mask;
865 unsigned int stat76;
866 ca0106_channel_t *pchannel;
867
868 spin_lock(&chip->emu_lock);
869
870 status = inl(chip->port + IPR);
871
872 // call updater, unlock before it
873 spin_unlock(&chip->emu_lock);
874
875 if (! status)
876 return IRQ_NONE;
877
878 stat76 = snd_ca0106_ptr_read(chip, EXTENDED_INT, 0);
879 //snd_printk("interrupt status = 0x%08x, stat76=0x%08x\n", status, stat76);
880 //snd_printk("ptr=0x%08x\n",snd_ca0106_ptr_read(chip, PLAYBACK_POINTER, 0));
881 mask = 0x11; /* 0x1 for one half, 0x10 for the other half period. */
882 for(i = 0; i < 4; i++) {
883 pchannel = &(chip->playback_channels[i]);
884 if(stat76 & mask) {
885/* FIXME: Select the correct substream for period elapsed */
886 if(pchannel->use) {
887 snd_pcm_period_elapsed(pchannel->epcm->substream);
888 //printk(KERN_INFO "interrupt [%d] used\n", i);
889 }
890 }
891 //printk(KERN_INFO "channel=%p\n",pchannel);
892 //printk(KERN_INFO "interrupt stat76[%d] = %08x, use=%d, channel=%d\n", i, stat76, pchannel->use, pchannel->number);
893 mask <<= 1;
894 }
895 mask = 0x110000; /* 0x1 for one half, 0x10 for the other half period. */
896 for(i = 0; i < 4; i++) {
897 pchannel = &(chip->capture_channels[i]);
898 if(stat76 & mask) {
899/* FIXME: Select the correct substream for period elapsed */
900 if(pchannel->use) {
901 snd_pcm_period_elapsed(pchannel->epcm->substream);
902 //printk(KERN_INFO "interrupt [%d] used\n", i);
903 }
904 }
905 //printk(KERN_INFO "channel=%p\n",pchannel);
906 //printk(KERN_INFO "interrupt stat76[%d] = %08x, use=%d, channel=%d\n", i, stat76, pchannel->use, pchannel->number);
907 mask <<= 1;
908 }
909
910 snd_ca0106_ptr_write(chip, EXTENDED_INT, 0, stat76);
911 spin_lock(&chip->emu_lock);
912 // acknowledge the interrupt if necessary
913 outl(status, chip->port+IPR);
914
915 spin_unlock(&chip->emu_lock);
916
917 return IRQ_HANDLED;
918}
919
920static void snd_ca0106_pcm_free(snd_pcm_t *pcm)
921{
922 ca0106_t *emu = pcm->private_data;
923 emu->pcm = NULL;
924 snd_pcm_lib_preallocate_free_for_all(pcm);
925}
926
927static int __devinit snd_ca0106_pcm(ca0106_t *emu, int device, snd_pcm_t **rpcm)
928{
929 snd_pcm_t *pcm;
930 snd_pcm_substream_t *substream;
931 int err;
932
933 if (rpcm)
934 *rpcm = NULL;
935 if ((err = snd_pcm_new(emu->card, "ca0106", device, 1, 1, &pcm)) < 0)
936 return err;
937
938 pcm->private_data = emu;
939 pcm->private_free = snd_ca0106_pcm_free;
940
941 switch (device) {
942 case 0:
943 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_ca0106_playback_front_ops);
944 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_ca0106_capture_0_ops);
945 break;
946 case 1:
947 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_ca0106_playback_rear_ops);
948 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_ca0106_capture_1_ops);
949 break;
950 case 2:
951 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_ca0106_playback_center_lfe_ops);
952 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_ca0106_capture_2_ops);
953 break;
954 case 3:
955 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_ca0106_playback_unknown_ops);
956 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_ca0106_capture_3_ops);
957 break;
958 }
959
960 pcm->info_flags = 0;
961 pcm->dev_subclass = SNDRV_PCM_SUBCLASS_GENERIC_MIX;
962 strcpy(pcm->name, "CA0106");
963 emu->pcm = pcm;
964
965 for(substream = pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream;
966 substream;
967 substream = substream->next) {
968 if ((err = snd_pcm_lib_preallocate_pages(substream,
969 SNDRV_DMA_TYPE_DEV,
970 snd_dma_pci_data(emu->pci),
971 64*1024, 64*1024)) < 0) /* FIXME: 32*1024 for sound buffer, between 32and64 for Periods table. */
972 return err;
973 }
974
975 for (substream = pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream;
976 substream;
977 substream = substream->next) {
978 if ((err = snd_pcm_lib_preallocate_pages(substream,
979 SNDRV_DMA_TYPE_DEV,
980 snd_dma_pci_data(emu->pci),
981 64*1024, 64*1024)) < 0)
982 return err;
983 }
984
985 if (rpcm)
986 *rpcm = pcm;
987
988 return 0;
989}
990
991static int __devinit snd_ca0106_create(snd_card_t *card,
992 struct pci_dev *pci,
993 ca0106_t **rchip)
994{
995 ca0106_t *chip;
996 int err;
997 int ch;
998 static snd_device_ops_t ops = {
999 .dev_free = snd_ca0106_dev_free,
1000 };
1001
1002 *rchip = NULL;
1003
1004 if ((err = pci_enable_device(pci)) < 0)
1005 return err;
1006 if (pci_set_dma_mask(pci, 0xffffffffUL) < 0 ||
1007 pci_set_consistent_dma_mask(pci, 0xffffffffUL) < 0) {
1008 printk(KERN_ERR "error to set 32bit mask DMA\n");
1009 pci_disable_device(pci);
1010 return -ENXIO;
1011 }
1012
1013 chip = kcalloc(1, sizeof(*chip), GFP_KERNEL);
1014 if (chip == NULL) {
1015 pci_disable_device(pci);
1016 return -ENOMEM;
1017 }
1018
1019 chip->card = card;
1020 chip->pci = pci;
1021 chip->irq = -1;
1022
1023 spin_lock_init(&chip->emu_lock);
1024
1025 chip->port = pci_resource_start(pci, 0);
1026 if ((chip->res_port = request_region(chip->port, 0x20,
1027 "snd_ca0106")) == NULL) {
1028 snd_ca0106_free(chip);
1029 printk(KERN_ERR "cannot allocate the port\n");
1030 return -EBUSY;
1031 }
1032
1033 if (request_irq(pci->irq, snd_ca0106_interrupt,
1034 SA_INTERRUPT|SA_SHIRQ, "snd_ca0106",
1035 (void *)chip)) {
1036 snd_ca0106_free(chip);
1037 printk(KERN_ERR "cannot grab irq\n");
1038 return -EBUSY;
1039 }
1040 chip->irq = pci->irq;
1041
1042 /* This stores the periods table. */
1043 if(snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(pci), 1024, &chip->buffer) < 0) {
1044 snd_ca0106_free(chip);
1045 return -ENOMEM;
1046 }
1047
1048 pci_set_master(pci);
1049 /* read revision & serial */
1050 pci_read_config_byte(pci, PCI_REVISION_ID, (char *)&chip->revision);
1051 pci_read_config_dword(pci, PCI_SUBSYSTEM_VENDOR_ID, &chip->serial);
1052 pci_read_config_word(pci, PCI_SUBSYSTEM_ID, &chip->model);
1053#if 1
1054 printk(KERN_INFO "Model %04x Rev %08x Serial %08x\n", chip->model,
1055 chip->revision, chip->serial);
1056#endif
1057
1058 outl(0, chip->port + INTE);
1059
1060 /*
1061 * Init to 0x02109204 :
1062 * Clock accuracy = 0 (1000ppm)
1063 * Sample Rate = 2 (48kHz)
1064 * Audio Channel = 1 (Left of 2)
1065 * Source Number = 0 (Unspecified)
1066 * Generation Status = 1 (Original for Cat Code 12)
1067 * Cat Code = 12 (Digital Signal Mixer)
1068 * Mode = 0 (Mode 0)
1069 * Emphasis = 0 (None)
1070 * CP = 1 (Copyright unasserted)
1071 * AN = 0 (Audio data)
1072 * P = 0 (Consumer)
1073 */
1074 snd_ca0106_ptr_write(chip, SPCS0, 0,
1075 chip->spdif_bits[0] =
1076 SPCS_CLKACCY_1000PPM | SPCS_SAMPLERATE_48 |
1077 SPCS_CHANNELNUM_LEFT | SPCS_SOURCENUM_UNSPEC |
1078 SPCS_GENERATIONSTATUS | 0x00001200 |
1079 0x00000000 | SPCS_EMPHASIS_NONE | SPCS_COPYRIGHT);
1080 /* Only SPCS1 has been tested */
1081 snd_ca0106_ptr_write(chip, SPCS1, 0,
1082 chip->spdif_bits[1] =
1083 SPCS_CLKACCY_1000PPM | SPCS_SAMPLERATE_48 |
1084 SPCS_CHANNELNUM_LEFT | SPCS_SOURCENUM_UNSPEC |
1085 SPCS_GENERATIONSTATUS | 0x00001200 |
1086 0x00000000 | SPCS_EMPHASIS_NONE | SPCS_COPYRIGHT);
1087 snd_ca0106_ptr_write(chip, SPCS2, 0,
1088 chip->spdif_bits[2] =
1089 SPCS_CLKACCY_1000PPM | SPCS_SAMPLERATE_48 |
1090 SPCS_CHANNELNUM_LEFT | SPCS_SOURCENUM_UNSPEC |
1091 SPCS_GENERATIONSTATUS | 0x00001200 |
1092 0x00000000 | SPCS_EMPHASIS_NONE | SPCS_COPYRIGHT);
1093 snd_ca0106_ptr_write(chip, SPCS3, 0,
1094 chip->spdif_bits[3] =
1095 SPCS_CLKACCY_1000PPM | SPCS_SAMPLERATE_48 |
1096 SPCS_CHANNELNUM_LEFT | SPCS_SOURCENUM_UNSPEC |
1097 SPCS_GENERATIONSTATUS | 0x00001200 |
1098 0x00000000 | SPCS_EMPHASIS_NONE | SPCS_COPYRIGHT);
1099
1100 snd_ca0106_ptr_write(chip, PLAYBACK_MUTE, 0, 0x00fc0000);
1101 snd_ca0106_ptr_write(chip, CAPTURE_MUTE, 0, 0x00fc0000);
1102
1103 /* Write 0x8000 to AC97_REC_GAIN to mute it. */
1104 outb(AC97_REC_GAIN, chip->port + AC97ADDRESS);
1105 outw(0x8000, chip->port + AC97DATA);
1106#if 0
1107 snd_ca0106_ptr_write(chip, SPCS0, 0, 0x2108006);
1108 snd_ca0106_ptr_write(chip, 0x42, 0, 0x2108006);
1109 snd_ca0106_ptr_write(chip, 0x43, 0, 0x2108006);
1110 snd_ca0106_ptr_write(chip, 0x44, 0, 0x2108006);
1111#endif
1112
1113 //snd_ca0106_ptr_write(chip, SPDIF_SELECT2, 0, 0xf0f003f); /* OSS drivers set this. */
1114 /* Analog or Digital output */
1115 snd_ca0106_ptr_write(chip, SPDIF_SELECT1, 0, 0xf);
1116 snd_ca0106_ptr_write(chip, SPDIF_SELECT2, 0, 0x000b0000); /* 0x0b000000 for digital, 0x000b0000 for analog, from win2000 drivers */
1117 chip->spdif_enable = 0; /* Set digital SPDIF output off */
1118 chip->capture_source = 3; /* Set CAPTURE_SOURCE */
1119 //snd_ca0106_ptr_write(chip, 0x45, 0, 0); /* Analogue out */
1120 //snd_ca0106_ptr_write(chip, 0x45, 0, 0xf00); /* Digital out */
1121
1122 snd_ca0106_ptr_write(chip, CAPTURE_CONTROL, 0, 0x40c81000); /* goes to 0x40c80000 when doing SPDIF IN/OUT */
1123 snd_ca0106_ptr_write(chip, CAPTURE_CONTROL, 1, 0xffffffff); /* (Mute) CAPTURE feedback into PLAYBACK volume. Only lower 16 bits matter. */
1124 snd_ca0106_ptr_write(chip, CAPTURE_CONTROL, 2, 0x30300000); /* SPDIF IN Volume */
1125 snd_ca0106_ptr_write(chip, CAPTURE_CONTROL, 3, 0x00700000); /* SPDIF IN Volume, 0x70 = (vol & 0x3f) | 0x40 */
1126 snd_ca0106_ptr_write(chip, PLAYBACK_ROUTING1, 0, 0x32765410);
1127 snd_ca0106_ptr_write(chip, PLAYBACK_ROUTING2, 0, 0x76767676);
1128 snd_ca0106_ptr_write(chip, CAPTURE_ROUTING1, 0, 0x32765410);
1129 snd_ca0106_ptr_write(chip, CAPTURE_ROUTING2, 0, 0x76767676);
1130 for(ch = 0; ch < 4; ch++) {
1131 snd_ca0106_ptr_write(chip, CAPTURE_VOLUME1, ch, 0x30303030); /* Only high 16 bits matter */
1132 snd_ca0106_ptr_write(chip, CAPTURE_VOLUME2, ch, 0x30303030);
1133 //snd_ca0106_ptr_write(chip, PLAYBACK_VOLUME1, ch, 0x40404040); /* Mute */
1134 //snd_ca0106_ptr_write(chip, PLAYBACK_VOLUME2, ch, 0x40404040); /* Mute */
1135 snd_ca0106_ptr_write(chip, PLAYBACK_VOLUME1, ch, 0xffffffff); /* Mute */
1136 snd_ca0106_ptr_write(chip, PLAYBACK_VOLUME2, ch, 0xffffffff); /* Mute */
1137 }
1138 snd_ca0106_ptr_write(chip, CAPTURE_SOURCE, 0x0, 0x333300e4); /* Select MIC, Line in, TAD in, AUX in */
1139 chip->capture_source = 3; /* Set CAPTURE_SOURCE */
1140
1141 if ((chip->serial == 0x10061102) ||
1142 (chip->serial == 0x10071102) ||
1143 (chip->serial == 0x10091462)) { /* The SB0410 and SB0413 use GPIO differently. */
1144 /* FIXME: Still need to find out what the other GPIO bits do. E.g. For digital spdif out. */
1145 outl(0x0, chip->port+GPIO);
1146 //outl(0x00f0e000, chip->port+GPIO); /* Analog */
1147 outl(0x005f4300, chip->port+GPIO); /* Analog */
1148 } else {
1149 outl(0x0, chip->port+GPIO);
1150 outl(0x005f03a3, chip->port+GPIO); /* Analog */
1151 //outl(0x005f02a2, chip->port+GPIO); /* SPDIF */
1152 }
1153 snd_ca0106_intr_enable(chip, 0x105); /* Win2000 uses 0x1e0 */
1154
1155 //outl(HCFG_LOCKSOUNDCACHE|HCFG_AUDIOENABLE, chip->port+HCFG);
1156 //outl(0x00001409, chip->port+HCFG); /* 0x1000 causes AC3 to fails. Maybe it effects 24 bit output. */
1157 //outl(0x00000009, chip->port+HCFG);
1158 outl(HCFG_AC97 | HCFG_AUDIOENABLE, chip->port+HCFG); /* AC97 2.0, Enable outputs. */
1159
1160 if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL,
1161 chip, &ops)) < 0) {
1162 snd_ca0106_free(chip);
1163 return err;
1164 }
1165 *rchip = chip;
1166 return 0;
1167}
1168
1169static int __devinit snd_ca0106_probe(struct pci_dev *pci,
1170 const struct pci_device_id *pci_id)
1171{
1172 static int dev;
1173 snd_card_t *card;
1174 ca0106_t *chip;
1175 ca0106_names_t *c;
1176 int err;
1177
1178 if (dev >= SNDRV_CARDS)
1179 return -ENODEV;
1180 if (!enable[dev]) {
1181 dev++;
1182 return -ENOENT;
1183 }
1184
1185 card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
1186 if (card == NULL)
1187 return -ENOMEM;
1188
1189 if ((err = snd_ca0106_create(card, pci, &chip)) < 0) {
1190 snd_card_free(card);
1191 return err;
1192 }
1193
1194 if ((err = snd_ca0106_pcm(chip, 0, NULL)) < 0) {
1195 snd_card_free(card);
1196 return err;
1197 }
1198 if ((err = snd_ca0106_pcm(chip, 1, NULL)) < 0) {
1199 snd_card_free(card);
1200 return err;
1201 }
1202 if ((err = snd_ca0106_pcm(chip, 2, NULL)) < 0) {
1203 snd_card_free(card);
1204 return err;
1205 }
1206 if ((err = snd_ca0106_pcm(chip, 3, NULL)) < 0) {
1207 snd_card_free(card);
1208 return err;
1209 }
1210 if ((chip->serial != 0x10061102) &&
1211 (chip->serial != 0x10071102) &&
1212 (chip->serial != 0x10091462) ) { /* The SB0410 and SB0413 do not have an ac97 chip. */
1213 if ((err = snd_ca0106_ac97(chip)) < 0) {
1214 snd_card_free(card);
1215 return err;
1216 }
1217 }
1218 if ((err = snd_ca0106_mixer(chip)) < 0) {
1219 snd_card_free(card);
1220 return err;
1221 }
1222
1223 snd_ca0106_proc_init(chip);
1224
1225 strcpy(card->driver, "CA0106");
1226 strcpy(card->shortname, "CA0106");
1227
1228 for (c=ca0106_chip_names; c->serial; c++) {
1229 if (c->serial == chip->serial) break;
1230 }
1231 sprintf(card->longname, "%s at 0x%lx irq %i",
1232 c->name, chip->port, chip->irq);
1233
1234 if ((err = snd_card_register(card)) < 0) {
1235 snd_card_free(card);
1236 return err;
1237 }
1238
1239 pci_set_drvdata(pci, card);
1240 dev++;
1241 return 0;
1242}
1243
1244static void __devexit snd_ca0106_remove(struct pci_dev *pci)
1245{
1246 snd_card_free(pci_get_drvdata(pci));
1247 pci_set_drvdata(pci, NULL);
1248}
1249
1250// PCI IDs
1251static struct pci_device_id snd_ca0106_ids[] = {
1252 { 0x1102, 0x0007, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* Audigy LS or Live 24bit */
1253 { 0, }
1254};
1255MODULE_DEVICE_TABLE(pci, snd_ca0106_ids);
1256
1257// pci_driver definition
1258static struct pci_driver driver = {
1259 .name = "CA0106",
1260 .id_table = snd_ca0106_ids,
1261 .probe = snd_ca0106_probe,
1262 .remove = __devexit_p(snd_ca0106_remove),
1263};
1264
1265// initialization of the module
1266static int __init alsa_card_ca0106_init(void)
1267{
1268 int err;
1269
1270 if ((err = pci_module_init(&driver)) > 0)
1271 return err;
1272
1273 return 0;
1274}
1275
1276// clean up the module
1277static void __exit alsa_card_ca0106_exit(void)
1278{
1279 pci_unregister_driver(&driver);
1280}
1281
1282module_init(alsa_card_ca0106_init)
1283module_exit(alsa_card_ca0106_exit)
diff --git a/sound/pci/ca0106/ca0106_mixer.c b/sound/pci/ca0106/ca0106_mixer.c
new file mode 100644
index 000000000000..97bed1b0899d
--- /dev/null
+++ b/sound/pci/ca0106/ca0106_mixer.c
@@ -0,0 +1,634 @@
1/*
2 * Copyright (c) 2004 James Courtier-Dutton <James@superbug.demon.co.uk>
3 * Driver CA0106 chips. e.g. Sound Blaster Audigy LS and Live 24bit
4 * Version: 0.0.16
5 *
6 * FEATURES currently supported:
7 * See ca0106_main.c for features.
8 *
9 * Changelog:
10 * Support interrupts per period.
11 * Removed noise from Center/LFE channel when in Analog mode.
12 * Rename and remove mixer controls.
13 * 0.0.6
14 * Use separate card based DMA buffer for periods table list.
15 * 0.0.7
16 * Change remove and rename ctrls into lists.
17 * 0.0.8
18 * Try to fix capture sources.
19 * 0.0.9
20 * Fix AC3 output.
21 * Enable S32_LE format support.
22 * 0.0.10
23 * Enable playback 48000 and 96000 rates. (Rates other that these do not work, even with "plug:front".)
24 * 0.0.11
25 * Add Model name recognition.
26 * 0.0.12
27 * Correct interrupt timing. interrupt at end of period, instead of in the middle of a playback period.
28 * Remove redundent "voice" handling.
29 * 0.0.13
30 * Single trigger call for multi channels.
31 * 0.0.14
32 * Set limits based on what the sound card hardware can do.
33 * playback periods_min=2, periods_max=8
34 * capture hw constraints require period_size = n * 64 bytes.
35 * playback hw constraints require period_size = n * 64 bytes.
36 * 0.0.15
37 * Separated ca0106.c into separate functional .c files.
38 * 0.0.16
39 * Modified Copyright message.
40 *
41 * This code was initally based on code from ALSA's emu10k1x.c which is:
42 * Copyright (c) by Francisco Moraes <fmoraes@nc.rr.com>
43 *
44 * This program is free software; you can redistribute it and/or modify
45 * it under the terms of the GNU General Public License as published by
46 * the Free Software Foundation; either version 2 of the License, or
47 * (at your option) any later version.
48 *
49 * This program is distributed in the hope that it will be useful,
50 * but WITHOUT ANY WARRANTY; without even the implied warranty of
51 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
52 * GNU General Public License for more details.
53 *
54 * You should have received a copy of the GNU General Public License
55 * along with this program; if not, write to the Free Software
56 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
57 *
58 */
59#include <sound/driver.h>
60#include <linux/delay.h>
61#include <linux/init.h>
62#include <linux/interrupt.h>
63#include <linux/pci.h>
64#include <linux/slab.h>
65#include <linux/moduleparam.h>
66#include <sound/core.h>
67#include <sound/initval.h>
68#include <sound/pcm.h>
69#include <sound/ac97_codec.h>
70#include <sound/info.h>
71
72#include "ca0106.h"
73
74static int snd_ca0106_shared_spdif_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
75{
76 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
77 uinfo->count = 1;
78 uinfo->value.integer.min = 0;
79 uinfo->value.integer.max = 1;
80 return 0;
81}
82
83static int snd_ca0106_shared_spdif_get(snd_kcontrol_t * kcontrol,
84 snd_ctl_elem_value_t * ucontrol)
85{
86 ca0106_t *emu = snd_kcontrol_chip(kcontrol);
87
88 ucontrol->value.enumerated.item[0] = emu->spdif_enable;
89 return 0;
90}
91
92static int snd_ca0106_shared_spdif_put(snd_kcontrol_t * kcontrol,
93 snd_ctl_elem_value_t * ucontrol)
94{
95 ca0106_t *emu = snd_kcontrol_chip(kcontrol);
96 unsigned int val;
97 int change = 0;
98 u32 mask;
99
100 val = ucontrol->value.enumerated.item[0] ;
101 change = (emu->spdif_enable != val);
102 if (change) {
103 emu->spdif_enable = val;
104 if (val == 1) {
105 /* Digital */
106 snd_ca0106_ptr_write(emu, SPDIF_SELECT1, 0, 0xf);
107 snd_ca0106_ptr_write(emu, SPDIF_SELECT2, 0, 0x0b000000);
108 snd_ca0106_ptr_write(emu, CAPTURE_CONTROL, 0,
109 snd_ca0106_ptr_read(emu, CAPTURE_CONTROL, 0) & ~0x1000);
110 mask = inl(emu->port + GPIO) & ~0x101;
111 outl(mask, emu->port + GPIO);
112
113 } else {
114 /* Analog */
115 snd_ca0106_ptr_write(emu, SPDIF_SELECT1, 0, 0xf);
116 snd_ca0106_ptr_write(emu, SPDIF_SELECT2, 0, 0x000b0000);
117 snd_ca0106_ptr_write(emu, CAPTURE_CONTROL, 0,
118 snd_ca0106_ptr_read(emu, CAPTURE_CONTROL, 0) | 0x1000);
119 mask = inl(emu->port + GPIO) | 0x101;
120 outl(mask, emu->port + GPIO);
121 }
122 }
123 return change;
124}
125
126static snd_kcontrol_new_t snd_ca0106_shared_spdif __devinitdata =
127{
128 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
129 .name = "SPDIF Out",
130 .info = snd_ca0106_shared_spdif_info,
131 .get = snd_ca0106_shared_spdif_get,
132 .put = snd_ca0106_shared_spdif_put
133};
134
135static int snd_ca0106_capture_source_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
136{
137 static char *texts[6] = { "SPDIF out", "i2s mixer out", "SPDIF in", "i2s in", "AC97 in", "SRC out" };
138
139 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
140 uinfo->count = 1;
141 uinfo->value.enumerated.items = 6;
142 if (uinfo->value.enumerated.item > 5)
143 uinfo->value.enumerated.item = 5;
144 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
145 return 0;
146}
147
148static int snd_ca0106_capture_source_get(snd_kcontrol_t * kcontrol,
149 snd_ctl_elem_value_t * ucontrol)
150{
151 ca0106_t *emu = snd_kcontrol_chip(kcontrol);
152
153 ucontrol->value.enumerated.item[0] = emu->capture_source;
154 return 0;
155}
156
157static int snd_ca0106_capture_source_put(snd_kcontrol_t * kcontrol,
158 snd_ctl_elem_value_t * ucontrol)
159{
160 ca0106_t *emu = snd_kcontrol_chip(kcontrol);
161 unsigned int val;
162 int change = 0;
163 u32 mask;
164 u32 source;
165
166 val = ucontrol->value.enumerated.item[0] ;
167 change = (emu->capture_source != val);
168 if (change) {
169 emu->capture_source = val;
170 source = (val << 28) | (val << 24) | (val << 20) | (val << 16);
171 mask = snd_ca0106_ptr_read(emu, CAPTURE_SOURCE, 0) & 0xffff;
172 snd_ca0106_ptr_write(emu, CAPTURE_SOURCE, 0, source | mask);
173 }
174 return change;
175}
176
177static snd_kcontrol_new_t snd_ca0106_capture_source __devinitdata =
178{
179 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
180 .name = "Capture Source",
181 .info = snd_ca0106_capture_source_info,
182 .get = snd_ca0106_capture_source_get,
183 .put = snd_ca0106_capture_source_put
184};
185
186static int snd_ca0106_spdif_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
187{
188 uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
189 uinfo->count = 1;
190 return 0;
191}
192
193static int snd_ca0106_spdif_get(snd_kcontrol_t * kcontrol,
194 snd_ctl_elem_value_t * ucontrol)
195{
196 ca0106_t *emu = snd_kcontrol_chip(kcontrol);
197 unsigned int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
198
199 ucontrol->value.iec958.status[0] = (emu->spdif_bits[idx] >> 0) & 0xff;
200 ucontrol->value.iec958.status[1] = (emu->spdif_bits[idx] >> 8) & 0xff;
201 ucontrol->value.iec958.status[2] = (emu->spdif_bits[idx] >> 16) & 0xff;
202 ucontrol->value.iec958.status[3] = (emu->spdif_bits[idx] >> 24) & 0xff;
203 return 0;
204}
205
206static int snd_ca0106_spdif_get_mask(snd_kcontrol_t * kcontrol,
207 snd_ctl_elem_value_t * ucontrol)
208{
209 ucontrol->value.iec958.status[0] = 0xff;
210 ucontrol->value.iec958.status[1] = 0xff;
211 ucontrol->value.iec958.status[2] = 0xff;
212 ucontrol->value.iec958.status[3] = 0xff;
213 return 0;
214}
215
216static int snd_ca0106_spdif_put(snd_kcontrol_t * kcontrol,
217 snd_ctl_elem_value_t * ucontrol)
218{
219 ca0106_t *emu = snd_kcontrol_chip(kcontrol);
220 unsigned int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
221 int change;
222 unsigned int val;
223
224 val = (ucontrol->value.iec958.status[0] << 0) |
225 (ucontrol->value.iec958.status[1] << 8) |
226 (ucontrol->value.iec958.status[2] << 16) |
227 (ucontrol->value.iec958.status[3] << 24);
228 change = val != emu->spdif_bits[idx];
229 if (change) {
230 snd_ca0106_ptr_write(emu, SPCS0 + idx, 0, val);
231 emu->spdif_bits[idx] = val;
232 }
233 return change;
234}
235
236static snd_kcontrol_new_t snd_ca0106_spdif_mask_control =
237{
238 .access = SNDRV_CTL_ELEM_ACCESS_READ,
239 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
240 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,MASK),
241 .count = 4,
242 .info = snd_ca0106_spdif_info,
243 .get = snd_ca0106_spdif_get_mask
244};
245
246static snd_kcontrol_new_t snd_ca0106_spdif_control =
247{
248 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
249 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT),
250 .count = 4,
251 .info = snd_ca0106_spdif_info,
252 .get = snd_ca0106_spdif_get,
253 .put = snd_ca0106_spdif_put
254};
255
256static int snd_ca0106_volume_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
257{
258 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
259 uinfo->count = 2;
260 uinfo->value.integer.min = 0;
261 uinfo->value.integer.max = 255;
262 return 0;
263}
264
265static int snd_ca0106_volume_get(snd_kcontrol_t * kcontrol,
266 snd_ctl_elem_value_t * ucontrol, int reg, int channel_id)
267{
268 ca0106_t *emu = snd_kcontrol_chip(kcontrol);
269 unsigned int value;
270
271 value = snd_ca0106_ptr_read(emu, reg, channel_id);
272 ucontrol->value.integer.value[0] = 0xff - ((value >> 24) & 0xff); /* Left */
273 ucontrol->value.integer.value[1] = 0xff - ((value >> 16) & 0xff); /* Right */
274 return 0;
275}
276
277static int snd_ca0106_volume_get_spdif_front(snd_kcontrol_t * kcontrol,
278 snd_ctl_elem_value_t * ucontrol)
279{
280 int channel_id = CONTROL_FRONT_CHANNEL;
281 int reg = PLAYBACK_VOLUME1;
282 return snd_ca0106_volume_get(kcontrol, ucontrol, reg, channel_id);
283}
284
285static int snd_ca0106_volume_get_spdif_center_lfe(snd_kcontrol_t * kcontrol,
286 snd_ctl_elem_value_t * ucontrol)
287{
288 int channel_id = CONTROL_CENTER_LFE_CHANNEL;
289 int reg = PLAYBACK_VOLUME1;
290 return snd_ca0106_volume_get(kcontrol, ucontrol, reg, channel_id);
291}
292static int snd_ca0106_volume_get_spdif_unknown(snd_kcontrol_t * kcontrol,
293 snd_ctl_elem_value_t * ucontrol)
294{
295 int channel_id = CONTROL_UNKNOWN_CHANNEL;
296 int reg = PLAYBACK_VOLUME1;
297 return snd_ca0106_volume_get(kcontrol, ucontrol, reg, channel_id);
298}
299static int snd_ca0106_volume_get_spdif_rear(snd_kcontrol_t * kcontrol,
300 snd_ctl_elem_value_t * ucontrol)
301{
302 int channel_id = CONTROL_REAR_CHANNEL;
303 int reg = PLAYBACK_VOLUME1;
304 return snd_ca0106_volume_get(kcontrol, ucontrol, reg, channel_id);
305}
306static int snd_ca0106_volume_get_analog_front(snd_kcontrol_t * kcontrol,
307 snd_ctl_elem_value_t * ucontrol)
308{
309 int channel_id = CONTROL_FRONT_CHANNEL;
310 int reg = PLAYBACK_VOLUME2;
311 return snd_ca0106_volume_get(kcontrol, ucontrol, reg, channel_id);
312}
313
314static int snd_ca0106_volume_get_analog_center_lfe(snd_kcontrol_t * kcontrol,
315 snd_ctl_elem_value_t * ucontrol)
316{
317 int channel_id = CONTROL_CENTER_LFE_CHANNEL;
318 int reg = PLAYBACK_VOLUME2;
319 return snd_ca0106_volume_get(kcontrol, ucontrol, reg, channel_id);
320}
321static int snd_ca0106_volume_get_analog_unknown(snd_kcontrol_t * kcontrol,
322 snd_ctl_elem_value_t * ucontrol)
323{
324 int channel_id = CONTROL_UNKNOWN_CHANNEL;
325 int reg = PLAYBACK_VOLUME2;
326 return snd_ca0106_volume_get(kcontrol, ucontrol, reg, channel_id);
327}
328static int snd_ca0106_volume_get_analog_rear(snd_kcontrol_t * kcontrol,
329 snd_ctl_elem_value_t * ucontrol)
330{
331 int channel_id = CONTROL_REAR_CHANNEL;
332 int reg = PLAYBACK_VOLUME2;
333 return snd_ca0106_volume_get(kcontrol, ucontrol, reg, channel_id);
334}
335
336static int snd_ca0106_volume_get_feedback(snd_kcontrol_t * kcontrol,
337 snd_ctl_elem_value_t * ucontrol)
338{
339 int channel_id = 1;
340 int reg = CAPTURE_CONTROL;
341 return snd_ca0106_volume_get(kcontrol, ucontrol, reg, channel_id);
342}
343
344static int snd_ca0106_volume_put(snd_kcontrol_t * kcontrol,
345 snd_ctl_elem_value_t * ucontrol, int reg, int channel_id)
346{
347 ca0106_t *emu = snd_kcontrol_chip(kcontrol);
348 unsigned int value;
349 //value = snd_ca0106_ptr_read(emu, reg, channel_id);
350 //value = value & 0xffff;
351 value = ((0xff - ucontrol->value.integer.value[0]) << 24) | ((0xff - ucontrol->value.integer.value[1]) << 16);
352 value = value | ((0xff - ucontrol->value.integer.value[0]) << 8) | ((0xff - ucontrol->value.integer.value[1]) );
353 snd_ca0106_ptr_write(emu, reg, channel_id, value);
354 return 1;
355}
356static int snd_ca0106_volume_put_spdif_front(snd_kcontrol_t * kcontrol,
357 snd_ctl_elem_value_t * ucontrol)
358{
359 int channel_id = CONTROL_FRONT_CHANNEL;
360 int reg = PLAYBACK_VOLUME1;
361 return snd_ca0106_volume_put(kcontrol, ucontrol, reg, channel_id);
362}
363static int snd_ca0106_volume_put_spdif_center_lfe(snd_kcontrol_t * kcontrol,
364 snd_ctl_elem_value_t * ucontrol)
365{
366 int channel_id = CONTROL_CENTER_LFE_CHANNEL;
367 int reg = PLAYBACK_VOLUME1;
368 return snd_ca0106_volume_put(kcontrol, ucontrol, reg, channel_id);
369}
370static int snd_ca0106_volume_put_spdif_unknown(snd_kcontrol_t * kcontrol,
371 snd_ctl_elem_value_t * ucontrol)
372{
373 int channel_id = CONTROL_UNKNOWN_CHANNEL;
374 int reg = PLAYBACK_VOLUME1;
375 return snd_ca0106_volume_put(kcontrol, ucontrol, reg, channel_id);
376}
377static int snd_ca0106_volume_put_spdif_rear(snd_kcontrol_t * kcontrol,
378 snd_ctl_elem_value_t * ucontrol)
379{
380 int channel_id = CONTROL_REAR_CHANNEL;
381 int reg = PLAYBACK_VOLUME1;
382 return snd_ca0106_volume_put(kcontrol, ucontrol, reg, channel_id);
383}
384static int snd_ca0106_volume_put_analog_front(snd_kcontrol_t * kcontrol,
385 snd_ctl_elem_value_t * ucontrol)
386{
387 int channel_id = CONTROL_FRONT_CHANNEL;
388 int reg = PLAYBACK_VOLUME2;
389 return snd_ca0106_volume_put(kcontrol, ucontrol, reg, channel_id);
390}
391static int snd_ca0106_volume_put_analog_center_lfe(snd_kcontrol_t * kcontrol,
392 snd_ctl_elem_value_t * ucontrol)
393{
394 int channel_id = CONTROL_CENTER_LFE_CHANNEL;
395 int reg = PLAYBACK_VOLUME2;
396 return snd_ca0106_volume_put(kcontrol, ucontrol, reg, channel_id);
397}
398static int snd_ca0106_volume_put_analog_unknown(snd_kcontrol_t * kcontrol,
399 snd_ctl_elem_value_t * ucontrol)
400{
401 int channel_id = CONTROL_UNKNOWN_CHANNEL;
402 int reg = PLAYBACK_VOLUME2;
403 return snd_ca0106_volume_put(kcontrol, ucontrol, reg, channel_id);
404}
405static int snd_ca0106_volume_put_analog_rear(snd_kcontrol_t * kcontrol,
406 snd_ctl_elem_value_t * ucontrol)
407{
408 int channel_id = CONTROL_REAR_CHANNEL;
409 int reg = PLAYBACK_VOLUME2;
410 return snd_ca0106_volume_put(kcontrol, ucontrol, reg, channel_id);
411}
412
413static int snd_ca0106_volume_put_feedback(snd_kcontrol_t * kcontrol,
414 snd_ctl_elem_value_t * ucontrol)
415{
416 int channel_id = 1;
417 int reg = CAPTURE_CONTROL;
418 return snd_ca0106_volume_put(kcontrol, ucontrol, reg, channel_id);
419}
420
421static snd_kcontrol_new_t snd_ca0106_volume_control_analog_front =
422{
423 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
424 .name = "Analog Front Volume",
425 .info = snd_ca0106_volume_info,
426 .get = snd_ca0106_volume_get_analog_front,
427 .put = snd_ca0106_volume_put_analog_front
428};
429static snd_kcontrol_new_t snd_ca0106_volume_control_analog_center_lfe =
430{
431 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
432 .name = "Analog Center/LFE Volume",
433 .info = snd_ca0106_volume_info,
434 .get = snd_ca0106_volume_get_analog_center_lfe,
435 .put = snd_ca0106_volume_put_analog_center_lfe
436};
437static snd_kcontrol_new_t snd_ca0106_volume_control_analog_unknown =
438{
439 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
440 .name = "Analog Unknown Volume",
441 .info = snd_ca0106_volume_info,
442 .get = snd_ca0106_volume_get_analog_unknown,
443 .put = snd_ca0106_volume_put_analog_unknown
444};
445static snd_kcontrol_new_t snd_ca0106_volume_control_analog_rear =
446{
447 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
448 .name = "Analog Rear Volume",
449 .info = snd_ca0106_volume_info,
450 .get = snd_ca0106_volume_get_analog_rear,
451 .put = snd_ca0106_volume_put_analog_rear
452};
453static snd_kcontrol_new_t snd_ca0106_volume_control_spdif_front =
454{
455 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
456 .name = "SPDIF Front Volume",
457 .info = snd_ca0106_volume_info,
458 .get = snd_ca0106_volume_get_spdif_front,
459 .put = snd_ca0106_volume_put_spdif_front
460};
461static snd_kcontrol_new_t snd_ca0106_volume_control_spdif_center_lfe =
462{
463 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
464 .name = "SPDIF Center/LFE Volume",
465 .info = snd_ca0106_volume_info,
466 .get = snd_ca0106_volume_get_spdif_center_lfe,
467 .put = snd_ca0106_volume_put_spdif_center_lfe
468};
469static snd_kcontrol_new_t snd_ca0106_volume_control_spdif_unknown =
470{
471 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
472 .name = "SPDIF Unknown Volume",
473 .info = snd_ca0106_volume_info,
474 .get = snd_ca0106_volume_get_spdif_unknown,
475 .put = snd_ca0106_volume_put_spdif_unknown
476};
477static snd_kcontrol_new_t snd_ca0106_volume_control_spdif_rear =
478{
479 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
480 .name = "SPDIF Rear Volume",
481 .info = snd_ca0106_volume_info,
482 .get = snd_ca0106_volume_get_spdif_rear,
483 .put = snd_ca0106_volume_put_spdif_rear
484};
485
486static snd_kcontrol_new_t snd_ca0106_volume_control_feedback =
487{
488 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
489 .name = "CAPTURE feedback into PLAYBACK",
490 .info = snd_ca0106_volume_info,
491 .get = snd_ca0106_volume_get_feedback,
492 .put = snd_ca0106_volume_put_feedback
493};
494
495
496static int remove_ctl(snd_card_t *card, const char *name)
497{
498 snd_ctl_elem_id_t id;
499 memset(&id, 0, sizeof(id));
500 strcpy(id.name, name);
501 id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
502 return snd_ctl_remove_id(card, &id);
503}
504
505static snd_kcontrol_t *ctl_find(snd_card_t *card, const char *name)
506{
507 snd_ctl_elem_id_t sid;
508 memset(&sid, 0, sizeof(sid));
509 /* FIXME: strcpy is bad. */
510 strcpy(sid.name, name);
511 sid.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
512 return snd_ctl_find_id(card, &sid);
513}
514
515static int rename_ctl(snd_card_t *card, const char *src, const char *dst)
516{
517 snd_kcontrol_t *kctl = ctl_find(card, src);
518 if (kctl) {
519 strcpy(kctl->id.name, dst);
520 return 0;
521 }
522 return -ENOENT;
523}
524
525int __devinit snd_ca0106_mixer(ca0106_t *emu)
526{
527 int err;
528 snd_kcontrol_t *kctl;
529 snd_card_t *card = emu->card;
530 char **c;
531 static char *ca0106_remove_ctls[] = {
532 "Master Mono Playback Switch",
533 "Master Mono Playback Volume",
534 "3D Control - Switch",
535 "3D Control Sigmatel - Depth",
536 "PCM Playback Switch",
537 "PCM Playback Volume",
538 "CD Playback Switch",
539 "CD Playback Volume",
540 "Phone Playback Switch",
541 "Phone Playback Volume",
542 "Video Playback Switch",
543 "Video Playback Volume",
544 "PC Speaker Playback Switch",
545 "PC Speaker Playback Volume",
546 "Mono Output Select",
547 "Capture Source",
548 "Capture Switch",
549 "Capture Volume",
550 "External Amplifier",
551 "Sigmatel 4-Speaker Stereo Playback Switch",
552 "Sigmatel Surround Phase Inversion Playback ",
553 NULL
554 };
555 static char *ca0106_rename_ctls[] = {
556 "Master Playback Switch", "Capture Switch",
557 "Master Playback Volume", "Capture Volume",
558 "Line Playback Switch", "AC97 Line Capture Switch",
559 "Line Playback Volume", "AC97 Line Capture Volume",
560 "Aux Playback Switch", "AC97 Aux Capture Switch",
561 "Aux Playback Volume", "AC97 Aux Capture Volume",
562 "Mic Playback Switch", "AC97 Mic Capture Switch",
563 "Mic Playback Volume", "AC97 Mic Capture Volume",
564 "Mic Select", "AC97 Mic Select",
565 "Mic Boost (+20dB)", "AC97 Mic Boost (+20dB)",
566 NULL
567 };
568#if 1
569 for (c=ca0106_remove_ctls; *c; c++)
570 remove_ctl(card, *c);
571 for (c=ca0106_rename_ctls; *c; c += 2)
572 rename_ctl(card, c[0], c[1]);
573#endif
574
575 if ((kctl = snd_ctl_new1(&snd_ca0106_volume_control_analog_front, emu)) == NULL)
576 return -ENOMEM;
577 if ((err = snd_ctl_add(card, kctl)))
578 return err;
579 if ((kctl = snd_ctl_new1(&snd_ca0106_volume_control_analog_rear, emu)) == NULL)
580 return -ENOMEM;
581 if ((err = snd_ctl_add(card, kctl)))
582 return err;
583 if ((kctl = snd_ctl_new1(&snd_ca0106_volume_control_analog_center_lfe, emu)) == NULL)
584 return -ENOMEM;
585 if ((err = snd_ctl_add(card, kctl)))
586 return err;
587 if ((kctl = snd_ctl_new1(&snd_ca0106_volume_control_analog_unknown, emu)) == NULL)
588 return -ENOMEM;
589 if ((err = snd_ctl_add(card, kctl)))
590 return err;
591 if ((kctl = snd_ctl_new1(&snd_ca0106_volume_control_spdif_front, emu)) == NULL)
592 return -ENOMEM;
593 if ((err = snd_ctl_add(card, kctl)))
594 return err;
595 if ((kctl = snd_ctl_new1(&snd_ca0106_volume_control_spdif_rear, emu)) == NULL)
596 return -ENOMEM;
597 if ((err = snd_ctl_add(card, kctl)))
598 return err;
599 if ((kctl = snd_ctl_new1(&snd_ca0106_volume_control_spdif_center_lfe, emu)) == NULL)
600 return -ENOMEM;
601 if ((err = snd_ctl_add(card, kctl)))
602 return err;
603 if ((kctl = snd_ctl_new1(&snd_ca0106_volume_control_spdif_unknown, emu)) == NULL)
604 return -ENOMEM;
605 if ((err = snd_ctl_add(card, kctl)))
606 return err;
607 if ((kctl = snd_ctl_new1(&snd_ca0106_volume_control_feedback, emu)) == NULL)
608 return -ENOMEM;
609 if ((err = snd_ctl_add(card, kctl)))
610 return err;
611 if ((kctl = snd_ctl_new1(&snd_ca0106_spdif_mask_control, emu)) == NULL)
612 return -ENOMEM;
613 if ((err = snd_ctl_add(card, kctl)))
614 return err;
615 if ((kctl = snd_ctl_new1(&snd_ca0106_shared_spdif, emu)) == NULL)
616 return -ENOMEM;
617 if ((err = snd_ctl_add(card, kctl)))
618 return err;
619 if ((kctl = snd_ctl_new1(&snd_ca0106_capture_source, emu)) == NULL)
620 return -ENOMEM;
621 if ((err = snd_ctl_add(card, kctl)))
622 return err;
623 if ((kctl = ctl_find(card, SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT))) != NULL) {
624 /* already defined by ac97, remove it */
625 /* FIXME: or do we need both controls? */
626 remove_ctl(card, SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT));
627 }
628 if ((kctl = snd_ctl_new1(&snd_ca0106_spdif_control, emu)) == NULL)
629 return -ENOMEM;
630 if ((err = snd_ctl_add(card, kctl)))
631 return err;
632 return 0;
633}
634
diff --git a/sound/pci/ca0106/ca0106_proc.c b/sound/pci/ca0106/ca0106_proc.c
new file mode 100644
index 000000000000..afb711421e47
--- /dev/null
+++ b/sound/pci/ca0106/ca0106_proc.c
@@ -0,0 +1,436 @@
1/*
2 * Copyright (c) 2004 James Courtier-Dutton <James@superbug.demon.co.uk>
3 * Driver CA0106 chips. e.g. Sound Blaster Audigy LS and Live 24bit
4 * Version: 0.0.17
5 *
6 * FEATURES currently supported:
7 * See ca0106_main.c for features.
8 *
9 * Changelog:
10 * Support interrupts per period.
11 * Removed noise from Center/LFE channel when in Analog mode.
12 * Rename and remove mixer controls.
13 * 0.0.6
14 * Use separate card based DMA buffer for periods table list.
15 * 0.0.7
16 * Change remove and rename ctrls into lists.
17 * 0.0.8
18 * Try to fix capture sources.
19 * 0.0.9
20 * Fix AC3 output.
21 * Enable S32_LE format support.
22 * 0.0.10
23 * Enable playback 48000 and 96000 rates. (Rates other that these do not work, even with "plug:front".)
24 * 0.0.11
25 * Add Model name recognition.
26 * 0.0.12
27 * Correct interrupt timing. interrupt at end of period, instead of in the middle of a playback period.
28 * Remove redundent "voice" handling.
29 * 0.0.13
30 * Single trigger call for multi channels.
31 * 0.0.14
32 * Set limits based on what the sound card hardware can do.
33 * playback periods_min=2, periods_max=8
34 * capture hw constraints require period_size = n * 64 bytes.
35 * playback hw constraints require period_size = n * 64 bytes.
36 * 0.0.15
37 * Separate ca0106.c into separate functional .c files.
38 * 0.0.16
39 * Modified Copyright message.
40 * 0.0.17
41 * Add iec958 file in proc file system to show status of SPDIF in.
42 *
43 * This code was initally based on code from ALSA's emu10k1x.c which is:
44 * Copyright (c) by Francisco Moraes <fmoraes@nc.rr.com>
45 *
46 * This program is free software; you can redistribute it and/or modify
47 * it under the terms of the GNU General Public License as published by
48 * the Free Software Foundation; either version 2 of the License, or
49 * (at your option) any later version.
50 *
51 * This program is distributed in the hope that it will be useful,
52 * but WITHOUT ANY WARRANTY; without even the implied warranty of
53 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
54 * GNU General Public License for more details.
55 *
56 * You should have received a copy of the GNU General Public License
57 * along with this program; if not, write to the Free Software
58 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
59 *
60 */
61#include <sound/driver.h>
62#include <linux/delay.h>
63#include <linux/init.h>
64#include <linux/interrupt.h>
65#include <linux/pci.h>
66#include <linux/slab.h>
67#include <linux/moduleparam.h>
68#include <sound/core.h>
69#include <sound/initval.h>
70#include <sound/pcm.h>
71#include <sound/ac97_codec.h>
72#include <sound/info.h>
73#include <sound/asoundef.h>
74
75#include "ca0106.h"
76
77
78struct snd_ca0106_category_str {
79 int val;
80 const char *name;
81};
82
83static struct snd_ca0106_category_str snd_ca0106_con_category[] = {
84 { IEC958_AES1_CON_DAT, "DAT" },
85 { IEC958_AES1_CON_VCR, "VCR" },
86 { IEC958_AES1_CON_MICROPHONE, "microphone" },
87 { IEC958_AES1_CON_SYNTHESIZER, "synthesizer" },
88 { IEC958_AES1_CON_RATE_CONVERTER, "rate converter" },
89 { IEC958_AES1_CON_MIXER, "mixer" },
90 { IEC958_AES1_CON_SAMPLER, "sampler" },
91 { IEC958_AES1_CON_PCM_CODER, "PCM coder" },
92 { IEC958_AES1_CON_IEC908_CD, "CD" },
93 { IEC958_AES1_CON_NON_IEC908_CD, "non-IEC908 CD" },
94 { IEC958_AES1_CON_GENERAL, "general" },
95};
96
97
98void snd_ca0106_proc_dump_iec958( snd_info_buffer_t *buffer, u32 value)
99{
100 int i;
101 u32 status[4];
102 status[0] = value & 0xff;
103 status[1] = (value >> 8) & 0xff;
104 status[2] = (value >> 16) & 0xff;
105 status[3] = (value >> 24) & 0xff;
106
107 if (! (status[0] & IEC958_AES0_PROFESSIONAL)) {
108 /* consumer */
109 snd_iprintf(buffer, "Mode: consumer\n");
110 snd_iprintf(buffer, "Data: ");
111 if (!(status[0] & IEC958_AES0_NONAUDIO)) {
112 snd_iprintf(buffer, "audio\n");
113 } else {
114 snd_iprintf(buffer, "non-audio\n");
115 }
116 snd_iprintf(buffer, "Rate: ");
117 switch (status[3] & IEC958_AES3_CON_FS) {
118 case IEC958_AES3_CON_FS_44100:
119 snd_iprintf(buffer, "44100 Hz\n");
120 break;
121 case IEC958_AES3_CON_FS_48000:
122 snd_iprintf(buffer, "48000 Hz\n");
123 break;
124 case IEC958_AES3_CON_FS_32000:
125 snd_iprintf(buffer, "32000 Hz\n");
126 break;
127 default:
128 snd_iprintf(buffer, "unknown\n");
129 break;
130 }
131 snd_iprintf(buffer, "Copyright: ");
132 if (status[0] & IEC958_AES0_CON_NOT_COPYRIGHT) {
133 snd_iprintf(buffer, "permitted\n");
134 } else {
135 snd_iprintf(buffer, "protected\n");
136 }
137 snd_iprintf(buffer, "Emphasis: ");
138 if ((status[0] & IEC958_AES0_CON_EMPHASIS) != IEC958_AES0_CON_EMPHASIS_5015) {
139 snd_iprintf(buffer, "none\n");
140 } else {
141 snd_iprintf(buffer, "50/15us\n");
142 }
143 snd_iprintf(buffer, "Category: ");
144 for (i = 0; i < ARRAY_SIZE(snd_ca0106_con_category); i++) {
145 if ((status[1] & IEC958_AES1_CON_CATEGORY) == snd_ca0106_con_category[i].val) {
146 snd_iprintf(buffer, "%s\n", snd_ca0106_con_category[i].name);
147 break;
148 }
149 }
150 if (i >= ARRAY_SIZE(snd_ca0106_con_category)) {
151 snd_iprintf(buffer, "unknown 0x%x\n", status[1] & IEC958_AES1_CON_CATEGORY);
152 }
153 snd_iprintf(buffer, "Original: ");
154 if (status[1] & IEC958_AES1_CON_ORIGINAL) {
155 snd_iprintf(buffer, "original\n");
156 } else {
157 snd_iprintf(buffer, "1st generation\n");
158 }
159 snd_iprintf(buffer, "Clock: ");
160 switch (status[3] & IEC958_AES3_CON_CLOCK) {
161 case IEC958_AES3_CON_CLOCK_1000PPM:
162 snd_iprintf(buffer, "1000 ppm\n");
163 break;
164 case IEC958_AES3_CON_CLOCK_50PPM:
165 snd_iprintf(buffer, "50 ppm\n");
166 break;
167 case IEC958_AES3_CON_CLOCK_VARIABLE:
168 snd_iprintf(buffer, "variable pitch\n");
169 break;
170 default:
171 snd_iprintf(buffer, "unknown\n");
172 break;
173 }
174 } else {
175 snd_iprintf(buffer, "Mode: professional\n");
176 snd_iprintf(buffer, "Data: ");
177 if (!(status[0] & IEC958_AES0_NONAUDIO)) {
178 snd_iprintf(buffer, "audio\n");
179 } else {
180 snd_iprintf(buffer, "non-audio\n");
181 }
182 snd_iprintf(buffer, "Rate: ");
183 switch (status[0] & IEC958_AES0_PRO_FS) {
184 case IEC958_AES0_PRO_FS_44100:
185 snd_iprintf(buffer, "44100 Hz\n");
186 break;
187 case IEC958_AES0_PRO_FS_48000:
188 snd_iprintf(buffer, "48000 Hz\n");
189 break;
190 case IEC958_AES0_PRO_FS_32000:
191 snd_iprintf(buffer, "32000 Hz\n");
192 break;
193 default:
194 snd_iprintf(buffer, "unknown\n");
195 break;
196 }
197 snd_iprintf(buffer, "Rate Locked: ");
198 if (status[0] & IEC958_AES0_PRO_FREQ_UNLOCKED)
199 snd_iprintf(buffer, "no\n");
200 else
201 snd_iprintf(buffer, "yes\n");
202 snd_iprintf(buffer, "Emphasis: ");
203 switch (status[0] & IEC958_AES0_PRO_EMPHASIS) {
204 case IEC958_AES0_PRO_EMPHASIS_CCITT:
205 snd_iprintf(buffer, "CCITT J.17\n");
206 break;
207 case IEC958_AES0_PRO_EMPHASIS_NONE:
208 snd_iprintf(buffer, "none\n");
209 break;
210 case IEC958_AES0_PRO_EMPHASIS_5015:
211 snd_iprintf(buffer, "50/15us\n");
212 break;
213 case IEC958_AES0_PRO_EMPHASIS_NOTID:
214 default:
215 snd_iprintf(buffer, "unknown\n");
216 break;
217 }
218 snd_iprintf(buffer, "Stereophonic: ");
219 if ((status[1] & IEC958_AES1_PRO_MODE) == IEC958_AES1_PRO_MODE_STEREOPHONIC) {
220 snd_iprintf(buffer, "stereo\n");
221 } else {
222 snd_iprintf(buffer, "not indicated\n");
223 }
224 snd_iprintf(buffer, "Userbits: ");
225 switch (status[1] & IEC958_AES1_PRO_USERBITS) {
226 case IEC958_AES1_PRO_USERBITS_192:
227 snd_iprintf(buffer, "192bit\n");
228 break;
229 case IEC958_AES1_PRO_USERBITS_UDEF:
230 snd_iprintf(buffer, "user-defined\n");
231 break;
232 default:
233 snd_iprintf(buffer, "unkown\n");
234 break;
235 }
236 snd_iprintf(buffer, "Sample Bits: ");
237 switch (status[2] & IEC958_AES2_PRO_SBITS) {
238 case IEC958_AES2_PRO_SBITS_20:
239 snd_iprintf(buffer, "20 bit\n");
240 break;
241 case IEC958_AES2_PRO_SBITS_24:
242 snd_iprintf(buffer, "24 bit\n");
243 break;
244 case IEC958_AES2_PRO_SBITS_UDEF:
245 snd_iprintf(buffer, "user defined\n");
246 break;
247 default:
248 snd_iprintf(buffer, "unknown\n");
249 break;
250 }
251 snd_iprintf(buffer, "Word Length: ");
252 switch (status[2] & IEC958_AES2_PRO_WORDLEN) {
253 case IEC958_AES2_PRO_WORDLEN_22_18:
254 snd_iprintf(buffer, "22 bit or 18 bit\n");
255 break;
256 case IEC958_AES2_PRO_WORDLEN_23_19:
257 snd_iprintf(buffer, "23 bit or 19 bit\n");
258 break;
259 case IEC958_AES2_PRO_WORDLEN_24_20:
260 snd_iprintf(buffer, "24 bit or 20 bit\n");
261 break;
262 case IEC958_AES2_PRO_WORDLEN_20_16:
263 snd_iprintf(buffer, "20 bit or 16 bit\n");
264 break;
265 default:
266 snd_iprintf(buffer, "unknown\n");
267 break;
268 }
269 }
270}
271
272static void snd_ca0106_proc_iec958(snd_info_entry_t *entry,
273 snd_info_buffer_t * buffer)
274{
275 ca0106_t *emu = entry->private_data;
276 u32 value;
277
278 value = snd_ca0106_ptr_read(emu, SAMPLE_RATE_TRACKER_STATUS, 0);
279 snd_iprintf(buffer, "Status: %s, %s, %s\n",
280 (value & 0x100000) ? "Rate Locked" : "Not Rate Locked",
281 (value & 0x200000) ? "SPDIF Locked" : "No SPDIF Lock",
282 (value & 0x400000) ? "Audio Valid" : "No valid audio" );
283 snd_iprintf(buffer, "Estimated sample rate: %u\n",
284 ((value & 0xfffff) * 48000) / 0x8000 );
285 if (value & 0x200000) {
286 snd_iprintf(buffer, "IEC958/SPDIF input status:\n");
287 value = snd_ca0106_ptr_read(emu, SPDIF_INPUT_STATUS, 0);
288 snd_ca0106_proc_dump_iec958(buffer, value);
289 }
290
291 snd_iprintf(buffer, "\n");
292}
293
294static void snd_ca0106_proc_reg_write32(snd_info_entry_t *entry,
295 snd_info_buffer_t * buffer)
296{
297 ca0106_t *emu = entry->private_data;
298 unsigned long flags;
299 char line[64];
300 u32 reg, val;
301 while (!snd_info_get_line(buffer, line, sizeof(line))) {
302 if (sscanf(line, "%x %x", &reg, &val) != 2)
303 continue;
304 if ((reg < 0x40) && (reg >=0) && (val <= 0xffffffff) ) {
305 spin_lock_irqsave(&emu->emu_lock, flags);
306 outl(val, emu->port + (reg & 0xfffffffc));
307 spin_unlock_irqrestore(&emu->emu_lock, flags);
308 }
309 }
310}
311
312static void snd_ca0106_proc_reg_read32(snd_info_entry_t *entry,
313 snd_info_buffer_t * buffer)
314{
315 ca0106_t *emu = entry->private_data;
316 unsigned long value;
317 unsigned long flags;
318 int i;
319 snd_iprintf(buffer, "Registers:\n\n");
320 for(i = 0; i < 0x20; i+=4) {
321 spin_lock_irqsave(&emu->emu_lock, flags);
322 value = inl(emu->port + i);
323 spin_unlock_irqrestore(&emu->emu_lock, flags);
324 snd_iprintf(buffer, "Register %02X: %08lX\n", i, value);
325 }
326}
327
328static void snd_ca0106_proc_reg_read16(snd_info_entry_t *entry,
329 snd_info_buffer_t * buffer)
330{
331 ca0106_t *emu = entry->private_data;
332 unsigned int value;
333 unsigned long flags;
334 int i;
335 snd_iprintf(buffer, "Registers:\n\n");
336 for(i = 0; i < 0x20; i+=2) {
337 spin_lock_irqsave(&emu->emu_lock, flags);
338 value = inw(emu->port + i);
339 spin_unlock_irqrestore(&emu->emu_lock, flags);
340 snd_iprintf(buffer, "Register %02X: %04X\n", i, value);
341 }
342}
343
344static void snd_ca0106_proc_reg_read8(snd_info_entry_t *entry,
345 snd_info_buffer_t * buffer)
346{
347 ca0106_t *emu = entry->private_data;
348 unsigned int value;
349 unsigned long flags;
350 int i;
351 snd_iprintf(buffer, "Registers:\n\n");
352 for(i = 0; i < 0x20; i+=1) {
353 spin_lock_irqsave(&emu->emu_lock, flags);
354 value = inb(emu->port + i);
355 spin_unlock_irqrestore(&emu->emu_lock, flags);
356 snd_iprintf(buffer, "Register %02X: %02X\n", i, value);
357 }
358}
359
360static void snd_ca0106_proc_reg_read1(snd_info_entry_t *entry,
361 snd_info_buffer_t * buffer)
362{
363 ca0106_t *emu = entry->private_data;
364 unsigned long value;
365 int i,j;
366
367 snd_iprintf(buffer, "Registers\n");
368 for(i = 0; i < 0x40; i++) {
369 snd_iprintf(buffer, "%02X: ",i);
370 for (j = 0; j < 4; j++) {
371 value = snd_ca0106_ptr_read(emu, i, j);
372 snd_iprintf(buffer, "%08lX ", value);
373 }
374 snd_iprintf(buffer, "\n");
375 }
376}
377
378static void snd_ca0106_proc_reg_read2(snd_info_entry_t *entry,
379 snd_info_buffer_t * buffer)
380{
381 ca0106_t *emu = entry->private_data;
382 unsigned long value;
383 int i,j;
384
385 snd_iprintf(buffer, "Registers\n");
386 for(i = 0x40; i < 0x80; i++) {
387 snd_iprintf(buffer, "%02X: ",i);
388 for (j = 0; j < 4; j++) {
389 value = snd_ca0106_ptr_read(emu, i, j);
390 snd_iprintf(buffer, "%08lX ", value);
391 }
392 snd_iprintf(buffer, "\n");
393 }
394}
395
396static void snd_ca0106_proc_reg_write(snd_info_entry_t *entry,
397 snd_info_buffer_t * buffer)
398{
399 ca0106_t *emu = entry->private_data;
400 char line[64];
401 unsigned int reg, channel_id , val;
402 while (!snd_info_get_line(buffer, line, sizeof(line))) {
403 if (sscanf(line, "%x %x %x", &reg, &channel_id, &val) != 3)
404 continue;
405 if ((reg < 0x80) && (reg >=0) && (val <= 0xffffffff) && (channel_id >=0) && (channel_id <= 3) )
406 snd_ca0106_ptr_write(emu, reg, channel_id, val);
407 }
408}
409
410
411int __devinit snd_ca0106_proc_init(ca0106_t * emu)
412{
413 snd_info_entry_t *entry;
414
415 if(! snd_card_proc_new(emu->card, "iec958", &entry))
416 snd_info_set_text_ops(entry, emu, 1024, snd_ca0106_proc_iec958);
417 if(! snd_card_proc_new(emu->card, "ca0106_reg32", &entry)) {
418 snd_info_set_text_ops(entry, emu, 1024, snd_ca0106_proc_reg_read32);
419 entry->c.text.write_size = 64;
420 entry->c.text.write = snd_ca0106_proc_reg_write32;
421 }
422 if(! snd_card_proc_new(emu->card, "ca0106_reg16", &entry))
423 snd_info_set_text_ops(entry, emu, 1024, snd_ca0106_proc_reg_read16);
424 if(! snd_card_proc_new(emu->card, "ca0106_reg8", &entry))
425 snd_info_set_text_ops(entry, emu, 1024, snd_ca0106_proc_reg_read8);
426 if(! snd_card_proc_new(emu->card, "ca0106_regs1", &entry)) {
427 snd_info_set_text_ops(entry, emu, 1024, snd_ca0106_proc_reg_read1);
428 entry->c.text.write_size = 64;
429 entry->c.text.write = snd_ca0106_proc_reg_write;
430// entry->private_data = emu;
431 }
432 if(! snd_card_proc_new(emu->card, "ca0106_regs2", &entry))
433 snd_info_set_text_ops(entry, emu, 1024, snd_ca0106_proc_reg_read2);
434 return 0;
435}
436